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