patch-2.4.20 linux-2.4.20/include/asm-mips64/ide.h

Next file: linux-2.4.20/include/asm-mips64/io.h
Previous file: linux-2.4.20/include/asm-mips64/gt64120.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/include/asm-mips64/ide.h linux-2.4.20/include/asm-mips64/ide.h
@@ -18,6 +18,7 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <asm/io.h>
 
 #ifndef MAX_HWIFS
 # ifdef CONFIG_BLK_DEV_IDEPCI
@@ -79,11 +80,19 @@
 typedef union {
 	unsigned all			: 8;	/* all of the bits together */
 	struct {
+#ifdef __MIPSEB__
+		unsigned bit7           : 1;    /* always 1 */
+		unsigned lba            : 1;    /* using LBA instead of CHS */
+		unsigned bit5           : 1;    /* always 1 */
+		unsigned unit           : 1;    /* drive select number, 0 or 1 */
+		unsigned head           : 4;    /* always zeros here */
+#else
 		unsigned head		: 4;	/* always zeros here */
 		unsigned unit		: 1;	/* drive select number, 0 or 1 */
 		unsigned bit5		: 1;	/* always 1 */
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
+#endif
 	} b;
 } select_t;
 
@@ -139,54 +148,142 @@
 
 #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
 
-#ifdef insl
-#undef insl
-#endif
-#ifdef outsl
-#undef outsl
-#endif
+/* get rid of defs from io.h - ide has its private and conflicting versions */
 #ifdef insw
 #undef insw
 #endif
 #ifdef outsw
 #undef outsw
 #endif
+#ifdef insl
+#undef insl
+#endif
+#ifdef outsl
+#undef outsl
+#endif
 
-#define insw(p,a,c)							\
-do {									\
-	unsigned short *ptr = (unsigned short *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		*ptr++ = inw(p);					\
-} while (0)
-#define insl(p,a,c)							\
-do {									\
-	unsigned long *ptr = (unsigned long *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		*ptr++ = inl(p);					\
-} while (0)
-#define outsw(p,a,c)							\
-do {									\
-	unsigned short *ptr = (unsigned short *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		outw(*ptr++, (p));					\
-} while (0)
-#define outsl(p,a,c) {							\
-	unsigned long *ptr = (unsigned long *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		outl(*ptr++, (p));					\
-} while (0)
+#define insw(port, addr, count) ide_insw(port, addr, count)
+#define insl(port, addr, count) ide_insl(port, addr, count)
+#define outsw(port, addr, count) ide_outsw(port, addr, count)
+#define outsl(port, addr, count) ide_outsl(port, addr, count)
 
-#endif /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
+static inline void ide_insw(unsigned long port, void *addr, unsigned int count)
+{
+       while (count--) {
+               *(u16 *)addr = *(volatile u16 *)(mips_io_port_base + port);
+               addr += 2;
+       }
+}
+
+static inline void ide_outsw(unsigned long port, void *addr, unsigned int count)
+{
+       while (count--) {
+               *(volatile u16 *)(mips_io_port_base + (port)) = *(u16 *)addr;
+               addr += 2;
+       }
+}
+
+static inline void ide_insl(unsigned long port, void *addr, unsigned int count)
+{
+       while (count--) {
+               *(u32 *)addr = *(volatile u32 *)(mips_io_port_base + port);
+               addr += 4;
+       }
+}
+
+static inline void ide_outsl(unsigned long port, void *addr, unsigned int count)
+{
+       while (count--) {
+               *(volatile u32 *)(mips_io_port_base + (port)) = *(u32 *)addr;
+               addr += 4;
+       }
+}
+
+#define T_CHAR          (0x0000)        /* char:  don't touch  */
+#define T_SHORT         (0x4000)        /* short: 12 -> 21     */
+#define T_INT           (0x8000)        /* int:   1234 -> 4321 */
+#define T_TEXT          (0xc000)        /* text:  12 -> 21     */
+
+#define T_MASK_TYPE     (0xc000)
+#define T_MASK_COUNT    (0x3fff)
+
+#define D_CHAR(cnt)     (T_CHAR  | (cnt))
+#define D_SHORT(cnt)    (T_SHORT | (cnt))
+#define D_INT(cnt)      (T_INT   | (cnt))
+#define D_TEXT(cnt)     (T_TEXT  | (cnt))
+
+static u_short driveid_types[] = {
+	D_SHORT(10),	/* config - vendor2 */
+	D_TEXT(20),	/* serial_no */
+	D_SHORT(3),	/* buf_type - ecc_bytes */
+	D_TEXT(48),	/* fw_rev - model */
+	D_CHAR(2),	/* max_multsect - vendor3 */
+	D_SHORT(1),	/* dword_io */
+	D_CHAR(2),	/* vendor4 - capability */
+	D_SHORT(1),	/* reserved50 */
+	D_CHAR(4),	/* vendor5 - tDMA */
+	D_SHORT(4),	/* field_valid - cur_sectors */
+	D_INT(1),	/* cur_capacity */
+	D_CHAR(2),	/* multsect - multsect_valid */
+	D_INT(1),	/* lba_capacity */
+	D_SHORT(194)	/* dma_1word - reservedyy */
+};
+
+#define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
+
+static __inline__ void ide_fix_driveid(struct hd_driveid *id)
+{
+	u_char *p = (u_char *)id;
+	int i, j, cnt;
+	u_char t;
+
+	for (i = 0; i < num_driveid_types; i++) {
+		cnt = driveid_types[i] & T_MASK_COUNT;
+		switch (driveid_types[i] & T_MASK_TYPE) {
+		case T_CHAR:
+			p += cnt;
+			break;
+		case T_SHORT:
+			for (j = 0; j < cnt; j++) {
+				t = p[0];
+				p[0] = p[1];
+				p[1] = t;
+				p += 2;
+			}
+			break;
+		case T_INT:
+			for (j = 0; j < cnt; j++) {
+				t = p[0];
+				p[0] = p[3];
+				p[3] = t;
+				t = p[1];
+				p[1] = p[2];
+				p[2] = t;
+				p += 4;
+			}
+			break;
+		case T_TEXT:
+			for (j = 0; j < cnt; j += 2) {
+				t = p[0];
+				p[0] = p[1];
+				p[1] = t;
+				p += 2;
+			}
+			break;
+		};
+	}
+}
+
+#else /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
+
+#define ide_fix_driveid(id)		do {} while (0)
+
+#endif
 
 /*
  * The following are not needed for the non-m68k ports
  */
 #define ide_ack_intr(hwif)		(1)
-#define ide_fix_driveid(id)		do {} while (0)
 #define ide_release_lock(lock)		do {} while (0)
 #define ide_get_lock(lock, hdlr, data)	do {} while (0)
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)