Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / dev / disk / wd / wdreg.h
1 /*-
2  * Copyright (c) 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * William Jolitz.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *      from: @(#)wdreg.h       7.1 (Berkeley) 5/9/91
37  * $FreeBSD: src/sys/i386/isa/wdreg.h,v 1.30 1999/12/29 04:33:16 peter Exp $
38  */
39
40 /*
41  * modified for PC9801 by F.Ukai
42  *                      Kyoto University Microcomputer Club (KMC)
43  */
44
45 /*
46  * Disk Controller register definitions.
47  */
48 #ifdef PC98
49 #define wd_data         0x0             /* data register (R/W - 16 bits) */
50 #define wd_error        0x2             /* error register (R) */
51 #define wd_precomp      wd_error        /* write precompensation (W) */
52 #define wd_features     wd_error        /* features register (W) */
53 #define wd_seccnt       0x4             /* sector count (R/W) */
54 #define wd_sector       0x6             /* first sector number (R/W) */
55 #define wd_cyl_lo       0x8             /* cylinder address, low byte (R/W) */
56 #define wd_cyl_hi       0xa             /* cylinder address, high byte (R/W)*/
57 #define wd_sdh          0xc             /* sector size/drive/head (R/W)*/
58 #define wd_command      0xe             /* command register (W)  */
59 #define wd_status wd_command            /* immediate status (R)  */
60
61 #define wd_altsts_nec   0x10c    /*alternate fixed disk status(via 1015) (R)*/
62 #define wd_ctlr_nec     0x10c    /*fixed disk controller control(via 1015) (W)*/
63 #define wd_altsts_epson 0x3      /*alternate fixed disk status(via 1015) (R)*/
64 #define wd_ctlr_epson   0x3      /*fixed disk controller control(via 1015) (W)*/
65 #define wd_altsts               wd_altsts_nec
66
67 #define  WDCTL_4BIT      0x8    /* use four head bits (wd1003) */
68 #define  WDCTL_RST       0x4    /* reset the controller */
69 #define  WDCTL_IDS       0x2    /* disable controller interrupts */
70 #define wd_digin        0x10e    /* disk controller input(via 1015) (R)*/
71 #else   /* IBM-PC */
72 #define wd_data         0x0             /* data register (R/W - 16 bits) */
73 #define wd_error        0x1             /* error register (R) */
74 #define wd_precomp      wd_error        /* write precompensation (W) */
75 #define wd_features     wd_error        /* features register (W) */
76 #define wd_seccnt       0x2             /* sector count (R/W) */
77 #define wd_sector       0x3             /* first sector number (R/W) */
78 #define wd_cyl_lo       0x4             /* cylinder address, low byte (R/W) */
79 #define wd_cyl_hi       0x5             /* cylinder address, high byte (R/W)*/
80 #define wd_sdh          0x6             /* sector size/drive/head (R/W)*/
81 #define wd_command      0x7             /* command register (W)  */
82 #define wd_status wd_command            /* immediate status (R)  */
83
84 #define wd_altsts       0x206    /*alternate fixed disk status(via 1015) (R)*/
85 #define wd_ctlr         0x206    /*fixed disk controller control(via 1015) (W)*/
86 #define  WDCTL_4BIT      0x8    /* use four head bits (wd1003) */
87 #define  WDCTL_RST       0x4    /* reset the controller */
88 #define  WDCTL_IDS       0x2    /* disable controller interrupts */
89 #define wd_digin        0x207    /* disk controller input(via 1015) (R)*/
90 #endif  /* PC98 */
91
92 /*
93  * Status Bits.
94  */
95 #define WDCS_BUSY       0x80            /* Controller busy bit. */
96 #define WDCS_READY      0x40            /* Selected drive is ready */
97 #define WDCS_WRTFLT     0x20            /* Write fault */
98 #define WDCS_SEEKCMPLT  0x10            /* Seek complete */
99 #define WDCS_DRQ        0x08            /* Data request bit. */
100 #define WDCS_ECCCOR     0x04            /* ECC correction made in data */
101 #define WDCS_INDEX      0x02            /* Index pulse from selected drive */
102 #define WDCS_ERR        0x01            /* Error detect bit. */
103
104 #define WDCS_BITS       "\020\010busy\007rdy\006wrtflt\005seekdone\004drq\003ecc_cor\002index\001err"
105 #define WDERR_ABORT     0x04
106
107 #define WDERR_BITS      "\020\010badblk\007uncorr\006id_crc\005no_id\003abort\002tr000\001no_dam"
108
109 /*
110  * Commands for Disk Controller.
111  */
112 #define WDCC_RESTORE    0x10            /* disk restore code -- resets cntlr */
113
114 #define WDCC_READ       0x20            /* disk read code */
115 #define WDCC_WRITE      0x30            /* disk write code */
116 #define  WDCC__LONG      0x02            /* modifier -- access ecc bytes */
117 #define  WDCC__NORETRY   0x01            /* modifier -- no retrys */
118
119 #define WDCC_FORMAT     0x50            /* disk format code */
120 #define WDCC_DIAGNOSE   0x90            /* controller diagnostic */
121 #define WDCC_IDC        0x91            /* initialize drive command */
122 #define WDCC_READ_MULTI 0xC4    /* read multiple */
123 #define WDCC_WRITE_MULTI        0xC5    /* write multiple */
124 #define WDCC_SET_MULTI 0xC6             /* set multiple count */
125 #define WDCC_READ_DMA   0xC8            /* read using DMA */
126 #define WDCC_WRITE_DMA  0xCA            /* write using DMA */
127
128
129 #define WDCC_EXTDCMD    0xE0            /* send extended command */
130 #define WDCC_READP      0xEC            /* read parameters from controller */
131 #define WDCC_FEATURES   0xEF            /* features control */
132
133 #define WDCC_DEFECT     0xF0            /* read defect list */
134
135 #define WDFEA_NORCACHE  0x55            /* read cache disable */
136 #define WDFEA_RCACHE    0xAA            /* read cache enable */
137 #define WDFEA_NOWCACHE  0x82            /* write cache disable */
138 #define WDFEA_WCACHE    0x02            /* write cache enable */
139 #define WDFEA_SETXFER   0x03            /* set transfer mode */
140
141 #define WD_STEP         0               /* winchester- default 35us step */
142
143 #define WDSD_IBM        0xa0            /* forced to 512 byte sector, ecc */
144 #define WDSD_LBA        0x40            /* use Logical Block Adressing */
145
146 #ifdef _KERNEL
147 /*
148  * read parameters command returns this:
149  */
150 struct wdparams {
151         /*
152          * XXX partly based on DRAFT X3T13/1153D rev 14.  
153          * by the time you read this it will have changed.
154          * Offsets in words
155          * (as that's how they are usually presented in tables
156          * e.g. QUANTUM Product manuals)
157          */
158         /* drive info */
159         short   wdp_config;             /*0 general configuration bits */
160         u_short wdp_cylinders;          /*1 number of cylinders */
161         short   wdp_reserved2;          /*2*/
162         u_short wdp_heads;              /*3 number of heads */
163         short   wdp_unfbytespertrk;     /*4 number of unformatted bytes/track */
164         short   wdp_unfbytes;           /*5 number of unformatted bytes/sec */
165         u_short wdp_sectors;            /*6 number of sectors per track */
166         short   wdp_vendorunique[3];    /*7,8,9*/
167         /* controller info */
168         char    wdp_serial[20];         /*10-19 serial number */
169         short   wdp_buffertype;         /*20 buffer type */
170 #define WDTYPE_SINGLEPORTSECTOR 1        /* single port, single sector buffer */
171 #define WDTYPE_DUALPORTMULTI    2        /* dual port, multiple sector buffer */
172 #define WDTYPE_DUALPORTMULTICACHE 3      /* above plus track cache */
173         short   wdp_buffersize;         /*21 buffer size, in 512-byte units */
174         short   wdp_necc;               /*22 ecc bytes appended */
175         char    wdp_rev[8];             /*23-26 firmware revision */
176         char    wdp_model[40];          /*27-46 model name */
177         char    wdp_nsecperint;         /*47L sectors per interrupt */
178         char    wdp_vendorunique1;      /*47H*/
179         short   wdp_usedmovsd;          /*48 can use double word read/write? */
180         char    wdp_vendorunique2;      /*49L*/
181         char    wdp_capability;         /*49H various capability bits */
182         short   wdp_cap_validate;       /*50 validation for above */
183         char    wdp_vendorunique3;      /*51L*/
184         char    wdp_opiomode;           /*51H PIO modes 0-2 */
185         char    wdp_vendorunique4;      /*52*/
186         char    wdp_odmamode;           /*52 old DMA modes, not in ATA-3 */
187         short   wdp_atavalid;           /*53 validation for newer fields */
188         short   wdp_currcyls;           /*54 */
189         short   wdp_currheads;          /*55 */
190         short   wdp_currsectors;        /*56 */
191         short   wdp_currsize0;          /*57 CHS size*/
192         short   wdp_currsize1;          /*58 CHS size*/
193         char    wdp_currmultsect;       /*59L */
194         char    wdp_multsectvalid;      /*59H */
195         int     wdp_lbasize;            /*60,61*/
196         short   wdp_dmasword;           /*62 obsolete in ATA-3 */
197         short   wdp_dmamword;           /*63 multiword DMA modes */
198         short   wdp_eidepiomodes;       /*64 advanced PIO modes */
199         short   wdp_eidedmamin;         /*65 fastest possible DMA timing */
200         short   wdp_eidedmanorm;        /*66 recommended DMA timing */
201         short   wdp_eidepioblind;       /*67 fastest possible blind PIO */
202         short   wdp_eidepioacked;       /*68 fastest possible IORDY PIO */
203         short   wdp_reserved69;         /*69*/
204         short   wdp_reserved70;         /*70*/
205         short   wdp_reserved71;         /*71*/
206         short   wdp_reserved72;         /*72*/
207         short   wdp_reserved73;         /*73*/
208         short   wdp_reserved74;         /*74*/
209         short   wdp_queuelen;           /*75*/
210         short   wdp_reserved76;         /*76*/
211         short   wdp_reserved77;         /*77*/
212         short   wdp_reserved78;         /*78*/
213         short   wdp_reserved79;         /*79*/
214         short   wdp_versmaj;            /*80*/
215         short   wdp_versmin;            /*81*/
216         short   wdp_featsupp1;          /*82*/
217         short   wdp_featsupp2;          /*83*/
218         short   wdp_featsupp3;          /*84*/
219         short   wdp_featenab1;          /*85*/
220         short   wdp_featenab2;          /*86*/
221         short   wdp_featenab3;          /*87*/
222         short   wdp_udmamode;           /*88 UltraDMA modes */
223         short   wdp_erasetime;          /*89*/
224         short   wdp_enherasetime;       /*90*/
225         short   wdp_apmlevel;           /*91*/
226         short   wdp_reserved92[34];     /*92*/
227         short   wdp_rmvcap;             /*93*/
228         short   wdp_securelevel;        /*94*/
229 };
230
231 /*
232  * IDE DMA support.
233  * This is based on what is needed for the IDE DMA function of the Intel
234  * Triton chipset; hopefully it's general enough to be used for other
235  * chipsets as well.
236  *
237  * To use this:
238  *      For each drive which you might want to do DMA on, call wdd_candma()
239  *      to get a cookie.  If it returns a null pointer, then the drive
240  *      can't do DMA.  Then call wdd_dmainit() to initialize the controller
241  *      and drive.  wdd_dmainit should leave PIO modes operational, though
242  *      perhaps with suboptimal performance.
243  *
244  *      Check the transfer by calling wdd_dmaverify().  The cookie is what
245  *      you got before; vaddr is the virtual address of the buffer to be
246  *      written; len is the length of the buffer; and direction is either
247  *      B_READ or B_WRITE. This function verifies that the DMA hardware is
248  *      capable of handling the request you've made.
249  *
250  *      Setup the transfer by calling wdd_dmaprep().  This takes the same
251  *      paramaters as wdd_dmaverify().
252  *
253  *      Send a read/write DMA command to the drive.
254  *
255  *      Call wdd_dmastart().
256  *
257  *      Wait for an interrupt.  Multi-sector transfers will only interrupt
258  *      at the end of the transfer.
259  *
260  *      Call wdd_dmadone().  It will return the status as defined by the
261  *      WDDS_* constants below.
262  */
263 struct wddma {
264         void    *(*wdd_candma)          /* returns a cookie if PCI */
265                 __P((int iobase_wd, int ctlr, int unit));
266         int     (*wdd_dmaverify)        /* verify that request is DMA-able */
267                 __P((void *cookie, char *vaddr, u_long len, int direction));
268         int     (*wdd_dmaprep)          /* prepare DMA hardware */
269                 __P((void *cookie, char *vaddr, u_long len, int direction));
270         void    (*wdd_dmastart)         /* begin DMA transfer */
271                 __P((void *cookie));
272         int     (*wdd_dmadone)          /* DMA transfer completed */
273                 __P((void *cookie));
274         int     (*wdd_dmastatus)        /* return status of DMA */
275                 __P((void *cookie));
276         int     (*wdd_dmainit)          /* initialize controller and drive */
277                 __P((void *cookie, 
278                      struct wdparams *wp, 
279                      int(wdcmd)__P((int mode, void *wdinfo)),
280                      void *wdinfo));
281         int     (*wdd_iobase)           /* returns iobase address */
282                 __P((void *cookie));
283         int     (*wdd_altiobase)        /* returns altiobase address */
284                 __P((void *cookie));
285 };
286
287 /* logical status bits returned by wdd_dmastatus */
288 #define WDDS_ACTIVE     0x0001
289 #define WDDS_ERROR      0x0002
290 #define WDDS_INTERRUPT  0x0004
291
292 #define WDDS_BITS       "\20\4interrupt\2error\1active"
293
294 /* defines for ATA timing modes */
295 #define WDDMA_GRPMASK   0xf8
296 #define WDDMA_MODEMASK  0x07
297 /* flow-controlled PIO modes */
298 #define WDDMA_PIO       0x10
299 #define WDDMA_PIO3      0x10
300 #define WDDMA_PIO4      0x11
301 /* multi-word DMA timing modes */
302 #define WDDMA_MDMA      0x20
303 #define WDDMA_MDMA0     0x20
304 #define WDDMA_MDMA1     0x21
305 #define WDDMA_MDMA2     0x22
306
307 /* Ultra DMA timing modes */
308 #define WDDMA_UDMA      0x40
309 #define WDDMA_UDMA0     0x40
310 #define WDDMA_UDMA1     0x41
311 #define WDDMA_UDMA2     0x42
312
313 #define Q_CMD640B       0x00000001 /* CMD640B quirk: serialize IDE channels */
314 void    wdc_pci(int quirks);
315
316 extern struct wddma wddma[];
317
318 void    wdintr __P((void *unit));
319
320 #endif /* _KERNEL */