FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/ida.c
1 /*
2 * Copyright (c) 1996, 1997, 1998, 1999
3 * Mark Dawson and David James. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice immediately at the beginning of the file, without modification,
10 * this list of conditions, and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD$
30 *
31 */
32
33 /*
34 * Compaq SMART disk array controller driver for FreeBSD.
35 * Supports the Compaq SMART-2 and SMART-3 families of disk
36 * array controllers.
37 *
38 */
39
40 #include "id.h"
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/conf.h>
45 #include <sys/errno.h>
46 #include <sys/malloc.h>
47 #include <sys/buf.h>
48 #include <sys/file.h>
49 #include <sys/stat.h>
50 #include <sys/proc.h>
51 #include <sys/sysctl.h>
52 #include <i386/isa/isa.h>
53 #include <i386/isa/isa_device.h>
54 #ifdef DEVFS
55 #include <sys/devfsext.h>
56 #endif /*DEVFS*/
57 /*#include <sys/dkbad.h>*/
58 #include <sys/devicestat.h>
59 #include <sys/disklabel.h>
60 #include <sys/diskslice.h>
61 #include <vm/vm.h>
62 #include <vm/vm_param.h>
63 #include <vm/vm_prot.h>
64 #include <vm/pmap.h>
65
66 #include <pci.h>
67 #include <pci/pcireg.h>
68 #include <pci/pcivar.h>
69
70 #include <sys/reboot.h>
71 extern u_long bootdev;
72
73 #define IDA_VERSION 1
74
75 #define PAGESIZ 4096
76
77 /* IDA wdc vector stealing (cuckoo) control */
78 #define IDA_CUCKOO_NEVER 0 /* never steal wdc vectors */
79 #define IDA_CUCKOO_ROOTWD 1 /* steal iff rootdev is wd device */
80 #define IDA_CUCKOO_ROOTNOTIDA 2 /* steal if rootdev not ida device */
81 #define IDA_CUCKOO_ALWAYS 3 /* always steal wdc vectors */
82
83 #ifndef IDA_CUCKOO_MODE
84 #define IDA_CUCKOO_MODE IDA_CUCKOO_ALWAYS
85 #endif
86
87 /* IDA PCI controller */
88
89 #define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae100e11ul
90 #define PCI_CONTROLLER(ctlp) (ctlp->ident == PCI_DEVICE_ID_COMPAQ_SMART2P)
91
92 typedef struct ida_pci_reg {
93 u_long unknown;
94 u_long initiate_fifo;
95 #define IDA_PCI_BUSY 1
96 u_long complete_fifo;
97 u_long interrupt;
98 #define IDA_PCI_ENABLE_INTS 1
99 #define IDA_PCI_DISABLE_INTS 0
100 u_long status;
101 #define IDA_PCI_PENDING 1
102 #define IDA_PCI_READY 2
103 } ida_pci_reg_t;
104
105 /* IDA controller register definitions */
106
107 #define R_ID0 0xc80 /* id byte 0 */
108 #define R_ID1 0xc81 /* id byte 1 */
109 #define R_ID2 0xc82 /* id byte 2 */
110 #define R_ID3 0xc83 /* id byte 3 */
111 #define R_CONF 0xc88 /* global configuration */
112 #define R_SYSINT 0xc89 /* system interrupt enable/ctrl */
113 #define R_SEM0 0xc8a /* semaphore port 0 */
114 #define R_SEM1 0xc8b /* semaphore port 1 */
115 #define R_LBELL_E 0xc8c /* local doorbell enable */
116 #define R_LBELL_I 0xc8d /* local doorbell int/status */
117 #define R_EBELL_E 0xc8e /* EISA doorbell enable */
118 #define R_EBELL_I 0xc8f /* EISA doorbell int/status */
119 #define R_SUB_ADDR 0xc90 /* submit address */
120 #define R_SUB_LEN 0xc94 /* submit cmdlist size */
121 #define R_COM_ADDR 0xc98 /* completion address */
122 #define R_COM_OFF 0xc9c /* completion request offset */
123 #define R_COM_STAT 0xc9e /* completion cmdlist status */
124 #define R_INTDEF 0xcc0 /* interrupt definition */
125
126 /*
127 * BMIC doorbell status codes
128 */
129
130 #define BMIC_DATA_READY 0x01 /* data ready bit */
131 #define BMIC_CHAN_CLEAR 0x02 /* channel clear bit */
132
133
134 /* IDA controller command list return status values */
135
136 #define IDA_COMPL_OK 0x01 /* command list completed ok */
137 #define IDA_NON_FATAL 0x02 /* non-fatal error */
138 #define IDA_FATAL 0x04 /* fatal error */
139 #define IDA_ABORTED 0x08 /* command list aborted */
140 #define IDA_INVAL_REQ 0x10 /* bad request block */
141 #define IDA_INVAL_LIST 0x20 /* bad command list */
142 #define IDA_AARGH_LIST 0x40 /* totally disastrous command list */
143
144
145 /* IDA controller command codes */
146
147 #define IDA_GET_DRV_INFO 0x10
148 #define IDA_GET_CTL_INFO 0x11
149 #define IDA_READ_DATA 0x20
150 #define IDA_WRITE_DATA 0x30
151 #define IDA_FLUSH_CACHE 0xc2
152
153
154 /* Interrupt definition codes */
155
156 #define IDA_IRQ_MASK 0xfc
157 #define IDA_IRQ_10 0x20
158 #define IDA_IRQ_11 0x10
159 #define IDA_IRQ_14 0x40
160 #define IDA_IRQ_15 0x80
161
162
163 /* IDA controller hardware command structure definitions */
164
165 typedef u_long physaddr_t;
166
167 struct ida_hdr {
168 u_long drive:8; /* logical drive */
169 u_long priority:8; /* block priority */
170 u_long flags:16; /* control flags */
171 };
172
173 struct ida_req {
174 u_long next:16; /* offset of next request */
175 u_long command:8; /* command */
176 u_long error:8; /* return error code */
177 u_long blkno; /* block number */
178 u_short bcount; /* block count */
179 u_short sgcount; /* number of scatter gather entries */
180
181 /* a struct ida_req is followed physically by an array of struct ida_sgb */
182 };
183
184 struct ida_sgb {
185 u_long len; /* length of scatter gather segmmentk */
186 physaddr_t addr; /* physical address of block */
187 };
188
189
190 /* first some handy definitions as FreeBSD gcc doesn't do #pragma pack() */
191
192 #define pack_char(name) u_char name[1]
193 #define pack_short(name) u_char name[2]
194 #define pack_int(name) u_char name[4]
195 #define pack_long(name) u_char name[4]
196
197 /* ugly, but not inefficient, as it gets evaluated at compile time by gcc */
198
199 #define u_unpack(member) ( \
200 (sizeof(member) == 1) ? *(u_char *)(member) \
201 : (sizeof(member) == 2) ? *(u_short *)(member) \
202 : *(u_int *)(member) \
203 )
204
205 #define s_unpack(member) ( \
206 (sizeof(member) == 1) ? *(char *)(member) \
207 : (sizeof(member) == 2) ? *(short *)(member) \
208 : *(int *)(member) \
209 )
210
211 /* IDA controller hardware returned data structure definitions */
212
213 struct ida_ctl_info {
214 pack_char(num_drvs);
215 pack_long(signature);
216 pack_long(firm_rev);
217 };
218
219 struct ida_drv_info {
220 pack_short(secsize);
221 pack_long(secperunit);
222 pack_short(ncylinders);
223 pack_char(ntracks);
224 pack_char(signature);
225 pack_char(psectors);
226 pack_short(wprecomp);
227 pack_char(max_acc);
228 pack_char(control);
229 pack_short(pcylinders);
230 pack_char(ptracks);
231 pack_short(landing_zone);
232 pack_char(nsectors);
233 pack_char(checksum);
234 pack_char(mirror);
235 };
236
237
238 /* IDA driver queue command block */
239
240 #define IDA_MAX_SGLEN 32 /* maximum entries in scatter gather list */
241 #define IDA_MAX_DRVS_CTLR 8 /* maximum logical drives per controller */
242 #define IDA_DEF_PRIORITY 16 /* default priority for command list */
243
244 #define IDA_SCSI_TARGET_ID 7
245 #define IDA_QCB_MAX 256
246
247 struct ida_qcb {
248 /* first some hardware specific fields ... */
249
250 struct ida_hdr hdr;
251 struct ida_req req;
252 struct ida_sgb sglist[IDA_MAX_SGLEN];
253
254 /* and then some driver queue managment stuff */
255
256 u_int flags; /* qcb type */
257 #define QCB_FREE 0 /* ready for a new command */
258 #define QCB_ACTIVE 1 /* waiting to be sent to the controller */
259 #define QCB_SENT 2 /* waiting for interrupt from the controller */
260 #define QCB_IMMED 4 /* immediate (non-queued) command */
261 #define QCB_IMMED_FAIL 8
262 struct ida_qcb *next; /* next ida command block of this type */
263 struct ida_qcb *last; /* last ida command block of this type */
264 struct buf *buf; /* buf associated with this qcb */
265 physaddr_t paddr; /* physical address of this struct */
266 struct ida_qcb *nexthash; /* next ida command block with same hash value */
267 };
268 typedef struct ida_qcb qcb_t;
269
270
271 /* IDA driver controller and drive information blocks */
272
273 #define QCB_HASH_SIZE 257 /* some suitable prime number */
274 #define QCB_HASH(h) ((h) % QCB_HASH_SIZE)
275
276 struct ida_drv {
277 u_int flags;
278 #define ID_INIT 0x0001
279 #define ID_WRITEPROT 0x0002
280 #define ID_DEV_OPEN 0x0004
281 u_int ctl_unit; /* which controller is this drive on */
282 u_int drv_unit; /* number of this virtual disk */
283 struct ida_drv_info drv_info; /* data from the controller */
284 struct diskslices *slices; /* new slice code */
285 struct devstat dk_stats; /* devstat entry */
286 };
287
288 struct ida_ctl {
289 u_int ident; /* controller identifier */
290 u_int flags;
291 u_int iobase;
292 u_short inside; /* number of qcbs in the controller */
293 u_short max_inside; /* maximum number simulaneously active */
294 u_short num_qcbs; /* number of qcbs allocated */
295 u_char num_drvs;
296 u_char irq;
297 u_char com_status; /* status of last completed command list */
298 physaddr_t com_addr; /* address of last completed command list */
299 u_short com_offset; /* offset of last completed command list */
300 qcb_t *freelist; /* linked list of free qcbs */
301 qcb_t *send_next; /* doubly-linked list of unsent qcbs */
302 qcb_t *send_last; /* because we must treat all jobs equally */
303 qcb_t *hashlist[QCB_HASH_SIZE];
304 };
305
306 extern struct ida_ctl *idadata[NIDA];
307
308
309 /* Useful IDA controller IO macro definitions */
310
311 #define IDA_DISABLE_INTERRUPT(iobase) outb(iobase + R_SYSINT, 0)
312 #define IDA_ENABLE_INTERRUPT(ctlp) outb(ctlp->iobase + R_SYSINT, 1)
313
314 #define IDA_SET_READY(ctlp) outb(ctlp->iobase + R_EBELL_E, 1)
315
316 #define IDA_DATA_READY(ctlp) ((inb(ctlp->iobase + R_EBELL_I) & 1))
317 #define IDA_CHAN_CLEAR(ctlp) ((inb(ctlp->iobase + R_EBELL_I) & 2))
318
319 /* enable/disable interrupts on a change of channel clear status (?) */
320
321 #define IDA_ENABLE_CHAN(ctlp) \
322 outb(ctlp->iobase + R_EBELL_E, inb(ctlp->iobase + R_EBELL_E) | 2)
323 #define IDA_DISABLE_CHAN(ctlp) \
324 outb(ctlp->iobase + R_EBELL_E, inb(ctlp->iobase + R_EBELL_E) & ~0x2)
325
326 /* acknowledge the completion of a command */
327
328 #define IDA_ACK_CMD_COM(ctlp) \
329 (outb(ctlp->iobase + R_EBELL_I, 1), outb(ctlp->iobase + R_LBELL_I, 2))
330
331 /* set submission details for a command list */
332
333 #define IDA_SET_SUB_ADDR(ctlp, addr) outl(ctlp->iobase + R_SUB_ADDR, addr)
334 #define IDA_SET_SUB_LEN(ctlp, size) outw(ctlp->iobase + R_SUB_LEN, size)
335
336 /* get completion details for a command list */
337
338 #define IDA_GET_COM_ADDR(ctlp) inl(ctlp->iobase + R_COM_ADDR)
339 #define IDA_GET_COM_OFFSET(ctlp) inw(ctlp->iobase + R_COM_OFF)
340 #define IDA_GET_COM_STATUS(ctlp) inb(ctlp->iobase + R_COM_STAT)
341
342
343 #define IDA_READ_EBELL_I(ctlp) inb(ctlp->iobase + R_EBELL_I)
344 #define IDA_READ_EBELL_E(ctlp) inb(ctlp->iobase + R_EBELL_E)
345 #define IDA_READ_LBELL_I(ctlp) inb(ctlp->iobase + R_LBELL_I)
346 #define IDA_SET_EBELL_I(ctlp, n) outb(ctlp->iobase + R_EBELL_I, n)
347 #define IDA_SET_LBELL_I(ctlp, n) outb(ctlp->iobase + R_LBELL_I, n)
348
349 #define JOB_SUCCESS 0
350 #define JOB_FAILURE 1
351 #define JOB_ABORTED 2
352
353 /* debugging aids */
354
355 #ifdef IDADEBUG
356 # define IDA_MAXQCBS (1<<0)
357 # define IDA_SHOWQCBS (1<<1)
358 # define IDA_SHOWSUBS (1<<2)
359 # define IDA_SHOWINTS (1<<3)
360 # define IDA_SHOWCMDS (1<<4)
361 # define IDA_SHOWMISC (1<<5)
362 void ida_print_qcb(qcb_t *qcbp);
363 void ida_print_active_qcb(int unit);
364 static int ida_debug = 0;
365 SYSCTL_INT(_debug, OID_AUTO, ida_debug, CTLFLAG_RW, &ida_debug, 0, "");
366 #endif
367
368 static int ida_soft_errors = 0;
369 SYSCTL_INT(_debug, OID_AUTO, ida_soft_errors,
370 CTLFLAG_RW, &ida_soft_errors, 0, "");
371
372 /* EISA probe and board identification definitions */
373
374 #define MAX_EISA_SLOT 16
375 #define IDA_EISA_PROD_ID 0x40
376
377 union eisa_id {
378 u_int value;
379 struct {
380 u_int rev:8;
381 u_int prod:8;
382 u_int mfr2:5;
383 u_int mfr1:5;
384 u_int mfr0:5;
385 } split;
386 };
387
388
389 /* test the manufacturer ID within an EISA board ID */
390
391 #define EISA_MFR_EQ(ident, mfr) ( \
392 (ident).split.mfr0 + '@' == (mfr)[0] && \
393 (ident).split.mfr1 + '@' == (mfr)[1] && \
394 (ident).split.mfr2 + '@' == (mfr)[2] \
395 )
396
397 /* generates a list of EISA board ID values, suitable for a printf */
398
399 #define EISA_ID_LIST(ident) \
400 (ident).split.mfr0 + '@', \
401 (ident).split.mfr1 + '@', \
402 (ident).split.mfr2 + '@', \
403 (ident).split.prod, \
404 (ident).split.rev
405
406 extern void DELAY(int millisecs);
407
408 /* FreeBSD IDA driver forward function definitions */
409
410 static d_open_t idopen;
411 static d_read_t idread;
412 static d_write_t idwrite;
413 static d_close_t idclose;
414 static d_strategy_t idstrategy;
415 static d_ioctl_t idioctl;
416 static d_dump_t iddump;
417 static d_psize_t idsize;
418
419 static pci_inthand_t idaintr;
420
421 static const char *ida_pci_probe(pcici_t tag, pcidi_t type);
422 static void ida_pci_attach(pcici_t config_id, int unit);
423
424 static int ida_eisa_probe __P((struct isa_device *dev));
425 static int ida_eisa_attach __P((struct isa_device *dev));
426 static int ida_poll __P((int unit, int wait));
427
428 static void idaminphys __P((struct buf *bp));
429 static void ida_start __P((int unit));
430
431 static int ida_get_ctl_info(int unit);
432 static int ida_attach_drives(int unit);
433 void ida_done(int cntlr, qcb_t *qcbp, int state);
434 static void ida_queue_buf(int cntlr, struct buf *bp);
435 static void ida_newqueue(int cntlr);
436 static qcb_t *ida_dequeue(int cntlr);
437 static void ida_enqueue(int cntlr, qcb_t *qcbp);
438 static int ida_submit(int unit, qcb_t *qcbp, int size);
439 static int ida_submit_wait(int unit, qcb_t *qcbp, int size);
440 static qcb_t *ida_get_qcb(int unit);
441 static void ida_free_qcb(int unit, qcb_t *qcbp);
442 static qcb_t *ida_qcb_phys_kv(struct ida_ctl *ida, physaddr_t ida_qcb_phys);
443
444 static struct cdevsw id_cdevsw;
445
446 struct isa_driver idadriver = {
447 ida_eisa_probe,
448 ida_eisa_attach,
449 "ida"
450 };
451
452 static u_long ida_pci_count;
453
454 static struct pci_device ida_pci_driver = {
455 "ida",
456 ida_pci_probe,
457 ida_pci_attach,
458 &ida_pci_count
459 };
460
461 DATA_SET (pcidevice_set, ida_pci_driver);
462
463 /* definitions for stealing wd driver's vectors */
464
465 #define ID_BDMAJ 29
466 #define ID_CDMAJ 109
467 #define WD_BDMAJ 0
468 #define WD_CDMAJ 3
469
470 struct isa_driver wdcdriver;
471 static int stub_probe __P((struct isa_device *dev));
472 static int stub_attach __P((struct isa_device *dev));
473
474 static struct isa_driver nodriver = {
475 stub_probe,
476 stub_attach,
477 "stub"
478 };
479
480 /* steal the wdc driver's vectors if we have booted off a wd device */
481
482 static
483 void
484 ida_cuckoo_wdc(void)
485 {
486 int cuckoo = IDA_CUCKOO_MODE;
487 int steal = 0;
488 char *mode;
489 int major = B_TYPE(bootdev);
490
491 if (cuckoo == IDA_CUCKOO_NEVER) {
492 mode = "never";
493 } else if (cuckoo == IDA_CUCKOO_ROOTWD) {
494 mode = "rootwd";
495 steal = (major == WD_BDMAJ);
496 } else if (cuckoo == IDA_CUCKOO_ROOTNOTIDA) {
497 mode = "notida";
498 /* check for magic value of 3 rather than ID_BDMAJ as boot code
499 * pretends we are a wt device (not normally bootable)
500 */
501 steal = (major != 3);
502 } else {
503 mode = "always";
504 steal = 1;
505 }
506
507 printf("ida: wdc vector stealing %s (mode = %s, boot major = %d)\n",
508 (steal ? "on" : "off"), mode, major);
509 if (!steal) return;
510
511 /* OK - we have a controller, so steal wd driver's vectors */
512 wdcdriver = nodriver;
513 bdevsw[WD_BDMAJ]->d_open = cdevsw[WD_CDMAJ]->d_open = idopen;
514 bdevsw[WD_BDMAJ]->d_close = cdevsw[WD_CDMAJ]->d_close = idclose;
515 bdevsw[WD_BDMAJ]->d_read = cdevsw[WD_CDMAJ]->d_read = idread;
516 bdevsw[WD_BDMAJ]->d_write = cdevsw[WD_CDMAJ]->d_write = idwrite;
517 bdevsw[WD_BDMAJ]->d_strategy = cdevsw[WD_CDMAJ]->d_strategy = idstrategy;
518 bdevsw[WD_BDMAJ]->d_ioctl = cdevsw[WD_CDMAJ]->d_ioctl = idioctl;
519 bdevsw[WD_BDMAJ]->d_dump = iddump;
520 bdevsw[WD_BDMAJ]->d_psize = idsize;
521 return;
522 }
523
524 static struct ida_ctl *idadata[NIDA]; /* controller structures */
525 static struct ida_drv *id_drive[NID]; /* table of drives */
526 static int id_unit = 0; /* number of drives found */
527
528 /* general purpose data buffer for 'special' IDA driver commands */
529
530 union ida_buf {
531 char pad[512];
532 struct ida_ctl_info ctl;
533 struct ida_drv_info drv;
534 } ida_buf;
535
536 static int
537 stub_probe(struct isa_device *dev)
538 {
539 return 0;
540 }
541
542 static int
543 stub_attach(struct isa_device *dev)
544 {
545 return 0;
546 }
547
548 const char *
549 ida_pci_probe(pcici_t tag, pcidi_t type)
550 {
551 switch (type) {
552 case PCI_DEVICE_ID_COMPAQ_SMART2P:
553 return "Compaq SMART-2/P array controller";
554 break;
555 default:
556 break;
557 }
558 return NULL;
559 }
560
561 static void
562 ida_pci_attach(pcici_t config_id, int unit)
563 {
564 ida_pci_reg_t *reg;
565 struct ida_ctl *ctlp;
566 u_long id;
567 vm_offset_t paddr, vaddr;
568
569 id = pci_conf_read(config_id, PCI_ID_REG);
570 switch (id) {
571 case PCI_DEVICE_ID_COMPAQ_SMART2P:
572 break;
573 default:
574 break;
575 }
576
577 if (!pci_map_mem(config_id, 0x14, &vaddr, &paddr)) {
578 printf("ida: map failed.\n");
579 return;
580 }
581
582 /* allocate and initialise a storage area for this controller */
583 if (idadata[unit]) {
584 printf("ida%d: controller structure already allocated\n", unit);
585 return;
586 }
587 if ((ctlp = malloc(sizeof(struct ida_ctl), M_TEMP, M_NOWAIT)) == NULL) {
588 printf("ida%d: unable to allocate controller structure\n", unit);
589 return;
590 }
591
592 idadata[unit] = ctlp;
593 bzero(ctlp, sizeof(struct ida_ctl));
594 ctlp->ident = id;
595 ctlp->iobase = vaddr;
596
597 /* Install the interrupt handler. */
598 if (!pci_map_int (config_id, idaintr, (void *)unit, &bio_imask)) {
599 printf ("ida%d: failed to assign an interrupt handler\n", unit);
600 free((caddr_t)ctlp, M_DEVBUF);
601 idadata[unit] = 0;
602 return;
603 }
604
605 if (!(ida_get_ctl_info(unit) && ida_attach_drives(unit))) {
606 return;
607 }
608
609 reg = (ida_pci_reg_t *) vaddr;
610 reg->interrupt = IDA_PCI_ENABLE_INTS;
611 ida_cuckoo_wdc();
612 return;
613 }
614
615 int
616 ida_eisa_probe(struct isa_device *dev)
617 {
618 static u_int ida_used = 0;
619 u_int slot;
620 u_int port;
621 u_char intdef;
622 u_char irq;
623 int unit = dev->id_unit;
624 union eisa_id ident;
625 struct ida_ctl *ctlp;
626
627 if (dev->id_iobase) {
628 /* check out the configured iobase if given one */
629 slot = dev->id_iobase / 0x1000;
630 if (slot == 0 || slot > MAX_EISA_SLOT) {
631 printf("ida: port address (0x%x) out of range\n", dev->id_iobase);
632 return 0;
633 }
634 } else {
635 /* otherwise, search from the beginning for an unused slot to check out */
636 slot = 1;
637 }
638
639 while (1) {
640 while (ida_used & (1 << slot)) {
641 if (slot++ == MAX_EISA_SLOT) return 0;
642 }
643
644 ida_used |= (1 << slot);
645 port = slot * 0x1000;
646
647 /* read the EISA identification bytes */
648 ident.value = inb(port + R_ID0);
649 ident.value <<= 8;
650 ident.value |= inb(port + R_ID1);
651 ident.value <<= 8;
652 ident.value |= inb(port + R_ID2);
653 ident.value <<= 8;
654 ident.value |= inb(port + R_ID3);
655
656 /* check that the card is the right type ? */
657 if (EISA_MFR_EQ(ident, "CPQ") && ident.split.prod == IDA_EISA_PROD_ID) {
658 break;
659 }
660
661 /* if we were config'ed with an iobase, then don't probe any more slots */
662 if (dev->id_iobase) return 0;
663 }
664
665 /* disable interrupts and find out what interrupt this controller uses */
666 IDA_DISABLE_INTERRUPT(port);
667
668 intdef = inb(port + R_INTDEF);
669 switch (intdef & IDA_IRQ_MASK) {
670 case IDA_IRQ_10:
671 irq = 10;
672 break;
673
674 case IDA_IRQ_11:
675 irq = 11;
676 break;
677
678 case IDA_IRQ_14:
679 irq = 14;
680 break;
681
682 case IDA_IRQ_15:
683 irq = 15;
684 break;
685
686 default:
687 printf("ida: slot %d bogus interrupt setting (0x%02x)\n", slot, intdef);
688 return 0;
689 }
690 dev->id_irq = (1 << irq);
691 dev->id_drq = -1;
692
693 /* allocate and initialise a storage area for this controller */
694 if (idadata[unit]) {
695 printf("ida%d: controller structure already allocated\n", unit);
696 return 0;
697 }
698 if ((ctlp = malloc(sizeof(struct ida_ctl), M_TEMP, M_NOWAIT)) == NULL) {
699 printf("ida%d: unable to allocate controller structure\n", unit);
700 return 0;
701 }
702 idadata[unit] = ctlp;
703
704 bzero(ctlp, sizeof(struct ida_ctl));
705 ctlp->iobase = dev->id_iobase = port;
706 ctlp->ident = ident.value;
707 ctlp->irq = irq;
708
709 if (ida_get_ctl_info(unit) == 0) {
710 return 0;
711 }
712
713 /* return range of io ports used */
714 return 0x1000;
715 }
716
717 int
718 ida_get_ctl_info(int unit)
719 {
720 struct ida_ctl *ctlp = idadata[unit];
721 qcb_t qcb;
722 qcb_t *qcbp = &qcb;
723
724 ida_newqueue(unit);
725 /* controller capacity statistics */
726 ctlp->inside = 0;
727 ctlp->max_inside = 0;
728
729 /* ask the controller to tell us about itself with an IDA_GET_CTL_INFO */
730 bzero(qcbp, sizeof(qcb_t));
731 qcbp->paddr = vtophys(qcbp);
732 if (PCI_CONTROLLER(ctlp)) {
733 qcbp->hdr.priority = 0x00;
734 qcbp->hdr.flags = 0x24;
735 } else {
736 qcbp->hdr.priority = IDA_DEF_PRIORITY;
737 qcbp->hdr.flags = 0x12;
738 }
739 qcbp->req.command = IDA_GET_CTL_INFO;
740 qcbp->req.bcount = 1;
741 qcbp->req.sgcount = 1;
742 qcbp->sglist[0].len = sizeof(ida_buf);
743 qcbp->sglist[0].addr = vtophys(&ida_buf);
744
745 if (ida_submit_wait(unit, qcbp, sizeof(struct ida_qcb))) {
746 printf("ida%d: idasubmit failed on IDA_GET_CTL_INFO\n", unit);
747 return 0;
748 }
749
750 if (!PCI_CONTROLLER(ctlp)) {
751 if (ctlp->com_status != IDA_COMPL_OK) {
752 printf("ida%d: bad status 0x%02x from IDA_GET_CTL_INFO\n",
753 unit, ctlp->com_status);
754 return 0;
755 }
756 }
757
758 /* got the information at last, print it and note the number of drives */
759 printf("ida%d: drvs=%d firm_rev=%c%c%c%c\n", unit,
760 u_unpack(ida_buf.ctl.num_drvs), ida_buf.ctl.firm_rev[0],
761 ida_buf.ctl.firm_rev[1], ida_buf.ctl.firm_rev[2],
762 ida_buf.ctl.firm_rev[3]);
763 ctlp->num_drvs = u_unpack(ida_buf.ctl.num_drvs);
764
765 return 1;
766 }
767
768 int
769 ida_attach_drives(int cntlr)
770 {
771 struct ida_ctl *ctlp = idadata[cntlr];
772 qcb_t qcb;
773 qcb_t *qcbp = &qcb;
774 struct ida_drv *drv;
775 int drive;
776 int unit;
777
778 /* prepare to interrogate the drives */
779 bzero(qcbp, sizeof(qcb_t));
780 qcbp->req.command = IDA_GET_DRV_INFO;
781 qcbp->paddr = vtophys(qcbp);
782 if (PCI_CONTROLLER(ctlp)) {
783 qcbp->hdr.priority = 0x00;
784 qcbp->hdr.flags = 0x24;
785 } else {
786 qcbp->hdr.priority = IDA_DEF_PRIORITY;
787 qcbp->hdr.flags = 0x12;
788 }
789 qcbp->req.bcount = 1;
790 qcbp->req.sgcount = 1;
791 qcbp->sglist[0].len = sizeof(ida_buf);
792 qcbp->sglist[0].addr = vtophys(&ida_buf);
793
794 for (drive = 0 ; drive < ctlp->num_drvs ; drive++) {
795 qcbp->hdr.drive = drive;
796
797 if (ida_submit_wait(cntlr, qcbp, sizeof(struct ida_qcb))) {
798 printf("ida%d: ida_submit_wait failed on IDA_GET_DRV_INFO\n", cntlr);
799 return 0;
800 }
801
802 if (!PCI_CONTROLLER(ctlp)) {
803 if (ctlp->com_status != IDA_COMPL_OK) {
804 printf("ida%d: bad status 0x%02x from IDA_GET_DRV_INFO\n",
805 cntlr, ctlp->com_status);
806 return 0;
807 }
808 }
809
810 if ((drv = malloc(sizeof(struct ida_drv), M_TEMP, M_NOWAIT)) == NULL) {
811 printf("ida%d: unable to allocate drive structure\n", cntlr);
812 return 0;
813 }
814
815 bzero(drv, sizeof(struct ida_drv));
816 drv->ctl_unit = cntlr;
817 drv->drv_unit = drive;
818 drv->drv_info = ida_buf.drv;
819 drv->flags |= ID_INIT;
820
821 unit = id_unit;
822 id_unit++; /* XXX unsure if this is the right way to do things */
823 id_drive[unit] = drv;
824
825 printf("ida%d: unit %d (id%d): <%s>\n",
826 cntlr, drive, unit, "Compaq Logical Drive");
827 printf("id%d: %luMB (%lu total sec), ",
828 unit,
829 (u_long)(u_unpack(drv->drv_info.secperunit) / 2048)
830 * (u_unpack(drv->drv_info.secsize) / 512),
831 (u_long)u_unpack(drv->drv_info.secperunit));
832 printf("%lu cyl, %lu head, %lu sec, bytes/sec %lu\n",
833 (u_long)u_unpack(drv->drv_info.ncylinders),
834 (u_long)u_unpack(drv->drv_info.ntracks),
835 (u_long)u_unpack(drv->drv_info.nsectors),
836 (u_long)u_unpack(drv->drv_info.secsize));
837
838 /*
839 * Export the drive to the devstat interface.
840 */
841 devstat_add_entry(&drv->dk_stats, "id",
842 unit, (u_int32_t)drv->drv_info.secsize,
843 DEVSTAT_NO_ORDERED_TAGS,
844 DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
845 DEVSTAT_PRIORITY_DA);
846
847 #ifdef IDADEBUG
848 if (ida_debug & IDA_SHOWMISC) {
849 printf("ida%d: drive %d secsize=%d secperunit=%d ncylinders=%d ntracks=%d\n",
850 unit,
851 drive,
852 u_unpack(ida_buf.drv.secsize),
853 u_unpack(ida_buf.drv.secperunit),
854 u_unpack(ida_buf.drv.ncylinders),
855 u_unpack(ida_buf.drv.ntracks));
856 printf(" signature=0x%02x psectors=%d wprecomp=%d max_acc=%d control=0x%02x\n",
857 u_unpack(ida_buf.drv.signature),
858 u_unpack(ida_buf.drv.psectors),
859 u_unpack(ida_buf.drv.wprecomp),
860 u_unpack(ida_buf.drv.max_acc),
861 u_unpack(ida_buf.drv.control));
862 printf(" pcylinders=%d ptracks=%d landing_zone=%d nsectors=%d checksum=0x%02x\n",
863 u_unpack(ida_buf.drv.pcylinders),
864 u_unpack(ida_buf.drv.ptracks),
865 u_unpack(ida_buf.drv.landing_zone),
866 u_unpack(ida_buf.drv.nsectors),
867 u_unpack(ida_buf.drv.checksum));
868 }
869 #endif
870 }
871
872 return 1;
873 }
874
875 /* Attach all the sub-devices we can find. */
876 int
877 ida_eisa_attach(struct isa_device *dev)
878 {
879 int cntlr = dev->id_unit;
880 struct ida_ctl *ctlp = idadata[cntlr];
881
882 if (ida_attach_drives(cntlr)) {
883 IDA_ENABLE_INTERRUPT(ctlp);
884 IDA_SET_READY(ctlp);
885 ida_cuckoo_wdc();
886 return 1;
887 } else {
888 return 0;
889 }
890 }
891
892 /*
893 * Initialize a drive.
894 */
895 int
896 idopen(dev_t dev, int flags, int fmt, struct proc *p)
897 {
898 struct ida_drv *drv;
899 int part = dkpart(dev);
900 int unit = dkunit(dev);
901 struct disklabel label;
902 int err;
903
904 if (unit >= NID || part >= MAXPARTITIONS) /* bounds check */
905 return(ENXIO);
906
907 drv = id_drive[unit];
908 if (!drv || !(drv->flags & ID_INIT)) /* drive not initialised */
909 return(ENXIO);
910
911 drv->flags |= ID_DEV_OPEN;
912
913 /* knock up a label for the whole disk. */
914 bzero(&label, sizeof label);
915 label.d_secsize = u_unpack(drv->drv_info.secsize);
916 label.d_nsectors = u_unpack(drv->drv_info.nsectors);
917 label.d_ntracks = u_unpack(drv->drv_info.ntracks);
918 label.d_ncylinders = u_unpack(drv->drv_info.ncylinders);
919 label.d_secpercyl =
920 u_unpack(drv->drv_info.ntracks) * u_unpack(drv->drv_info.nsectors);
921 if (label.d_secpercyl == 0)
922 label.d_secpercyl = 100; /* prevent accidental division by zero */
923 label.d_secperunit = u_unpack(drv->drv_info.secperunit);
924
925 /* Initialize slice tables. */
926 if ((err = dsopen("id", dev, fmt, 0, &drv->slices, &label, idstrategy,
927 (ds_setgeom_t *)NULL, &id_cdevsw)) == NULL) {
928 return 0;
929 }
930
931 if (!dsisopen(drv->slices)) {
932 drv->flags &= ~ID_DEV_OPEN;
933 }
934 return err;
935 }
936
937 /* ARGSUSED */
938 int
939 idclose(dev_t dev, int flags, int fmt, struct proc *p)
940 {
941 struct ida_drv *drv;
942 int part = dkpart(dev);
943 int unit = dkunit(dev);
944
945 if (unit >= NID || part >= MAXPARTITIONS) /* bounds check */
946 return(ENXIO);
947
948 drv = id_drive[unit];
949 dsclose(dev, fmt, drv->slices);
950 if (!dsisopen(drv->slices)) {
951 drv->flags &= ~ID_DEV_OPEN;
952 }
953 return 0;
954 }
955
956
957
958 int
959 idioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
960 {
961 struct ida_drv *drv;
962 int part = dkpart(dev);
963 int unit = dkunit(dev);
964 int err;
965
966 if (unit >= NID || part >= MAXPARTITIONS ||
967 !(drv = id_drive[unit]) || !(drv->flags & ID_INIT)) /* sanity check */
968 return(ENXIO);
969
970 err = dsioctl("id", dev, cmd, addr, flag, &drv->slices,
971 idstrategy, (ds_setgeom_t *)NULL);
972
973 if (err != -1)
974 return (err);
975
976 if (dkpart(dev) != RAW_PART)
977 return (ENOTTY);
978
979 return (0);
980 }
981 static int
982 idread(dev_t dev, struct uio *uio, int ioflag)
983 {
984 return (physio(idstrategy, NULL, dev, 1, minphys, uio));
985 }
986
987 static int
988 idwrite(dev_t dev, struct uio *uio, int ioflag)
989 {
990 return (physio(idstrategy, NULL, dev, 0, minphys, uio));
991 }
992
993
994 /* Read/write routine for a buffer. Finds the proper unit, range checks
995 * arguments, and schedules the transfer. Does not wait for the transfer
996 * to complete. Multi-page transfers are supported. All I/O requests must
997 * be a multiple of a sector in length.
998 */
999 void
1000 idstrategy(struct buf *bp)
1001 {
1002 int unit = dkunit(bp->b_dev);
1003 struct ida_drv *drv;
1004 int opri;
1005
1006 if (unit >= NID) {
1007 printf("ida: unit out of range\n");
1008 bp->b_error = EINVAL;
1009 goto bad;
1010 }
1011
1012 if (!(drv = id_drive[unit]) || !(drv->flags & ID_INIT)) {
1013 printf("id%d: drive not initialised\n", unit);
1014 bp->b_error = EINVAL;
1015 goto bad;
1016 }
1017
1018 if (bp->b_blkno < 0) {
1019 printf("id%d: negative block requested\n", unit);
1020 bp->b_error = EINVAL;
1021 goto bad;
1022 }
1023
1024 if (bp->b_bcount % DEV_BSIZE != 0) { /* bounds check */
1025 printf("id%d: count (%lu) not a multiple of a block\n",
1026 unit, bp->b_bcount);
1027 bp->b_error = EINVAL;
1028 goto bad;
1029 }
1030
1031 idaminphys(bp); /* adjust the transfer size */
1032
1033 /* "soft" write protect check */
1034 if ((drv->flags & ID_WRITEPROT) && (bp->b_flags & B_READ) == 0) {
1035 bp->b_error = EROFS;
1036 goto bad;
1037 }
1038
1039 /* If it's a null transfer, return immediately */
1040 if (bp->b_bcount == 0) {
1041 goto done;
1042 }
1043
1044 if (dscheck(bp, drv->slices) <= 0) {
1045 goto done;
1046 }
1047
1048 opri = splbio();
1049 ida_queue_buf(unit, bp);
1050 devstat_start_transaction(&drv->dk_stats);
1051 ida_start(drv->ctl_unit); /* hit the appropriate controller */
1052 splx(opri);
1053
1054 return /**/;
1055
1056 bad:
1057 bp->b_flags |= B_ERROR;
1058
1059 done:
1060 /* correctly set the buf to indicate a completed xfer */
1061 bp->b_resid = bp->b_bcount;
1062 biodone(bp);
1063 return /**/;
1064 }
1065
1066
1067 void
1068 idaminphys(bp)
1069 struct buf *bp;
1070 {
1071 /* assumes each page requires an sgb entry */
1072 int max = (IDA_MAX_SGLEN - 1) * PAGESIZ;
1073 if (bp->b_bcount > max) {
1074 bp->b_bcount = max;
1075 }
1076 }
1077
1078
1079 /* Get a free qcb.
1080 * If there are none, see if we can allocate a new one.
1081 * If so, put it in the hash table too,
1082 * otherwise either return an error or sleep.
1083 */
1084 static qcb_t *
1085 ida_get_qcb(int unit)
1086 {
1087 struct ida_ctl *ida = idadata[unit];
1088 unsigned opri = 0;
1089 qcb_t *qcbp;
1090 int hashnum;
1091
1092 opri = splbio();
1093
1094 /* if the freelist is empty - create a qcb until limit is reached */
1095 while (!(qcbp = ida->freelist)) {
1096 if (ida->num_qcbs < IDA_QCB_MAX) {
1097 qcbp = (qcb_t *)malloc(sizeof(qcb_t), M_TEMP, M_NOWAIT);
1098 if (qcbp) {
1099 bzero(qcbp, sizeof(qcb_t));
1100 ida->num_qcbs++;
1101 qcbp->flags = QCB_ACTIVE;
1102 #ifdef IDADEBUG
1103 if (ida_debug & IDA_SHOWQCBS)
1104 printf("ida_get_qcb%d: qcb %d created\n",
1105 unit, ida->num_qcbs);
1106 #endif
1107 /* Put in the phystokv hash table. */
1108 /* Never gets taken out. */
1109 qcbp->paddr = vtophys(qcbp);
1110 hashnum = QCB_HASH(qcbp->paddr);
1111 qcbp->nexthash = ida->hashlist[hashnum];
1112 ida->hashlist[hashnum] = qcbp;
1113 } else {
1114 printf("ida%d: Can't malloc QCB\n", unit);
1115 } goto gottit;
1116 } else {
1117 /* reached maximum allocation of qcbs - sleep until one is freed */
1118 tsleep((caddr_t)&ida->freelist, PRIBIO, "idaqcb", 0);
1119 }
1120 } if (qcbp) {
1121 /* qet the qcb from from the (non-empty) free list */
1122 ida->freelist = qcbp->next;
1123 qcbp->flags = QCB_ACTIVE;
1124 }
1125 gottit:
1126 splx(opri);
1127
1128 #ifdef IDADEBUG
1129 if (ida_debug & IDA_SHOWQCBS)
1130 printf("ida_get_qcb%d: returns 0x%x\n", unit, qcbp);
1131 #endif
1132
1133 return (qcbp);
1134 }
1135
1136
1137 /* Return a qcb to the free list */
1138 static void
1139 ida_free_qcb(int unit, qcb_t *qcbp)
1140 {
1141 unsigned int opri = 0;
1142 struct ida_ctl *ida = idadata[unit];
1143
1144 #ifdef IDADEBUG
1145 if (ida_debug & IDA_SHOWQCBS)
1146 printf("ida_free_qcb%d: freeing 0x%x\n", unit, qcbp);
1147 #endif
1148
1149 opri = splbio();
1150
1151 qcbp->next = ida->freelist;
1152 ida->freelist = qcbp;
1153 qcbp->flags = QCB_FREE;
1154
1155 /* if the free list was empty, wakeup anyone sleeping */
1156
1157 if (!qcbp->next) {
1158 #ifdef IDADEBUG
1159 if (ida_debug & IDA_SHOWQCBS)
1160 printf("ida_free_qcb%d: about to wakeup 0x%x queue\n",
1161 unit, &ida->freelist);
1162 #endif
1163 wakeup((caddr_t)&ida->freelist);
1164 }
1165
1166 splx(opri);
1167 }
1168
1169 /* Find the ida_qcb having a given physical address */
1170 qcb_t *
1171 ida_qcb_phys_kv(ida, ida_qcb_phys)
1172 struct ida_ctl *ida;
1173 physaddr_t ida_qcb_phys;
1174 {
1175 int hash = QCB_HASH(ida_qcb_phys);
1176 qcb_t *qcbp = ida->hashlist[hash];
1177
1178 while (qcbp) {
1179 if (qcbp->paddr == ida_qcb_phys)
1180 break;
1181 qcbp = qcbp->nexthash;
1182 }
1183
1184 #ifdef IDADEBUG
1185 if (ida_debug & IDA_SHOWQCBS)
1186 printf("ida?: ida_qcb_phys_kv(0x%x) = 0x%x\n", ida_qcb_phys, qcbp);
1187 #endif
1188
1189 return qcbp;
1190 }
1191
1192 void
1193 ida_queue_buf(int unit, struct buf *bp)
1194 {
1195 struct ida_drv *drv = id_drive[unit];
1196 int cntlr = drv->ctl_unit;
1197 qcb_t *qcbp = ida_get_qcb(cntlr); /* may cause us to wait */
1198 struct ida_ctl *ida = idadata[cntlr];
1199 unsigned int datalen = bp->b_bcount;
1200 int thiskv = (int)bp->b_data;
1201 physaddr_t thisphys = vtophys(thiskv);
1202 int nsgb = 0; /* number of scatter/gather blocks used */
1203 struct ida_sgb *sg = &(qcbp->sglist[0]);
1204
1205 /* fill in the qcb command header */
1206
1207 if (PCI_CONTROLLER(ida)) {
1208 qcbp->hdr.priority = 0x00;
1209 qcbp->hdr.flags =
1210 (sizeof(struct ida_req) + sizeof(struct ida_sgb) * IDA_MAX_SGLEN) >> 2;
1211 } else {
1212 qcbp->hdr.priority = IDA_DEF_PRIORITY;
1213 qcbp->hdr.flags = 0x10;
1214 }
1215 qcbp->hdr.drive = drv->drv_unit; /* logical drive number */
1216 qcbp->buf = bp; /* the buf this command came from */
1217
1218 /* set up the scatter-gather list in the qcb */
1219
1220 while ((datalen) && (nsgb < IDA_MAX_SGLEN)) {
1221 int bytes_this_seg = 0;
1222 physaddr_t nextphys;
1223
1224 /* put in the base address */
1225 sg->addr = thisphys;
1226
1227 /* do it at least once */
1228 nextphys = thisphys;
1229 while ((datalen) && (thisphys == nextphys)) {
1230 int bytes_this_page;
1231
1232 /* This page is contiguous (physically) with the the last, */
1233 /* just extend the length */
1234
1235 /* how far to the end of the page ... */
1236 nextphys = (thisphys & (~(PAGESIZ - 1))) + PAGESIZ;
1237 bytes_this_page = nextphys - thisphys;
1238 /* ... or to the end of the data */
1239 bytes_this_page = min(bytes_this_page, datalen);
1240 bytes_this_seg += bytes_this_page;
1241 datalen -= bytes_this_page;
1242
1243 /* get ready for the next page */
1244 thiskv = (thiskv & (~(PAGESIZ - 1))) + PAGESIZ;
1245 if (datalen)
1246 thisphys = vtophys(thiskv);
1247 }
1248
1249 /* next page isn't contiguous, finish the seg */
1250 sg->len = bytes_this_seg;
1251 sg++;
1252 nsgb++;
1253 }
1254
1255 if (datalen) { /* still data => command block too small */
1256 printf("ida_queue_buf%d: more than %d scatter/gather blocks needed\n",
1257 cntlr, IDA_MAX_SGLEN);
1258 bp->b_error = EIO;
1259 bp->b_flags |= B_ERROR;
1260 biodone(bp);
1261 return;
1262 }
1263
1264 /* fill-in the I/O request block */
1265
1266 qcbp->req.error = 0;
1267 qcbp->req.next = 0;
1268 qcbp->req.blkno = bp->b_pblkno;
1269 qcbp->req.bcount = bp->b_bcount >> 9;
1270 qcbp->req.sgcount = nsgb;
1271 qcbp->req.command = (bp->b_flags & B_READ ? IDA_READ_DATA : IDA_WRITE_DATA);
1272
1273 #ifdef IDADEBUG
1274 if (ida_debug & IDA_SHOWQCBS) {
1275 printf("ida_rw%d: queuing:\n", cntlr);
1276 ida_print_qcb(qcbp);
1277 }
1278 #endif
1279
1280 /* queue for submission to the controller */
1281 ida_enqueue(cntlr, qcbp);
1282 }
1283
1284
1285 void
1286 ida_start(int cntlr)
1287 {
1288 struct ida_ctl *ida = idadata[cntlr];
1289 qcb_t *qcbp;
1290 int count = 0;
1291 int opri = splbio();
1292
1293 if (!ida->send_next) { /* check there is a job in the queue */
1294 splx(opri);
1295 return;
1296 }
1297
1298 if (PCI_CONTROLLER(ida)) {
1299 ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
1300 u_int fifo = reg->initiate_fifo;
1301 if (fifo == 1) {
1302 splx(opri);
1303 return; /* not sent - must try again later */
1304 }
1305
1306 /* submit upto 16 jobs at once into the initiate fifo */
1307 while (count < 16 && (fifo = reg->initiate_fifo) != 1
1308 && (qcbp = ida_dequeue(cntlr))) {
1309 reg->initiate_fifo = qcbp->paddr;
1310 qcbp->flags = QCB_SENT;
1311 ida->inside++;
1312 count++;
1313 }
1314 } else {
1315
1316 if (!IDA_CHAN_CLEAR(ida)) {
1317 IDA_ENABLE_CHAN(ida);
1318 splx(opri);
1319 return;
1320 }
1321
1322 qcbp = ida_dequeue(cntlr);
1323
1324 #ifdef IDADEBUG
1325 if (ida_debug & IDA_SHOWQCBS)
1326 printf("ida%d: ida_start: sending 0x%x\n", cntlr, qcbp);
1327 #endif
1328
1329 IDA_SET_EBELL_I(ida, 2);
1330 IDA_SET_SUB_ADDR(ida, qcbp->paddr); /* physical address of this qcb */
1331 IDA_SET_SUB_LEN(ida, sizeof(qcb_t));
1332 IDA_SET_LBELL_I(ida, 1);
1333
1334 qcbp->flags = QCB_SENT;
1335 ida->inside++;
1336 count++;
1337 }
1338
1339 if (ida->inside > ida->max_inside) {
1340 ida->max_inside = ida->inside; /* new maximum */
1341 splx(opri);
1342
1343 #ifdef IDADEBUG
1344 if (ida_debug & IDA_MAXQCBS)
1345 printf("ida%d: qcbs %d/%d\n", cntlr, ida->inside, ida->num_qcbs);
1346 #endif
1347 } else {
1348 splx(opri);
1349 }
1350
1351 #ifdef IDADEBUG
1352 if ((ida_debug & IDA_SHOWSUBS) && count > 1)
1353 printf("ida%d: %d jobs submitted (queue %s).\n",
1354 cntlr, count, ida->send_next ? "not emptied" : "emptied");
1355 #endif
1356 }
1357
1358 void
1359 ida_newqueue(int cntlr)
1360 {
1361 struct ida_ctl *ida = idadata[cntlr];
1362 ida->send_next = 0;
1363 ida->send_last = 0;
1364 }
1365
1366 qcb_t *
1367 ida_dequeue(int cntlr)
1368 {
1369 struct ida_ctl *ida = idadata[cntlr];
1370 qcb_t *qcbp = ida->send_next; /* who is next? */
1371
1372 if (qcbp) { /* queue is not empty */
1373 qcb_t* nextp = qcbp->next;
1374
1375 if (nextp) { /* more than one element in the queue */
1376 nextp->last = 0; /* we are the first */
1377 ida->send_next = nextp; /* hence first to go */
1378 } else { /* exactly one element in the queue */
1379 ida->send_last = ida->send_next = 0;
1380 }
1381 }
1382
1383 return qcbp;
1384 }
1385
1386 static void
1387 ida_enqueue(int cntlr, qcb_t *qcbp)
1388 {
1389 struct ida_ctl *ida = idadata[cntlr];
1390 qcb_t *lastp = ida->send_last; /* who is last? */
1391 int opri = splbio();
1392
1393 if (lastp) { /* if the queue is not empty */
1394 lastp->next = qcbp; /* then we go after the last */
1395 } else { /* if the queue was empty */
1396 ida->send_next = qcbp; /* then we go next */
1397 }
1398
1399 qcbp->last = lastp; /* we follow the last */
1400 qcbp->next = 0; /* and nothing follows us */
1401
1402 ida->send_last = qcbp; /* we go last */
1403 splx(opri);
1404 }
1405
1406 void
1407 idaintr(void *arg)
1408 {
1409 int cntlr = (int)arg;
1410 qcb_t *qcbp;
1411 struct ida_ctl *ida = idadata[cntlr];
1412 u_char status;
1413 physaddr_t paddr, paddr1; /* physical address of the qcb */
1414 int offset; /* qcb offset */
1415 u_char cstat; /* job status */
1416
1417 if (PCI_CONTROLLER(ida)) { /*pci:*/
1418 ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
1419 int status = reg->status;
1420 #ifdef IDADEBUG
1421 if (ida_debug & IDA_SHOWINTS)
1422 printf("ida%d: idaintr: status=%x (before complete)\n"
1423 , cntlr, status);
1424 #endif
1425 while (status & IDA_PCI_PENDING) {
1426 paddr1 = reg->complete_fifo;
1427 paddr = paddr1 & ~3;
1428 qcbp = ida_qcb_phys_kv(ida, paddr);
1429 #ifdef IDADEBUG
1430 if (ida_debug & IDA_SHOWQCBS) {
1431 printf("ida%d: idaintr: qcb(%x) completed\n", cntlr, qcbp);
1432 ida_print_qcb(qcbp);
1433 }
1434 #endif
1435 if (qcbp) {
1436 if (qcbp->req.error & 3) ida_soft_errors++;
1437 ida_done(cntlr, qcbp, (qcbp->req.error>>2) ? JOB_FAILURE : JOB_SUCCESS);
1438 } else {
1439 printf("ida%d: idaintr: completion (%x) ignored\n", cntlr, paddr1);
1440 }
1441 status = reg->status;
1442 }
1443 #ifdef IDADEBUG
1444 if (ida_debug & IDA_SHOWINTS)
1445 printf("ida%d: idaintr: status=%x (before initiate)\n"
1446 , cntlr, status);
1447 #endif
1448 if (status & IDA_PCI_READY) {
1449 ida_start(cntlr);
1450 }
1451 } else {
1452 while(1) {
1453 status = IDA_READ_EBELL_I(ida) & IDA_READ_EBELL_E(ida);
1454
1455 #ifdef IDADEBUG
1456 if (ida_debug & IDA_SHOWINTS)
1457 printf("ida%d: idaintr: status = 0x%x\n", cntlr, status);
1458 #endif
1459
1460 if ((status & (BMIC_DATA_READY | BMIC_CHAN_CLEAR)) == 0) break;
1461
1462 if (status & BMIC_DATA_READY) { /* data ready */
1463 int job_status;
1464
1465 if (IDA_READ_LBELL_I(ida) & JOB_ABORTED) {
1466 printf("ida%d: idaintr: status:%x local channel should be busy! ",
1467 cntlr, status);
1468 }
1469
1470 paddr = IDA_GET_COM_ADDR(ida);
1471 offset = IDA_GET_COM_OFFSET(ida);
1472 cstat = IDA_GET_COM_STATUS(ida);
1473
1474 /* acknowledge interrupt */
1475 IDA_ACK_CMD_COM(ida);
1476
1477 /* determine which job completed */
1478 qcbp = ida_qcb_phys_kv(ida, paddr);
1479
1480 /* analyse the job status code */
1481 if (cstat & IDA_COMPL_OK) {
1482 job_status = JOB_SUCCESS;
1483 } else {
1484 printf("ida%d: idaintr: return code %x=", cntlr, cstat);
1485 if (cstat & IDA_NON_FATAL) printf("recoverable error! ");
1486 if (cstat & IDA_FATAL) printf("fatal error! ");
1487 if (cstat & IDA_ABORTED) printf("aborted! ");
1488 if (cstat & IDA_INVAL_REQ) printf("invalid request block! ");
1489 if (cstat & IDA_INVAL_LIST) printf("cmd list error! ");
1490 if (cstat & IDA_AARGH_LIST) printf("really bad cmd list! ");
1491 job_status = JOB_FAILURE;
1492 }
1493
1494 #ifdef IDADEBUG
1495 if (ida_debug & IDA_SHOWQCBS) {
1496 printf("ida%d: idaintr: qcb(%x) returned.\n", cntlr, qcbp);
1497 ida_print_qcb(qcbp);
1498 }
1499 #endif
1500
1501 ida_done(cntlr, qcbp, job_status); /* retire the job */
1502 ida_start(cntlr); /* send the controller another job */
1503 }
1504
1505 if (status & BMIC_CHAN_CLEAR) {
1506 /* channel not clear */
1507 IDA_DISABLE_CHAN(ida);
1508 ida_start(cntlr); /* send the controller another job */
1509 }
1510 } /*eisa*/
1511 }
1512 }
1513
1514
1515 int
1516 ida_poll(cntlr, wait)
1517 int cntlr;
1518 int wait; /* delay in milliseconds */
1519 {
1520 struct ida_ctl *ctlp = idadata[cntlr];
1521
1522 if (PCI_CONTROLLER(ctlp)) {
1523 printf("ida%d: error: ida_poll called on a PCI controller\n", cntlr);
1524 return EIO;
1525 }
1526
1527 while (wait-- > 0) {
1528 if (IDA_DATA_READY(ctlp)) {
1529 ctlp->com_addr = IDA_GET_COM_ADDR(ctlp);
1530 ctlp->com_offset = IDA_GET_COM_OFFSET(ctlp);
1531 ctlp->com_status = IDA_GET_COM_STATUS(ctlp);
1532 IDA_ACK_CMD_COM(ctlp);
1533
1534 if (0) printf("ida_poll: addr=0x%08x off=0x%04x cmdstatus=0x%02x\n",
1535 (u_int)ctlp->com_addr,
1536 ctlp->com_offset,
1537 ctlp->com_status);
1538
1539 return 0;
1540 }
1541 DELAY(1000);
1542 }
1543
1544 printf("ida%d: board not responding\n", cntlr);
1545 return EIO;
1546 }
1547
1548
1549 int
1550 ida_submit(int cntlr, qcb_t *qcbp, int size)
1551 {
1552 struct ida_ctl *ida = idadata[cntlr];
1553 int s = splbio();
1554
1555 if (PCI_CONTROLLER(ida)) {
1556 ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
1557 u_int fifo = reg->initiate_fifo;
1558 if (fifo == 1) {
1559 splx(s);
1560 #ifdef IDADEBUG
1561 if (ida_debug & IDA_SHOWSUBS)
1562 printf("ida%d: ida_submit(%x): fifo=1 not submitting\n",
1563 cntlr, qcbp, fifo);
1564 #endif
1565 return(1); /* not sent - must try again later */
1566 }
1567 #ifdef IDADEBUG
1568 if (ida_debug & IDA_SHOWSUBS)
1569 printf("ida%d: ida_submit(%x): fifo=%d submitting\n", cntlr, qcbp, fifo);
1570 #endif
1571 reg->initiate_fifo = qcbp->paddr;
1572
1573 } else {
1574 if (!IDA_CHAN_CLEAR(ida)) {
1575 IDA_ENABLE_CHAN(ida);
1576 splx(s);
1577 return(1); /* not sent - must try again later */
1578 }
1579
1580 IDA_SET_EBELL_I(ida, 2);
1581 IDA_SET_SUB_ADDR(ida, qcbp->paddr); /* physical address of this qcb */
1582 IDA_SET_SUB_LEN(ida, size);
1583 IDA_SET_LBELL_I(ida, 1);
1584 }
1585
1586 splx(s);
1587 return(0); /* sent */
1588 }
1589
1590 static
1591 void
1592 ida_empty_pci_complete_fifo(int cntlr, ida_pci_reg_t *reg) {
1593 u_long paddr;
1594 if (paddr = reg->complete_fifo) {
1595 int count = 200;
1596 while (paddr && count > 0) {
1597 printf("ida%d: command completion discarded (0x%x).\n",
1598 cntlr, (u_int)paddr);
1599 if (paddr = reg->complete_fifo) {
1600 DELAY(100);
1601 count--;
1602 }
1603 }
1604 }
1605 return;
1606 }
1607
1608 static
1609 u_long
1610 ida_complete_pci_command(int cntlr, ida_pci_reg_t *reg) {
1611 int count = 1;
1612 u_long paddr;
1613 while (count < 1000000) {
1614 if (reg->status & IDA_PCI_PENDING) {
1615 if ((paddr = reg->complete_fifo) == 0)
1616 printf("ida%d: ida_complete_pci_command: zero address returned.\n",
1617 cntlr);
1618 else
1619 return paddr;
1620 }
1621 DELAY(10);
1622 }
1623 return 1;
1624 }
1625
1626 static
1627 int
1628 ida_submit_wait(int cntlr, qcb_t *qcbp, int size)
1629 {
1630 struct ida_ctl *ida = idadata[cntlr];
1631
1632 if (PCI_CONTROLLER(ida)) {
1633 ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
1634 int i, count = 1000000;
1635 u_long paddr;
1636 ida_empty_pci_complete_fifo(cntlr, reg);
1637 reg->interrupt = IDA_PCI_DISABLE_INTS;
1638 while (count > 0 && (i = reg->initiate_fifo) > 16) {
1639 DELAY(10);
1640 count--;
1641 }
1642 if (count == 0) {
1643 printf("ida%d: ida_pci_submit_wait: fifo failed to clear - controller has failed.\n", cntlr);
1644 return 1;
1645 }
1646 reg->initiate_fifo = qcbp->paddr;
1647 paddr = ida_complete_pci_command(cntlr, reg);
1648 if (paddr == 1) {
1649 printf("ida%d: ida_pci_submit_wait timeout. No command list returned.\n",
1650 cntlr);
1651 return 1;
1652 }
1653 if (paddr != qcbp->paddr) {
1654 printf("ida%d: ida_pci_submit_wait error. Invalid command list returned.\n",
1655 cntlr);
1656 return 1;
1657 }
1658 if (qcbp->req.error != 0xfe && qcbp->req.error == 0x40) {
1659 printf("ida%d: ida_pci_submit_wait: Job error.\n", cntlr);
1660 return 1;
1661 }
1662 } else {
1663 if (ida_submit(cntlr, qcbp, size)) {
1664 return 1;
1665 }
1666 if (ida_poll(cntlr, 10)) {
1667 return 1;
1668 }
1669 }
1670
1671 return 0; /* sent */
1672 }
1673
1674
1675 void
1676 ida_done(int cntlr, qcb_t *qcbp, int state)
1677 {
1678 struct buf *bp = qcbp->buf;
1679
1680 if (idadata[cntlr] > 0)
1681 idadata[cntlr]->inside--; /* one less job inside the controller */
1682
1683 if (state != JOB_SUCCESS) {
1684 #ifdef IDADEBUG
1685 if (ida_debug & IDA_SHOWMISC)
1686 printf("ida%d: ida_done: job failed 0x%x\n", cntlr, state);
1687 #endif
1688 /* we had a problem */
1689 bp->b_error = EIO;
1690 bp->b_flags |= B_ERROR;
1691 } else {
1692 struct ida_drv *drv = id_drive[dkunit(bp->b_dev)];
1693 bp->b_resid = 0;
1694 /* Update device stats */
1695 devstat_end_transaction(&drv->dk_stats,
1696 bp->b_bcount - bp->b_resid,
1697 DEVSTAT_TAG_NONE,
1698 (bp->b_flags & B_READ) ? DEVSTAT_READ : DEVSTAT_WRITE);
1699 }
1700
1701 ida_free_qcb(cntlr, qcbp);
1702 biodone(bp);
1703 }
1704
1705
1706 int
1707 idsize(dev_t dev)
1708 {
1709 int unit = dkunit(dev);
1710 struct ida_drv *drv;
1711
1712 if (unit >= NID)
1713 return (-1);
1714
1715 drv = id_drive[unit];
1716 if (!drv || !(drv->flags & ID_INIT))
1717 return (-1);
1718
1719 return (dssize(dev, &drv->slices, idopen, idclose));
1720 }
1721
1722 /*
1723 * dump all of physical memory into the partition specified, starting
1724 * at offset 'dumplo' into the partition.
1725 */
1726 int
1727 iddump(dev_t dev)
1728 { /* dump core after a system crash */
1729 return 0; /* XXX */
1730 }
1731
1732 static id_devsw_installed = 0;
1733
1734 static void
1735 id_drvinit(void *unused)
1736 {
1737 if( ! id_devsw_installed ) {
1738 cdevsw_add_generic(ID_BDMAJ,ID_CDMAJ, &id_cdevsw);
1739 id_devsw_installed = 1;
1740 }
1741 }
1742
1743 SYSINIT(iddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+ID_CDMAJ,id_drvinit,NULL)
1744
1745 #ifdef IDADEBUG
1746 void
1747 ida_print_qcb(qcb_t *qcbp)
1748 {
1749 int i;
1750 printf("qcb(%x): drive=%x priority=%x flags=%x sgcount=%d\n"
1751 ,qcbp
1752 ,qcbp->hdr.drive
1753 ,qcbp->hdr.priority
1754 ,qcbp->hdr.flags
1755 ,qcbp->req.sgcount);
1756 printf("qcb(%x): next=%x command=%x error=%x blkno=%x bcount=%x\n"
1757 ,qcbp
1758 ,qcbp->req.next
1759 ,qcbp->req.command
1760 ,qcbp->req.error
1761 ,qcbp->req.blkno
1762 ,qcbp->req.bcount);
1763 for (i=0; i < qcbp->req.sgcount; i++)
1764 printf("qcb(%x): %x len=%x addr=%x\n"
1765 ,qcbp
1766 ,i
1767 ,qcbp->sglist[i].len
1768 ,qcbp->sglist[i].addr);
1769 }
1770
1771 void
1772 ida_print_active_qcb(int cntlr)
1773 {
1774 struct ida_ctl *ida = idadata[cntlr];
1775 int i;
1776
1777 for (i=0; i < QCB_HASH_SIZE; i++) {
1778 qcb_t *qcbp = ida->hashlist[i];
1779 while (qcbp) {
1780 if (qcbp->flags != QCB_FREE) {
1781 ida_print_qcb(qcbp);
1782 }
1783 qcbp = qcbp->nexthash;
1784 }
1785 }
1786 }
1787 #endif /*IDADEBUG */
1788
Cache object: 39a99f7f03151629f3512572feb8d71a
|