summaryrefslogtreecommitdiffstats
path: root/include/asm-sparc64/ide.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
commit545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch)
treee9ce4bc598d06374bda906f18365984bf22a526a /include/asm-sparc64/ide.h
parent4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (diff)
Merge with Linux 2.1.55. More bugfixes and goodies from my private
CVS archive.
Diffstat (limited to 'include/asm-sparc64/ide.h')
-rw-r--r--include/asm-sparc64/ide.h263
1 files changed, 263 insertions, 0 deletions
diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
new file mode 100644
index 000000000..e305ccf91
--- /dev/null
+++ b/include/asm-sparc64/ide.h
@@ -0,0 +1,263 @@
+/* $Id: ide.h,v 1.4 1997/08/30 16:29:29 davem Exp $
+ * ide.h: Ultra/PCI specific IDE glue.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_IDE_H
+#define _SPARC64_IDE_H
+
+#ifdef __KERNEL__
+
+typedef unsigned long ide_ioreg_t;
+
+#undef MAX_HWIFS
+#define MAX_HWIFS 2
+
+extern int sparc64_ide_ports_known;
+extern ide_ioreg_t sparc64_ide_regbase[MAX_HWIFS];
+extern ide_ioreg_t sparc64_idedma_regbase; /* one for both channels */
+extern unsigned int sparc64_ide_irq;
+
+extern void sparc64_ide_probe(void);
+
+#define ide_sti() sti()
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+ if(sparc64_ide_ports_known == 0)
+ sparc64_ide_probe();
+ return sparc64_ide_irq;
+}
+
+static __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+ if(sparc64_ide_ports_known == 0)
+ sparc64_ide_probe();
+ return sparc64_ide_regbase[index];
+}
+
+static __inline__ void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+{
+ ide_ioreg_t port = base;
+ int i = 9;
+
+ while(i--)
+ *p++ = port++;
+ if(base == sparc64_ide_regbase[0])
+ *p = sparc64_idedma_regbase + 0x2;
+ else
+ *p = sparc64_idedma_regbase + 0xa;
+ if(irq != NULL)
+ *irq = sparc64_ide_irq;
+}
+
+typedef union {
+ unsigned int all : 8; /* all of the bits together */
+ struct {
+ unsigned int bit7 : 1;
+ unsigned int lba : 1;
+ unsigned int bit5 : 1;
+ unsigned int unit : 1;
+ unsigned int head : 4;
+ } b;
+} select_t;
+
+static __inline__ int ide_request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *name, void *devid)
+{
+ return request_irq(irq, handler, SA_SHIRQ, name, devid);
+}
+
+static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
+{
+ free_irq(irq, dev_id);
+}
+
+static __inline__ int ide_check_region(ide_ioreg_t base, unsigned int size)
+{
+ return check_region(base, size);
+}
+
+static __inline__ void ide_request_region(ide_ioreg_t base, unsigned int size,
+ const char *name)
+{
+ request_region(base, size, name);
+}
+
+static __inline__ void ide_release_region(ide_ioreg_t base, unsigned int size)
+{
+ release_region(base, size);
+}
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#undef HD_DATA
+#define HD_DATA ((ide_ioreg_t)0)
+
+static __inline__ int ide_ack_intr(ide_ioreg_t status_port, ide_ioreg_t irq_port)
+{
+ unsigned char stat = inb(irq_port);
+
+ if(stat & 0x4) {
+ outb((inb(irq_port) & 0x60) | 4, irq_port);
+ return 1;
+ }
+ return 0;
+}
+
+/* From m68k code... */
+
+#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
+#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
+
+#define insw(port, buf, nr) ide_insw((port), (buf), (nr))
+#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr))
+
+static __inline__ void ide_insw(unsigned long port,
+ void *dst,
+ unsigned long count)
+{
+ volatile unsigned short *data_port;
+ u16 *ps = dst;
+ u32 *pi;
+
+ data_port = (volatile unsigned short *)port;
+
+ if(((u64)ps) & 0x2) {
+ *ps++ = *data_port;
+ count--;
+ }
+ pi = (u32 *)ps;
+ while(count >= 2) {
+ u32 w;
+
+ w = (*data_port) << 16;
+ w |= (*data_port);
+ *pi++ = w;
+ count -= 2;
+ }
+ ps = (u16 *)pi;
+ if(count)
+ *ps = *data_port;
+}
+
+static __inline__ void ide_outsw(unsigned long port,
+ const void *src,
+ unsigned long count)
+{
+ volatile unsigned short *data_port;
+ const u16 *ps = src;
+ const u32 *pi;
+
+ data_port = (volatile unsigned short *)port;
+
+ if(((u64)src) & 0x2) {
+ *data_port = *ps++;
+ count--;
+ }
+ pi = (const u32 *)ps;
+ while(count >= 2) {
+ u32 w;
+
+ w = *pi++;
+ *data_port = (w >> 16);
+ *data_port = w;
+ count -= 2;
+ }
+ ps = (const u16 *)pi;
+ if(count)
+ *data_port = *ps;
+}
+
+#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;
+ };
+ }
+}
+
+static __inline__ void ide_release_lock (int *ide_lock)
+{
+}
+
+static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
+{
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _SPARC64_IDE_H */