1/*
2 *  linux/include/asm-parisc/ide.h
3 *
4 *  Copyright (C) 1994-1996  Linus Torvalds & authors
5 */
6
7/*
8 *  This file contains the PARISC architecture specific IDE code.
9 */
10
11#ifndef __ASM_PARISC_IDE_H
12#define __ASM_PARISC_IDE_H
13
14#ifdef __KERNEL__
15
16#include <linux/config.h>
17#include <asm/superio.h>
18
19#ifndef MAX_HWIFS
20#define MAX_HWIFS	2
21#endif
22
23static __inline__ int ide_default_irq(ide_ioreg_t base)
24{
25	switch (base) {
26#ifdef CONFIG_SUPERIO
27		case 0x1f0:
28		case 0x170:
29			return superio_get_ide_irq();
30#endif /* CONFIG_SUPERIO */
31		default:
32			return 0;
33	}
34}
35
36static __inline__ ide_ioreg_t ide_default_io_base(int index)
37{
38	switch (index) {
39#ifdef CONFIG_SUPERIO
40		case 0:	return (superio_get_ide_irq() ? 0x1f0 : 0);
41		case 1:	return (superio_get_ide_irq() ? 0x170 : 0);
42#endif /* CONFIG_SUPERIO */
43		default:
44			return 0;
45	}
46}
47
48static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
49{
50	ide_ioreg_t reg = data_port;
51	int i;
52
53	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
54		hw->io_ports[i] = reg;
55		reg += 1;
56	}
57	if (ctrl_port) {
58		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
59	} else {
60		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
61	}
62	if (irq != NULL)
63		*irq = 0;
64	hw->io_ports[IDE_IRQ_OFFSET] = 0;
65}
66
67static __inline__ void ide_init_default_hwifs(void)
68{
69#ifndef CONFIG_BLK_DEV_IDEPCI
70	hw_regs_t hw;
71	int index;
72
73	for(index = 0; index < MAX_HWIFS; index++) {
74		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
75		hw.irq = ide_default_irq(ide_default_io_base(index));
76		ide_register_hw(&hw, NULL);
77	}
78#endif /* CONFIG_BLK_DEV_IDEPCI */
79}
80
81#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
82#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
83#define ide_check_region(from,extent)		check_region((from), (extent))
84#define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
85#define ide_release_region(from,extent)		release_region((from), (extent))
86
87#define T_CHAR          (0x0000)        /* char:  don't touch  */
88#define T_SHORT         (0x4000)        /* short: 12 -> 21     */
89#define T_INT           (0x8000)        /* int:   1234 -> 4321 */
90#define T_TEXT          (0xc000)        /* text:  12 -> 21     */
91
92#define T_MASK_TYPE     (0xc000)
93#define T_MASK_COUNT    (0x3fff)
94
95#define D_CHAR(cnt)     (T_CHAR  | (cnt))
96#define D_SHORT(cnt)    (T_SHORT | (cnt))
97#define D_INT(cnt)      (T_INT   | (cnt))
98#define D_TEXT(cnt)     (T_TEXT  | (cnt))
99
100static u_short driveid_types[] = {
101	D_SHORT(10),	/* config - vendor2 */
102	D_TEXT(20),	/* serial_no */
103	D_SHORT(3),	/* buf_type - ecc_bytes */
104	D_TEXT(48),	/* fw_rev - model */
105	D_CHAR(2),	/* max_multsect - vendor3 */
106	D_SHORT(1),	/* dword_io */
107	D_CHAR(2),	/* vendor4 - capability */
108	D_SHORT(1),	/* reserved50 */
109	D_CHAR(4),	/* vendor5 - tDMA */
110	D_SHORT(4),	/* field_valid - cur_sectors */
111	D_INT(1),	/* cur_capacity */
112	D_CHAR(2),	/* multsect - multsect_valid */
113	D_INT(1),	/* lba_capacity */
114	D_SHORT(194)	/* dma_1word - reservedyy */
115};
116
117#define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
118
119static __inline__ void ide_fix_driveid(struct hd_driveid *id)
120{
121	u_char *p = (u_char *)id;
122	int i, j, cnt;
123	u_char t;
124
125	for (i = 0; i < num_driveid_types; i++) {
126		cnt = driveid_types[i] & T_MASK_COUNT;
127		switch (driveid_types[i] & T_MASK_TYPE) {
128		case T_CHAR:
129			p += cnt;
130			break;
131		case T_SHORT:
132			for (j = 0; j < cnt; j++) {
133				t = p[0];
134				p[0] = p[1];
135				p[1] = t;
136				p += 2;
137			}
138			break;
139		case T_INT:
140			for (j = 0; j < cnt; j++) {
141				t = p[0];
142				p[0] = p[3];
143				p[3] = t;
144				t = p[1];
145				p[1] = p[2];
146				p[2] = t;
147				p += 4;
148			}
149			break;
150		case T_TEXT:
151			for (j = 0; j < cnt; j += 2) {
152				t = p[0];
153				p[0] = p[1];
154				p[1] = t;
155				p += 2;
156			}
157			break;
158		};
159	}
160}
161
162/*
163 * The following are not needed for the non-m68k ports
164 */
165#define ide_ack_intr(hwif)		(1)
166#define ide_release_lock(lock)		do {} while (0)
167#define ide_get_lock(lock, hdlr, data)	do {} while (0)
168
169#endif /* __KERNEL__ */
170
171#endif /* __ASM_PARISC_IDE_H */
172