outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
}
-static void
-insw(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u16 d = inw(port);
- SET_FARVAR(segment, *(u16*)(offset + 2*i), d);
- }
-}
-
-static void
-insl(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u32 d = inl(port);
- SET_FARVAR(segment, *(u32*)(offset + 4*i), d);
- }
-}
-
-static void
-outsw(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u16 d = GET_FARVAR(segment, *(u16*)(offset + 2*i));
- outw(d, port);
- }
-}
-
-static void
-outsl(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u32 d = GET_FARVAR(segment, *(u32*)(offset + 4*i));
- outl(d, port);
- }
-}
-
// ---------------------------------------------------------------------------
// ATA/ATAPI driver : execute a data-in command
}
if (mode == ATA_MODE_PIO32)
- insl(iobase1, segment, offset, 512 / 4);
+ insl_seg(iobase1, segment, offset, 512 / 4);
else
- insw(iobase1, segment, offset, 512 / 2);
+ insw_seg(iobase1, segment, offset, 512 / 2);
offset += 512;
current++;
}
if (mode == ATA_MODE_PIO32)
- outsl(iobase1, segment, offset, 512 / 4);
+ outsl_seg(iobase1, segment, offset, 512 / 4);
else
- outsw(iobase1, segment, offset, 512 / 2);
+ outsw_seg(iobase1, segment, offset, 512 / 2);
offset += 512;
current++;
// Send command to device
irq_enable();
- outsw(iobase1, GET_SEG(SS), (u32)cmdbuf, cmdlen);
+ outsw_seg(iobase1, GET_SEG(SS), (u32)cmdbuf, cmdlen);
if (inout == ATA_DATA_NO) {
await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
inw(iobase1);
if (lmode == ATA_MODE_PIO32)
- insl(iobase1, bufseg, bufoff, lcount);
+ insl_seg(iobase1, bufseg, bufoff, lcount);
else
- insw(iobase1, bufseg, bufoff, lcount);
+ insw_seg(iobase1, bufseg, bufoff, lcount);
for (i=0; i<lafter; i++)
if (lmode == ATA_MODE_PIO32)
#ifndef __FARPTR_H
#define __FARPTR_H
+#include "ioport.h" // insb
+
#define READ8_SEG(SEG, var) ({ \
u8 __value; \
__asm__ __volatile__("movb %%" #SEG ":%1, %b0" \
#define SET_FARPTR(ptr, val) do { (var) = (val); } while (0)
#endif
+static inline void insb_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ insb(port, (u8*)(offset+0), count);
+}
+static inline void insw_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ insw(port, (u16*)(offset+0), count);
+}
+static inline void insl_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ insl(port, (u32*)(offset+0), count);
+}
+static inline void outsb_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ outsb(port, (u8*)(offset+0), count);
+}
+static inline void outsw_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ outsw(port, (u16*)(offset+0), count);
+}
+static inline void outsl_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ outsl(port, (u32*)(offset+0), count);
+}
+
#endif // farptr.h
return value;
}
+static inline void insb(u16 port, u8 *data, u32 count) {
+ asm volatile("rep insb (%%dx), %%es:(%%di)"
+ : "+c"(count), "+D"(data) : "d"(port) : "memory");
+}
+static inline void insw(u16 port, u16 *data, u32 count) {
+ asm volatile("rep insw (%%dx), %%es:(%%di)"
+ : "+c"(count), "+D"(data) : "d"(port) : "memory");
+}
+static inline void insl(u16 port, u32 *data, u32 count) {
+ asm volatile("rep insl (%%dx), %%es:(%%di)"
+ : "+c"(count), "+D"(data) : "d"(port) : "memory");
+}
+// XXX - outs not limited to es segment
+static inline void outsb(u16 port, u8 *data, u32 count) {
+ asm volatile("rep outsb %%es:(%%si), (%%dx)"
+ : "+c"(count), "+S"(data) : "d"(port) : "memory");
+}
+static inline void outsw(u16 port, u16 *data, u32 count) {
+ asm volatile("rep outsw %%es:(%%si), (%%dx)"
+ : "+c"(count), "+S"(data) : "d"(port) : "memory");
+}
+static inline void outsl(u16 port, u32 *data, u32 count) {
+ asm volatile("rep outsl %%es:(%%si), (%%dx)"
+ : "+c"(count), "+S"(data) : "d"(port) : "memory");
+}
+
#endif // ioport.h