xref: /minix/minix/drivers/storage/at_wini/at_wini.c (revision e3b78ef1)
1 /* This file contains the device dependent part of a driver for the IBM-AT
2  * winchester controller.  Written by Adri Koppes.
3  *
4  * Changes:
5  *   Oct  2, 2013   drop non-PCI support; one controller per instance  (David)
6  *   Aug 19, 2005   ATA PCI support, supports SATA  (Ben Gras)
7  *   Nov 18, 2004   moved AT disk driver to user-space  (Jorrit N. Herder)
8  *   Aug 20, 2004   watchdogs replaced by sync alarms  (Jorrit N. Herder)
9  *   Mar 23, 2000   added ATAPI CDROM support  (Michael Temari)
10  *   May 14, 2000   d-d/i rewrite  (Kees J. Bot)
11  *   Apr 13, 1992   device dependent/independent split  (Kees J. Bot)
12  */
13 
14 #include "at_wini.h"
15 
16 #include <minix/sysutil.h>
17 #include <minix/type.h>
18 #include <minix/endpoint.h>
19 #include <sys/ioc_disk.h>
20 #include <machine/pci.h>
21 #include <sys/mman.h>
22 
23 /* Variables. */
24 
25 /* Common command block */
26 struct command {
27   u8_t	precomp;	/* REG_PRECOMP, etc. */
28   u8_t	count;
29   u8_t	sector;
30   u8_t	cyl_lo;
31   u8_t	cyl_hi;
32   u8_t	ldh;
33   u8_t	command;
34 
35   /* The following at for LBA48 */
36   u8_t	count_prev;
37   u8_t	sector_prev;
38   u8_t	cyl_lo_prev;
39   u8_t	cyl_hi_prev;
40 };
41 
42 /* Timeouts and max retries. */
43 static int timeout_usecs = DEF_TIMEOUT_USECS;
44 static int max_errors = MAX_ERRORS;
45 static long w_standard_timeouts = 0;
46 static long w_pci_debug = 0;
47 static long w_instance = 0;
48 static long disable_dma = 0;
49 static long atapi_debug = 0;
50 static long w_identify_wakeup_ticks;
51 static long wakeup_ticks;
52 static long w_atapi_dma;
53 
54 static int w_testing = 0;
55 static int w_silent = 0;
56 
57 static u32_t system_hz;
58 
59 /* The struct wini is indexed by drive (0-3). */
60 static struct wini {		/* main drive struct, one entry per drive */
61   unsigned state;		/* drive state: deaf, initialized, dead */
62   unsigned short w_status;	/* device status register */
63   unsigned base_cmd;		/* command base register */
64   unsigned base_ctl;		/* control base register */
65   unsigned base_dma;		/* dma base register */
66   unsigned char native;		/* if set, drive is native (not compat.) */
67   unsigned char lba48;		/* if set, drive supports lba48 */
68   unsigned char dma;		/* if set, drive supports dma */
69   unsigned char dma_intseen;	/* if set, drive has seen an interrupt */
70   int irq_hook_id;		/* id of irq hook at the kernel */
71   unsigned cylinders;		/* physical number of cylinders */
72   unsigned heads;		/* physical number of heads */
73   unsigned sectors;		/* physical number of sectors per track */
74   unsigned ldhpref;		/* top four bytes of the LDH (head) register */
75   unsigned max_count;		/* max request for this drive */
76   unsigned open_ct;		/* in-use count */
77   struct device part[DEV_PER_DRIVE];	/* disks and partitions */
78   struct device subpart[SUB_PER_DRIVE];	/* subpartitions */
79 } wini[MAX_DRIVES], *w_wn;
80 
81 static int w_device = -1;
82 
83 int w_command;			/* current command in execution */
84 static int w_drive;			/* selected drive */
85 static struct device *w_dv;		/* device's base and size */
86 
87 static u8_t *tmp_buf;
88 
89 #define ATA_DMA_SECTORS	64
90 #define ATA_DMA_BUF_SIZE	(ATA_DMA_SECTORS*SECTOR_SIZE)
91 
92 static char *dma_buf;
93 static phys_bytes dma_buf_phys;
94 
95 #define N_PRDTE	1024	/* Should be enough for large requests */
96 
97 struct prdte
98 {
99 	phys_bytes prdte_base;
100 	u16_t prdte_count;
101 	u8_t prdte_reserved;
102 	u8_t prdte_flags;
103 };
104 
105 #define PRDT_BYTES (sizeof(struct prdte) * N_PRDTE)
106 static struct prdte *prdt;
107 static phys_bytes prdt_phys;
108 
109 #define PRDTE_FL_EOT	0x80	/* End of table */
110 
111 static int w_probe(int skip, u16_t *vidp, u16_t *didp);
112 static void w_init(int devind, u16_t vid, u16_t did);
113 static int init_params(void);
114 static int w_do_open(devminor_t minor, int access);
115 static struct device *w_prepare(devminor_t dev);
116 static struct device *w_part(devminor_t minor);
117 static int w_identify(void);
118 static char *w_name(void);
119 static int w_specify(void);
120 static int w_io_test(void);
121 static ssize_t w_transfer(devminor_t minor, int do_write, u64_t position,
122 	endpoint_t proc_nr, iovec_t *iov, unsigned int nr_req, int flags);
123 static int com_out(struct command *cmd);
124 static int com_out_ext(struct command *cmd);
125 static int setup_dma(unsigned *sizep, endpoint_t proc_nr, iovec_t *iov,
126 	size_t addr_offset, int do_write);
127 static void w_need_reset(void);
128 static int w_do_close(devminor_t minor);
129 static int w_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
130 	cp_grant_id_t grant, endpoint_t user_endpt);
131 static void w_hw_int(unsigned int irqs);
132 static int com_simple(struct command *cmd);
133 static void w_timeout(void);
134 static int w_reset(void);
135 static void w_intr_wait(void);
136 static int at_intr_wait(void);
137 static int w_waitfor(int mask, int value);
138 static int w_waitfor_dma(unsigned int mask, unsigned int value);
139 static void w_geometry(devminor_t minor, struct part_geom *entry);
140 static int atapi_sendpacket(u8_t *packet, unsigned cnt, int do_dma);
141 static int atapi_intr_wait(int dma, size_t max);
142 static int atapi_open(void);
143 static void atapi_close(void);
144 static int atapi_transfer(int do_write, u64_t position, endpoint_t
145 	endpt, iovec_t *iov, unsigned int nr_req);
146 
147 /* Entry points to this driver. */
148 static struct blockdriver w_dtab = {
149   .bdr_type	= BLOCKDRIVER_TYPE_DISK,	/* handle partition requests */
150   .bdr_open	= w_do_open,	/* open or mount request, initialize device */
151   .bdr_close	= w_do_close,	/* release device */
152   .bdr_transfer	= w_transfer,	/* do the I/O */
153   .bdr_ioctl	= w_ioctl,	/* I/O control requests */
154   .bdr_part	= w_part,	/* return partition information */
155   .bdr_geometry	= w_geometry,	/* tell the geometry of the disk */
156   .bdr_intr	= w_hw_int,	/* leftover hardware interrupts */
157 };
158 
159 /* SEF functions and variables. */
160 static void sef_local_startup(void);
161 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
162 
163 /*===========================================================================*
164  *				at_winchester_task			     *
165  *===========================================================================*/
166 int main(int argc, char *argv[])
167 {
168   /* SEF local startup. */
169   env_setargs(argc, argv);
170   sef_local_startup();
171 
172   /* Call the generic receive loop. */
173   blockdriver_task(&w_dtab);
174 
175   return(OK);
176 }
177 
178 /*===========================================================================*
179  *			       sef_local_startup			     *
180  *===========================================================================*/
181 static void sef_local_startup(void)
182 {
183   /* Register init callbacks. */
184   sef_setcb_init_fresh(sef_cb_init_fresh);
185   sef_setcb_init_lu(sef_cb_init_fresh);
186 
187   /* Register live update callbacks. */
188   sef_setcb_lu_prepare(sef_cb_lu_prepare);
189   sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
190   sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
191 
192   /* Let SEF perform startup. */
193   sef_startup();
194 }
195 
196 /*===========================================================================*
197  *		            sef_cb_init_fresh                                *
198  *===========================================================================*/
199 static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
200 {
201 /* Initialize the at_wini driver. */
202   int skip, devind;
203   u16_t vid, did;
204 
205   system_hz = sys_hz();
206 
207   if (!(tmp_buf = alloc_contig(2*DMA_BUF_SIZE, AC_ALIGN4K, NULL)))
208 	panic("unable to allocate temporary buffer");
209 
210   w_identify_wakeup_ticks = WAKEUP_TICKS;
211   wakeup_ticks = WAKEUP_TICKS;
212 
213   /* Set special disk parameters. */
214   skip = init_params();
215 
216   /* Find the PCI device to use. If none found, terminate immediately. */
217   devind = w_probe(skip, &vid, &did);
218   if (devind < 0) {
219 	/* For now, complain only if even the first at_wini instance cannot
220 	 * find a device. There may be only one IDE controller after all,
221 	 * but if there are none, the system should probably be booted with
222 	 * another driver, and that's something the user might want to know.
223 	 */
224 	if (w_instance == 0)
225 		panic("no matching device found");
226 	return ENODEV;	/* the actual error code doesn't matter */
227   }
228 
229   /* Initialize the device. */
230   w_init(devind, vid, did);
231 
232   /* Announce we are up! */
233   blockdriver_announce(type);
234 
235   return(OK);
236 }
237 
238 /*===========================================================================*
239  *				init_params				     *
240  *===========================================================================*/
241 static int init_params(void)
242 {
243 /* This routine is called at startup to initialize the drive parameters. */
244   int drive;
245   long wakeup_secs = WAKEUP_SECS;
246 
247   /* Boot variables. */
248   env_parse("instance", "d", 0, &w_instance, 0, 8);
249   env_parse("ata_std_timeout", "d", 0, &w_standard_timeouts, 0, 1);
250   env_parse("ata_pci_debug", "d", 0, &w_pci_debug, 0, 1);
251   env_parse(NO_DMA_VAR, "d", 0, &disable_dma, 0, 1);
252   env_parse("ata_id_timeout", "d", 0, &wakeup_secs, 1, 60);
253   env_parse("atapi_debug", "d", 0, &atapi_debug, 0, 1);
254   env_parse("atapi_dma", "d", 0, &w_atapi_dma, 0, 1);
255 
256   w_identify_wakeup_ticks = wakeup_secs * system_hz;
257 
258   if(atapi_debug)
259 	panic("atapi_debug");
260 
261   if(w_identify_wakeup_ticks <= 0) {
262 	printf("changing wakeup from %ld to %d ticks.\n",
263 		w_identify_wakeup_ticks, WAKEUP_TICKS);
264 	w_identify_wakeup_ticks = WAKEUP_TICKS;
265   }
266 
267   if (disable_dma) {
268 	printf("at_wini%ld: DMA for ATA devices is disabled.\n", w_instance);
269   } else {
270 	/* Ask for anonymous memory for DMA, that is physically contiguous. */
271 	dma_buf = alloc_contig(ATA_DMA_BUF_SIZE, 0, &dma_buf_phys);
272 	prdt = alloc_contig(PRDT_BYTES, 0, &prdt_phys);
273 	if(!dma_buf || !prdt) {
274 		disable_dma = 1;
275 		printf("at_wini%ld: no dma\n", w_instance);
276 	}
277   }
278 
279   for (drive = 0; drive < MAX_DRIVES; drive++)
280 	wini[drive].state = IGNORING;
281 
282   return (int) w_instance;
283 }
284 
285 /*===========================================================================*
286  *				init_drive				     *
287  *===========================================================================*/
288 static void init_drive(int drive, int base_cmd, int base_ctl, int base_dma,
289 	int native, int hook)
290 {
291   struct wini *w;
292 
293   w = &wini[drive];
294 
295   w->state = 0;
296   w->w_status = 0;
297   w->base_cmd = base_cmd;
298   w->base_ctl = base_ctl;
299   w->base_dma = base_dma;
300   if (w_pci_debug)
301 	printf("at_wini%ld: drive %d: base_cmd 0x%x, base_ctl 0x%x, "
302 		"base_dma 0x%x\n", w_instance, drive, w->base_cmd, w->base_ctl,
303 		w->base_dma);
304   w->native = native;
305   w->irq_hook_id = hook;
306   w->ldhpref = ldh_init(drive);
307   w->max_count = MAX_SECS << SECTOR_SHIFT;
308   w->lba48 = 0;
309   w->dma = 0;
310 }
311 
312 /*===========================================================================*
313  *				w_probe					     *
314  *===========================================================================*/
315 static int w_probe(int skip, u16_t *vidp, u16_t *didp)
316 {
317 /* Go through the PCI devices that have been made visible to us, skipping as
318  * many as requested and then reserving the first one after that. We assume
319  * that all visible devices are in fact devices we can handle.
320  */
321   int r, devind;
322 
323   pci_init();
324 
325   r = pci_first_dev(&devind, vidp, didp);
326   if (r <= 0)
327 	return -1;
328 
329   while (skip--) {
330 	r = pci_next_dev(&devind, vidp, didp);
331 	if (r <= 0)
332 		return -1;
333   }
334 
335   pci_reserve(devind);
336 
337   return devind;
338 }
339 
340 /*===========================================================================*
341  *				w_init					     *
342  *===========================================================================*/
343 static void w_init(int devind, u16_t vid, u16_t did)
344 {
345 /* Initialize drives on the controller that we found and reserved. Each
346  * controller has two channels, each of which may have up to two disks
347  * attached, so the maximum number of disks per controller is always four.
348  * In this function, we always initialize the slots for all four disks; later,
349  * during normal operation, we determine whether the disks are actually there.
350  * For pure IDE devices (as opposed to e.g. RAID devices), each of the two
351  * channels on the controller may be in native or compatibility mode. The PCI
352  * interface field tells us which channel is in which mode. For native
353  * channels, we get the IRQ and the channel's base control and command
354  * addresses from the PCI slot, and we manually acknowledge interrupts. For
355  * compatibility channels, we use the hardcoded legacy IRQs and addresses, and
356  * enable automatic IRQ reenabling. In both cases, we get the base DMA address
357  * from the PCI slot if it is there.
358  */
359   int r, irq, native_hook, compat_hook, is_ide, nhooks;
360   u8_t bcr, scr, interface;
361   u16_t cr;
362   u32_t base_cmd, base_ctl, base_dma;
363 
364   bcr= pci_attr_r8(devind, PCI_BCR);
365   scr= pci_attr_r8(devind, PCI_SCR);
366   interface= pci_attr_r8(devind, PCI_PIFR);
367 
368   is_ide = (bcr == PCI_BCR_MASS_STORAGE && scr == PCI_MS_IDE);
369 
370   irq = pci_attr_r8(devind, PCI_ILR);
371   base_dma = pci_attr_r32(devind, PCI_BAR_5) & PCI_BAR_IO_MASK;
372 
373   nhooks = 0;	/* we don't care about notify IDs, but they must be unique */
374 
375   /* Any native drives? Then register their native IRQ first. */
376   if (!is_ide || (interface & (ATA_IF_NATIVE0 | ATA_IF_NATIVE1))) {
377 	native_hook = nhooks++;
378 	if ((r = sys_irqsetpolicy(irq, 0, &native_hook)) != OK)
379 		panic("couldn't set native IRQ policy %d: %d", irq, r);
380 	if ((r = sys_irqenable(&native_hook)) != OK)
381 		panic("couldn't enable native IRQ line %d: %d", irq, r);
382   }
383 
384   /* Add drives on the primary channel. */
385   if (!is_ide || (interface & ATA_IF_NATIVE0)) {
386 	base_cmd = pci_attr_r32(devind, PCI_BAR) & PCI_BAR_IO_MASK;
387 	base_ctl = pci_attr_r32(devind, PCI_BAR_2) & PCI_BAR_IO_MASK;
388 
389 	init_drive(0, base_cmd, base_ctl+PCI_CTL_OFF, base_dma, TRUE,
390 		native_hook);
391 	init_drive(1, base_cmd, base_ctl+PCI_CTL_OFF, base_dma, TRUE,
392 		native_hook);
393 
394 	if (w_pci_debug)
395 		printf("at_wini%ld: native 0 on %d: 0x%x 0x%x irq %d\n",
396 			w_instance, devind, base_cmd, base_ctl, irq);
397   } else {
398 	/* Register first compatibility IRQ. */
399 	compat_hook = nhooks++;
400 	if ((r = sys_irqsetpolicy(AT_WINI_0_IRQ, IRQ_REENABLE,
401 		&compat_hook)) != OK)
402 		panic("couldn't set compat(0) IRQ policy: %d", r);
403 	if ((r = sys_irqenable(&compat_hook)) != OK)
404 		panic("couldn't enable compat(0) IRQ line: %d", r);
405 
406 	init_drive(0, REG_CMD_BASE0, REG_CTL_BASE0, base_dma, FALSE,
407 		compat_hook);
408 	init_drive(1, REG_CMD_BASE0, REG_CTL_BASE0, base_dma, FALSE,
409 		compat_hook);
410 
411 	if (w_pci_debug)
412 		printf("at_wini%ld: compat 0 on %d\n", w_instance, devind);
413   }
414 
415   /* Add drives on the secondary channel. */
416   if (base_dma != 0)
417 	base_dma += PCI_DMA_2ND_OFF;
418   if (!is_ide || (interface & ATA_IF_NATIVE1)) {
419 	base_cmd = pci_attr_r32(devind, PCI_BAR_3) & PCI_BAR_IO_MASK;
420 	base_ctl = pci_attr_r32(devind, PCI_BAR_4) & PCI_BAR_IO_MASK;
421 	init_drive(2, base_cmd, base_ctl+PCI_CTL_OFF, base_dma, TRUE,
422 		native_hook);
423 	init_drive(3, base_cmd, base_ctl+PCI_CTL_OFF, base_dma, TRUE,
424 		native_hook);
425 	if (w_pci_debug)
426 		printf("at_wini%ld: native 1 on %d: 0x%x 0x%x irq %d\n",
427 			w_instance, devind, base_cmd, base_ctl, irq);
428   } else {
429 	/* Register secondary compatibility IRQ. */
430 	compat_hook = nhooks++;
431 	if ((r = sys_irqsetpolicy(AT_WINI_1_IRQ, IRQ_REENABLE,
432 		&compat_hook)) != OK)
433 		panic("couldn't set compat(1) IRQ policy: %d", r);
434 	if ((r = sys_irqenable(&compat_hook)) != OK)
435 		panic("couldn't enable compat(1) IRQ line: %d", r);
436 
437 	init_drive(2, REG_CMD_BASE1, REG_CTL_BASE1, base_dma, FALSE,
438 		compat_hook);
439 	init_drive(3, REG_CMD_BASE1, REG_CTL_BASE1, base_dma, FALSE,
440 		compat_hook);
441 
442 	if (w_pci_debug)
443 		printf("at_wini%ld: compat 1 on %d\n", w_instance, devind);
444   }
445 
446   /* Enable busmastering if necessary. */
447   cr = pci_attr_r16(devind, PCI_CR);
448   if (!(cr & PCI_CR_MAST_EN))
449 	pci_attr_w16(devind, PCI_CR, cr | PCI_CR_MAST_EN);
450 }
451 
452 /*===========================================================================*
453  *				w_do_open				     *
454  *===========================================================================*/
455 static int w_do_open(devminor_t minor, int access)
456 {
457 /* Device open: Initialize the controller and read the partition table. */
458 
459   struct wini *wn;
460 
461   if (w_prepare(minor) == NULL) return(ENXIO);
462 
463   wn = w_wn;
464 
465   /* If we've probed it before and it failed, don't probe it again. */
466   if (wn->state & IGNORING) return ENXIO;
467 
468   /* If we haven't identified it yet, or it's gone deaf,
469    * (re-)identify it.
470    */
471   if (!(wn->state & IDENTIFIED) || (wn->state & DEAF)) {
472 	/* Try to identify the device. */
473 	if (w_identify() != OK) {
474 #if VERBOSE
475 		printf("%s: identification failed\n", w_name());
476 #endif
477 		if (wn->state & DEAF){
478 			int err = w_reset();
479 			if( err != OK ){
480 				return err;
481 			}
482 		}
483 		wn->state = IGNORING;
484 		return(ENXIO);
485 	}
486 	  /* Do a test transaction unless it's a CD drive (then
487 	   * we can believe the controller, and a test may fail
488 	   * due to no CD being in the drive). If it fails, ignore
489 	   * the device forever.
490 	   */
491 	  if (!(wn->state & ATAPI) && w_io_test() != OK) {
492   		wn->state |= IGNORING;
493 	  	return(ENXIO);
494 	  }
495   }
496 
497    if ((wn->state & ATAPI) && (access & BDEV_W_BIT))
498 	return(EACCES);
499 
500   /* Partition the drive if it's being opened for the first time,
501    * or being opened after being closed.
502    */
503   if (wn->open_ct == 0) {
504 	if (wn->state & ATAPI) {
505 		int r;
506 		if ((r = atapi_open()) != OK) return(r);
507 	}
508 
509 	/* Partition the disk. */
510 	partition(&w_dtab, w_drive * DEV_PER_DRIVE, P_PRIMARY,
511 		wn->state & ATAPI);
512   }
513   wn->open_ct++;
514   return(OK);
515 }
516 
517 /*===========================================================================*
518  *				w_prepare				     *
519  *===========================================================================*/
520 static struct device *w_prepare(devminor_t device)
521 {
522   /* Prepare for I/O on a device. */
523   w_device = (int) device;
524 
525   if (device >= 0 && device < NR_MINORS) {	/* d0, d0p[0-3], d1, ... */
526 	w_drive = device / DEV_PER_DRIVE;	/* save drive number */
527 	if (w_drive >= MAX_DRIVES) return(NULL);
528 	w_wn = &wini[w_drive];
529 	w_dv = &w_wn->part[device % DEV_PER_DRIVE];
530   } else
531   if ((unsigned) (device -= MINOR_d0p0s0) < NR_SUBDEVS) {/*d[0-7]p[0-3]s[0-3]*/
532 	w_drive = device / SUB_PER_DRIVE;
533 	if (w_drive >= MAX_DRIVES) return(NULL);
534 	w_wn = &wini[w_drive];
535 	w_dv = &w_wn->subpart[device % SUB_PER_DRIVE];
536   } else {
537   	w_device = -1;
538 	return(NULL);
539   }
540   return(w_dv);
541 }
542 
543 /*===========================================================================*
544  *				w_part					     *
545  *===========================================================================*/
546 static struct device *w_part(devminor_t device)
547 {
548 /* Return a pointer to the partition information of the given minor device. */
549 
550   return w_prepare(device);
551 }
552 
553 #define id_byte(n)	(&tmp_buf[2 * (n)])
554 #define id_word(n)	(((u16_t) id_byte(n)[0] <<  0) \
555 			|((u16_t) id_byte(n)[1] <<  8))
556 #define id_longword(n)	(((u32_t) id_byte(n)[0] <<  0) \
557 			|((u32_t) id_byte(n)[1] <<  8) \
558 			|((u32_t) id_byte(n)[2] << 16) \
559 			|((u32_t) id_byte(n)[3] << 24))
560 
561 /*===========================================================================*
562  *				check_dma				     *
563  *===========================================================================*/
564 static void
565 check_dma(struct wini *wn)
566 {
567 	u32_t dma_status, dma_base;
568 	int id_dma, ultra_dma;
569 	u16_t w;
570 
571 	wn->dma= 0;
572 
573 	if (disable_dma)
574 		return;
575 
576 	w= id_word(ID_CAPABILITIES);
577 	id_dma= !!(w & ID_CAP_DMA);
578 	w= id_byte(ID_FIELD_VALIDITY)[0];
579 	ultra_dma= !!(w & ID_FV_88);
580 	dma_base= wn->base_dma;
581 
582 	if (dma_base) {
583 		if (sys_inb(dma_base + DMA_STATUS, &dma_status) != OK) {
584 			panic("unable to read DMA status register");
585 		}
586 	}
587 
588 	if (id_dma && dma_base) {
589 		w= id_word(ID_MULTIWORD_DMA);
590 		if (w_pci_debug &&
591 		(w & (ID_MWDMA_2_SUP|ID_MWDMA_1_SUP|ID_MWDMA_0_SUP))) {
592 			printf(
593 			"%s: multiword DMA modes supported:%s%s%s\n",
594 				w_name(),
595 				(w & ID_MWDMA_0_SUP) ? " 0" : "",
596 				(w & ID_MWDMA_1_SUP) ? " 1" : "",
597 				(w & ID_MWDMA_2_SUP) ? " 2" : "");
598 		}
599 		if (w_pci_debug &&
600 		(w & (ID_MWDMA_0_SEL|ID_MWDMA_1_SEL|ID_MWDMA_2_SEL))) {
601 			printf(
602 			"%s: multiword DMA mode selected:%s%s%s\n",
603 				w_name(),
604 				(w & ID_MWDMA_0_SEL) ? " 0" : "",
605 				(w & ID_MWDMA_1_SEL) ? " 1" : "",
606 				(w & ID_MWDMA_2_SEL) ? " 2" : "");
607 		}
608 		if (w_pci_debug && ultra_dma) {
609 			w= id_word(ID_ULTRA_DMA);
610 			if (w & (ID_UDMA_0_SUP|ID_UDMA_1_SUP|
611 				ID_UDMA_2_SUP|ID_UDMA_3_SUP|
612 				ID_UDMA_4_SUP|ID_UDMA_5_SUP)) {
613 				printf(
614 			"%s: Ultra DMA modes supported:%s%s%s%s%s%s\n",
615 				w_name(),
616 				(w & ID_UDMA_0_SUP) ? " 0" : "",
617 				(w & ID_UDMA_1_SUP) ? " 1" : "",
618 				(w & ID_UDMA_2_SUP) ? " 2" : "",
619 				(w & ID_UDMA_3_SUP) ? " 3" : "",
620 				(w & ID_UDMA_4_SUP) ? " 4" : "",
621 				(w & ID_UDMA_5_SUP) ? " 5" : "");
622 			}
623 			if (w & (ID_UDMA_0_SEL|ID_UDMA_1_SEL|
624 				ID_UDMA_2_SEL|ID_UDMA_3_SEL|
625 				ID_UDMA_4_SEL|ID_UDMA_5_SEL)) {
626 				printf(
627 			"%s: Ultra DMA mode selected:%s%s%s%s%s%s\n",
628 				w_name(),
629 				(w & ID_UDMA_0_SEL) ? " 0" : "",
630 				(w & ID_UDMA_1_SEL) ? " 1" : "",
631 				(w & ID_UDMA_2_SEL) ? " 2" : "",
632 				(w & ID_UDMA_3_SEL) ? " 3" : "",
633 				(w & ID_UDMA_4_SEL) ? " 4" : "",
634 				(w & ID_UDMA_5_SEL) ? " 5" : "");
635 			}
636 		}
637 		wn->dma= 1;
638 	} else if (id_dma || dma_base) {
639 		printf("id_dma %d, dma_base 0x%x\n", id_dma, dma_base);
640 	} else
641 		printf("no DMA support\n");
642 }
643 
644 /*===========================================================================*
645  *				w_identify				     *
646  *===========================================================================*/
647 static int w_identify(void)
648 {
649 /* Find out if a device exists, if it is an old AT disk, or a newer ATA
650  * drive, a removable media device, etc.
651  */
652 
653   struct wini *wn = w_wn;
654   struct command cmd;
655   int s;
656   u16_t w;
657   unsigned long size;
658   int prev_wakeup;
659   int r;
660 
661   /* Try to identify the device. */
662   cmd.ldh     = wn->ldhpref;
663   cmd.command = ATA_IDENTIFY;
664 
665   /* In testing mode, a drive will get ignored at the first timeout. */
666   w_testing = 1;
667 
668   /* Execute *_IDENTIFY with configured *_IDENTIFY timeout. */
669   prev_wakeup = wakeup_ticks;
670   wakeup_ticks = w_identify_wakeup_ticks;
671   r = com_simple(&cmd);
672 
673   if (r == OK && w_waitfor(STATUS_DRQ, STATUS_DRQ) &&
674 	!(wn->w_status & (STATUS_ERR|STATUS_WF))) {
675 
676 	/* Device information. */
677 	if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
678 		panic("Call to sys_insw() failed: %d", s);
679 
680 	/* This is an ATA device. */
681 	wn->state |= SMART;
682 
683 	/* Preferred CHS translation mode. */
684 	wn->cylinders = id_word(1);
685 	wn->heads = id_word(3);
686 	wn->sectors = id_word(6);
687 	size = (u32_t) wn->cylinders * wn->heads * wn->sectors;
688 
689 	w= id_word(ID_CAPABILITIES);
690 	if ((w & ID_CAP_LBA) && size > 512L*1024*2) {
691 		/* Drive is LBA capable and is big enough to trust it to
692 		 * not make a mess of it.
693 		 */
694 		wn->ldhpref |= LDH_LBA;
695 		size = id_longword(60);
696 
697 		w= id_word(ID_CSS);
698 		if (size < LBA48_CHECK_SIZE)
699 		{
700 			/* No need to check for LBA48 */
701 		}
702 		else if (w & ID_CSS_LBA48) {
703 			/* Drive is LBA48 capable (and LBA48 is turned on). */
704 			if (id_longword(102)) {
705 				/* If no. of sectors doesn't fit in 32 bits,
706 				 * trunacte to this. So it's LBA32 for now.
707 				 * This can still address devices up to 2TB
708 				 * though.
709 				 */
710 				size = ULONG_MAX;
711 			} else {
712 				/* Actual number of sectors fits in 32 bits. */
713 				size = id_longword(100);
714 			}
715 			wn->lba48 = 1;
716 		}
717 
718 		check_dma(wn);
719 	}
720   } else if (cmd.command = ATAPI_IDENTIFY,
721 	com_simple(&cmd) == OK && w_waitfor(STATUS_DRQ, STATUS_DRQ) &&
722 	!(wn->w_status & (STATUS_ERR|STATUS_WF))) {
723 	/* An ATAPI device. */
724 	wn->state |= ATAPI;
725 
726 	/* Device information. */
727 	if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, 512)) != OK)
728 		panic("Call to sys_insw() failed: %d", s);
729 
730 	size = 0;	/* Size set later. */
731 	check_dma(wn);
732   } else {
733 	/* Not an ATA device; no translations, no special features.  Don't
734 	 * touch it.
735 	 */
736 	wakeup_ticks = prev_wakeup;
737 	w_testing = 0;
738 	return(ERR);
739   }
740 
741   /* Restore wakeup_ticks and unset testing mode. */
742   wakeup_ticks = prev_wakeup;
743   w_testing = 0;
744 
745   /* Size of the whole drive */
746   wn->part[0].dv_size = (u64_t)size * SECTOR_SIZE;
747 
748   /* Reset/calibrate (where necessary) */
749   if (w_specify() != OK && w_specify() != OK) {
750   	return(ERR);
751   }
752 
753   wn->state |= IDENTIFIED;
754   return(OK);
755 }
756 
757 /*===========================================================================*
758  *				w_name					     *
759  *===========================================================================*/
760 static char *w_name(void)
761 {
762 /* Return a name for the current device. */
763   static char name[] = "AT0-D0";
764 
765   name[2] = '0' + w_instance;
766   name[5] = '0' + w_drive;
767   return name;
768 }
769 
770 /*===========================================================================*
771  *				w_io_test				     *
772  *===========================================================================*/
773 static int w_io_test(void)
774 {
775 	int save_dev;
776 	int save_timeout, save_errors, save_wakeup;
777 	iovec_t iov;
778 	static char *buf;
779 	ssize_t r;
780 
781 #define BUFSIZE CD_SECTOR_SIZE
782 	STATICINIT(buf, BUFSIZE);
783 
784 	iov.iov_addr = (vir_bytes) buf;
785 	iov.iov_size = BUFSIZE;
786 	save_dev = w_device;
787 
788 	/* Reduce timeout values for this test transaction. */
789 	save_timeout = timeout_usecs;
790 	save_errors = max_errors;
791 	save_wakeup = wakeup_ticks;
792 
793 	if (!w_standard_timeouts) {
794 		timeout_usecs = 4000000;
795 		wakeup_ticks = system_hz * 6;
796 		max_errors = 3;
797 	}
798 
799 	w_testing = 1;
800 
801 	/* Try I/O on the actual drive (not any (sub)partition). */
802 	r = w_transfer(w_drive * DEV_PER_DRIVE, FALSE /*do_write*/, 0,
803 		SELF, &iov, 1, BDEV_NOFLAGS);
804 
805 	/* Switch back. */
806  	if (w_prepare(save_dev) == NULL)
807  		panic("Couldn't switch back devices");
808 
809  	/* Restore parameters. */
810 	timeout_usecs = save_timeout;
811 	max_errors = save_errors;
812 	wakeup_ticks = save_wakeup;
813 	w_testing = 0;
814 
815  	/* Test if everything worked. */
816 	if (r != BUFSIZE) {
817 		return ERR;
818 	}
819 
820 	/* Everything worked. */
821 	return OK;
822 }
823 
824 /*===========================================================================*
825  *				w_specify				     *
826  *===========================================================================*/
827 static int w_specify(void)
828 {
829 /* Routine to initialize the drive after boot or when a reset is needed. */
830 
831   struct wini *wn = w_wn;
832   struct command cmd;
833 
834   if ((wn->state & DEAF) && w_reset() != OK) {
835   	return(ERR);
836   }
837 
838   if (!(wn->state & ATAPI)) {
839 	/* Specify parameters: precompensation, number of heads and sectors. */
840 	cmd.precomp = 0;
841 	cmd.count   = wn->sectors;
842 	cmd.ldh     = w_wn->ldhpref | (wn->heads - 1);
843 	cmd.command = CMD_SPECIFY;		/* Specify some parameters */
844 
845 	/* Output command block and see if controller accepts the parameters. */
846 	if (com_simple(&cmd) != OK) return(ERR);
847 
848 	if (!(wn->state & SMART)) {
849 		/* Calibrate an old disk. */
850 		cmd.sector  = 0;
851 		cmd.cyl_lo  = 0;
852 		cmd.cyl_hi  = 0;
853 		cmd.ldh     = w_wn->ldhpref;
854 		cmd.command = CMD_RECALIBRATE;
855 
856 		if (com_simple(&cmd) != OK) return(ERR);
857 	}
858   }
859   wn->state |= INITIALIZED;
860   return(OK);
861 }
862 
863 /*===========================================================================*
864  *				do_transfer				     *
865  *===========================================================================*/
866 static int do_transfer(const struct wini *wn, unsigned int count,
867 	unsigned int sector, unsigned int do_write, int do_dma)
868 {
869   	struct command cmd;
870 	unsigned int sector_high;
871 	unsigned secspcyl = wn->heads * wn->sectors;
872 	int do_lba48;
873 
874 	sector_high= 0;	/* For future extensions */
875 
876 	do_lba48= 0;
877 	if (sector >= LBA48_CHECK_SIZE || sector_high != 0)
878 	{
879 		if (wn->lba48)
880 			do_lba48= 1;
881 		else if (sector > LBA_MAX_SIZE || sector_high != 0)
882 		{
883 			/* Strange sector count for LBA device */
884 			return EIO;
885 		}
886 	}
887 
888 	cmd.precomp = 0;
889 	cmd.count   = count;
890 	if (do_dma)
891 	{
892 		cmd.command = do_write ? CMD_WRITE_DMA : CMD_READ_DMA;
893 	}
894 	else
895 		cmd.command = do_write ? CMD_WRITE : CMD_READ;
896 
897 	if (do_lba48) {
898 		if (do_dma)
899 		{
900 			cmd.command = (do_write ?
901 				CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT);
902 		}
903 		else
904 		{
905 			cmd.command = (do_write ?
906 				CMD_WRITE_EXT : CMD_READ_EXT);
907 		}
908 		cmd.count_prev= (count >> 8);
909 		cmd.sector  = (sector >>  0) & 0xFF;
910 		cmd.cyl_lo  = (sector >>  8) & 0xFF;
911 		cmd.cyl_hi  = (sector >> 16) & 0xFF;
912 		cmd.sector_prev= (sector >> 24) & 0xFF;
913 		cmd.cyl_lo_prev= (sector_high) & 0xFF;
914 		cmd.cyl_hi_prev= (sector_high >> 8) & 0xFF;
915 		cmd.ldh     = wn->ldhpref;
916 
917 		return com_out_ext(&cmd);
918 	} else if (wn->ldhpref & LDH_LBA) {
919 		cmd.sector  = (sector >>  0) & 0xFF;
920 		cmd.cyl_lo  = (sector >>  8) & 0xFF;
921 		cmd.cyl_hi  = (sector >> 16) & 0xFF;
922 		cmd.ldh     = wn->ldhpref | ((sector >> 24) & 0xF);
923 	} else {
924   		int cylinder, head, sec;
925 		cylinder = sector / secspcyl;
926 		head = (sector % secspcyl) / wn->sectors;
927 		sec = sector % wn->sectors;
928 		cmd.sector  = sec + 1;
929 		cmd.cyl_lo  = cylinder & BYTE;
930 		cmd.cyl_hi  = (cylinder >> 8) & BYTE;
931 		cmd.ldh     = wn->ldhpref | head;
932 	}
933 
934 	return com_out(&cmd);
935 }
936 
937 static void stop_dma(const struct wini *wn)
938 {
939 	int r;
940 
941 	/* Stop bus master operation */
942 	r= sys_outb(wn->base_dma + DMA_COMMAND, 0);
943 	if (r != 0) panic("stop_dma: sys_outb failed: %d", r);
944 }
945 
946 static void start_dma(const struct wini *wn, int do_write)
947 {
948 	u32_t v;
949 	int r;
950 
951 	/* Assume disk reads. Start DMA */
952 	v= DMA_CMD_START;
953 	if (!do_write)
954 	{
955 		/* Disk reads generate PCI write cycles. */
956 		v |= DMA_CMD_WRITE;
957 	}
958 	r= sys_outb(wn->base_dma + DMA_COMMAND, v);
959 	if (r != 0) panic("start_dma: sys_outb failed: %d", r);
960 }
961 
962 static int error_dma(const struct wini *wn)
963 {
964 	int r;
965 	u32_t v;
966 
967 #define DMAERR(msg) \
968 	printf("at_wini%ld: bad DMA: %s. Disabling DMA for drive %d.\n",	\
969 		w_instance, msg, wn - wini);				\
970 	printf("at_wini%ld: workaround: set %s=1 in boot monitor.\n", \
971 		w_instance, NO_DMA_VAR); \
972 	return 1;	\
973 
974 	r= sys_inb(wn->base_dma + DMA_STATUS, &v);
975 	if (r != 0) panic("w_transfer: sys_inb failed: %d", r);
976 
977 	if (!wn->dma_intseen) {
978 		/* DMA did not complete successfully */
979 		if (v & DMA_ST_BM_ACTIVE) {
980 			DMAERR("DMA did not complete");
981 		} else if (v & DMA_ST_ERROR) {
982 			DMAERR("DMA error");
983 		} else {
984 			DMAERR("DMA buffer too small");
985 		}
986 	} else if ((v & DMA_ST_BM_ACTIVE)) {
987 		DMAERR("DMA buffer too large");
988 	}
989 
990 	return 0;
991 }
992 
993 
994 /*===========================================================================*
995  *				w_transfer				     *
996  *===========================================================================*/
997 static ssize_t w_transfer(
998   devminor_t minor,		/* minor device to perform the transfer on */
999   int do_write,			/* read or write? */
1000   u64_t position,		/* offset on device to read or write */
1001   endpoint_t proc_nr,		/* process doing the request */
1002   iovec_t *iov,			/* pointer to read or write request vector */
1003   unsigned int nr_req,		/* length of request vector */
1004   int UNUSED(flags)		/* transfer flags */
1005 )
1006 {
1007   struct wini *wn;
1008   iovec_t *iop, *iov_end = iov + nr_req;
1009   int r, s, errors, do_dma;
1010   unsigned long block;
1011   u32_t w_status;
1012   u64_t dv_size;
1013   unsigned int n, nbytes;
1014   unsigned dma_buf_offset;
1015   ssize_t total = 0;
1016   size_t addr_offset = 0;
1017 
1018   if (w_prepare(minor) == NULL) return(ENXIO);
1019 
1020   wn = w_wn;
1021   dv_size = w_dv->dv_size;
1022 
1023   if (w_wn->state & ATAPI) {
1024 	return atapi_transfer(do_write, position, proc_nr, iov, nr_req);
1025   }
1026 
1027   /* Check disk address. */
1028   if ((unsigned)(position % SECTOR_SIZE) != 0) return(EINVAL);
1029 
1030   errors = 0;
1031 
1032   while (nr_req > 0) {
1033 	/* How many bytes to transfer? */
1034 	nbytes = 0;
1035 	for (iop = iov; iop < iov_end; iop++) nbytes += iop->iov_size;
1036 	if ((nbytes & SECTOR_MASK) != 0) return(EINVAL);
1037 
1038 	/* Which block on disk and how close to EOF? */
1039 	if (position >= dv_size) return(total);	/* At EOF */
1040 	if (position + nbytes > dv_size)
1041 		nbytes = (unsigned)(dv_size - position);
1042 	block = (unsigned long)((w_dv->dv_base + position) / SECTOR_SIZE);
1043 
1044 	do_dma= wn->dma;
1045 
1046 	if (nbytes >= wn->max_count) {
1047 		/* The drive can't do more then max_count at once. */
1048 		nbytes = wn->max_count;
1049 	}
1050 
1051 	/* First check to see if a reinitialization is needed. */
1052 	if (!(wn->state & INITIALIZED) && w_specify() != OK) return(EIO);
1053 
1054 	if (do_dma) {
1055 		stop_dma(wn);
1056 		if (!setup_dma(&nbytes, proc_nr, iov, addr_offset, do_write)) {
1057 			do_dma = 0;
1058 		}
1059 #if 0
1060 		printf("nbytes = %d\n", nbytes);
1061 #endif
1062 	}
1063 
1064 	/* Tell the controller to transfer nbytes bytes. */
1065 	r = do_transfer(wn, (nbytes >> SECTOR_SHIFT), block, do_write, do_dma);
1066 
1067 	if (do_dma)
1068 		start_dma(wn, do_write);
1069 
1070 	if (do_write) {
1071 		/* The specs call for a 400 ns wait after issuing the command.
1072 		 * Reading the alternate status register is the suggested
1073 		 * way to implement this wait.
1074 		 */
1075 		if (sys_inb((wn->base_ctl+REG_CTL_ALTSTAT), &w_status) != OK)
1076 			panic("couldn't get status");
1077 	}
1078 
1079 	if (do_dma) {
1080 		/* Wait for the interrupt, check DMA status and optionally
1081 		 * copy out.
1082 		 */
1083 
1084 		wn->dma_intseen = 0;
1085 		if ((r = at_intr_wait()) != OK)
1086 		{
1087 			/* Don't retry if sector marked bad or too many
1088 			 * errors.
1089 			 */
1090 			if (r == ERR_BAD_SECTOR || ++errors == max_errors) {
1091 				w_command = CMD_IDLE;
1092 				return(EIO);
1093 			}
1094 			continue;
1095 		}
1096 
1097 		/* Wait for DMA_ST_INT to get set */
1098 		if (!wn->dma_intseen) {
1099 			if(w_waitfor_dma(DMA_ST_INT, DMA_ST_INT))
1100 				wn->dma_intseen = 1;
1101 		}
1102 
1103 		if (error_dma(wn)) {
1104 			wn->dma = 0;
1105 			continue;
1106 		}
1107 
1108 		stop_dma(wn);
1109 
1110 		dma_buf_offset= 0;
1111 		while (r == OK && nbytes > 0)
1112 		{
1113 			n= iov->iov_size;
1114 			if (n > nbytes)
1115 				n= nbytes;
1116 
1117 			/* Book the bytes successfully transferred. */
1118 			nbytes -= n;
1119 			position= position + n;
1120 			total += n;
1121 			addr_offset += n;
1122 			if ((iov->iov_size -= n) == 0) {
1123 				iov++; nr_req--; addr_offset = 0;
1124 			}
1125 			dma_buf_offset += n;
1126 		}
1127 	}
1128 
1129 	while (r == OK && nbytes > 0) {
1130 		/* For each sector, wait for an interrupt and fetch the data
1131 		 * (read), or supply data to the controller and wait for an
1132 		 * interrupt (write).
1133 		 */
1134 
1135 		if (!do_write) {
1136 			/* First an interrupt, then data. */
1137 			if ((r = at_intr_wait()) != OK) {
1138 				/* An error, send data to the bit bucket. */
1139 				if (w_wn->w_status & STATUS_DRQ) {
1140 					if ((s=sys_insw(wn->base_cmd+REG_DATA,
1141 						SELF, tmp_buf,
1142 						SECTOR_SIZE)) != OK) {
1143 						panic("Call to sys_insw() failed: %d", s);
1144 					}
1145 				}
1146 				break;
1147 			}
1148 		}
1149 
1150 		/* Wait for busy to clear. */
1151 		if (!w_waitfor(STATUS_BSY, 0)) { r = ERR; break; }
1152 
1153 		/* Wait for data transfer requested. */
1154 		if (!w_waitfor(STATUS_DRQ, STATUS_DRQ)) { r = ERR; break; }
1155 
1156 		/* Copy bytes to or from the device's buffer. */
1157 		if (!do_write) {
1158 		   if(proc_nr != SELF) {
1159 			s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr,
1160 				(void *) (iov->iov_addr), addr_offset,
1161 					SECTOR_SIZE);
1162 		   } else {
1163 			s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
1164 				(void *) (iov->iov_addr + addr_offset),
1165 					SECTOR_SIZE);
1166 		   }
1167 		   if(s != OK) {
1168 			panic("Call to sys_insw() failed: %d", s);
1169 		   }
1170 		} else {
1171 		   if(proc_nr != SELF) {
1172 			s=sys_safe_outsw(wn->base_cmd + REG_DATA, proc_nr,
1173 				(void *) (iov->iov_addr), addr_offset,
1174 				SECTOR_SIZE);
1175 		   } else {
1176 			s=sys_outsw(wn->base_cmd + REG_DATA, proc_nr,
1177 				(void *) (iov->iov_addr + addr_offset),
1178 				SECTOR_SIZE);
1179 		   }
1180 
1181 		   if(s != OK) {
1182 		  	panic("Call to sys_outsw() failed: %d", s);
1183 		   }
1184 
1185 		   /* Data sent, wait for an interrupt. */
1186 		   if ((r = at_intr_wait()) != OK) break;
1187 		}
1188 
1189 		/* Book the bytes successfully transferred. */
1190 		nbytes -= SECTOR_SIZE;
1191 		position = position + SECTOR_SIZE;
1192 		addr_offset += SECTOR_SIZE;
1193 		total += SECTOR_SIZE;
1194 		if ((iov->iov_size -= SECTOR_SIZE) == 0) {
1195 			iov++;
1196 			nr_req--;
1197 			addr_offset = 0;
1198 		}
1199 	}
1200 
1201 	/* Any errors? */
1202 	if (r != OK) {
1203 		/* Don't retry if sector marked bad or too many errors. */
1204 		if (r == ERR_BAD_SECTOR || ++errors == max_errors) {
1205 			w_command = CMD_IDLE;
1206 			return(EIO);
1207 		}
1208 	}
1209   }
1210 
1211   w_command = CMD_IDLE;
1212   return(total);
1213 }
1214 
1215 /*===========================================================================*
1216  *				com_out					     *
1217  *===========================================================================*/
1218 static int com_out(cmd)
1219 struct command *cmd;		/* Command block */
1220 {
1221 /* Output the command block to the winchester controller and return status */
1222 
1223   struct wini *wn = w_wn;
1224   unsigned base_cmd = wn->base_cmd;
1225   unsigned base_ctl = wn->base_ctl;
1226   pvb_pair_t outbyte[7];		/* vector for sys_voutb() */
1227   int s;				/* status for sys_(v)outb() */
1228 
1229   if (w_wn->state & IGNORING) return ERR;
1230 
1231   if (!w_waitfor(STATUS_BSY, 0)) {
1232 	printf("%s: controller not ready\n", w_name());
1233 	return(ERR);
1234   }
1235 
1236   /* Select drive. */
1237   if ((s=sys_outb(base_cmd + REG_LDH, cmd->ldh)) != OK)
1238   	panic("Couldn't write register to select drive: %d", s);
1239 
1240   if (!w_waitfor(STATUS_BSY, 0)) {
1241 	printf("%s: com_out: drive not ready\n", w_name());
1242 	return(ERR);
1243   }
1244 
1245   /* Schedule a wakeup call, some controllers are flaky. This is done with a
1246    * synchronous alarm. If a timeout occurs a notify from CLOCK is sent, so that
1247    * w_intr_wait() can call w_timeout() in case the controller was not able to
1248    * execute the command. Leftover timeouts are simply ignored by the main loop.
1249    */
1250   sys_setalarm(wakeup_ticks, 0);
1251 
1252   wn->w_status = STATUS_ADMBSY;
1253   w_command = cmd->command;
1254   pv_set(outbyte[0], base_ctl + REG_CTL, wn->heads >= 8 ? CTL_EIGHTHEADS : 0);
1255   pv_set(outbyte[1], base_cmd + REG_PRECOMP, cmd->precomp);
1256   pv_set(outbyte[2], base_cmd + REG_COUNT, cmd->count);
1257   pv_set(outbyte[3], base_cmd + REG_SECTOR, cmd->sector);
1258   pv_set(outbyte[4], base_cmd + REG_CYL_LO, cmd->cyl_lo);
1259   pv_set(outbyte[5], base_cmd + REG_CYL_HI, cmd->cyl_hi);
1260   pv_set(outbyte[6], base_cmd + REG_COMMAND, cmd->command);
1261   if ((s=sys_voutb(outbyte,7)) != OK)
1262   	panic("Couldn't write registers with sys_voutb(): %d", s);
1263   return(OK);
1264 }
1265 
1266 /*===========================================================================*
1267  *				com_out_ext				     *
1268  *===========================================================================*/
1269 static int com_out_ext(cmd)
1270 struct command *cmd;		/* Command block */
1271 {
1272 /* Output the command block to the winchester controller and return status */
1273 
1274   struct wini *wn = w_wn;
1275   unsigned base_cmd = wn->base_cmd;
1276   unsigned base_ctl = wn->base_ctl;
1277   pvb_pair_t outbyte[11];		/* vector for sys_voutb() */
1278   int s;				/* status for sys_(v)outb() */
1279 
1280   if (w_wn->state & IGNORING) return ERR;
1281 
1282   if (!w_waitfor(STATUS_BSY, 0)) {
1283 	printf("%s: controller not ready\n", w_name());
1284 	return(ERR);
1285   }
1286 
1287   /* Select drive. */
1288   if ((s=sys_outb(base_cmd + REG_LDH, cmd->ldh)) != OK)
1289   	panic("Couldn't write register to select drive: %d", s);
1290 
1291   if (!w_waitfor(STATUS_BSY, 0)) {
1292 	printf("%s: com_out: drive not ready\n", w_name());
1293 	return(ERR);
1294   }
1295 
1296   /* Schedule a wakeup call, some controllers are flaky. This is done with a
1297    * synchronous alarm. If a timeout occurs a notify from CLOCK is sent, so that
1298    * w_intr_wait() can call w_timeout() in case the controller was not able to
1299    * execute the command. Leftover timeouts are simply ignored by the main loop.
1300    */
1301   sys_setalarm(wakeup_ticks, 0);
1302 
1303   wn->w_status = STATUS_ADMBSY;
1304   w_command = cmd->command;
1305   pv_set(outbyte[0], base_ctl + REG_CTL, 0);
1306   pv_set(outbyte[1], base_cmd + REG_COUNT, cmd->count_prev);
1307   pv_set(outbyte[2], base_cmd + REG_SECTOR, cmd->sector_prev);
1308   pv_set(outbyte[3], base_cmd + REG_CYL_LO, cmd->cyl_lo_prev);
1309   pv_set(outbyte[4], base_cmd + REG_CYL_HI, cmd->cyl_hi_prev);
1310   pv_set(outbyte[5], base_cmd + REG_COUNT, cmd->count);
1311   pv_set(outbyte[6], base_cmd + REG_SECTOR, cmd->sector);
1312   pv_set(outbyte[7], base_cmd + REG_CYL_LO, cmd->cyl_lo);
1313   pv_set(outbyte[8], base_cmd + REG_CYL_HI, cmd->cyl_hi);
1314   pv_set(outbyte[9], base_cmd + REG_COMMAND, cmd->command);
1315   if ((s=sys_voutb(outbyte, 10)) != OK)
1316   	panic("Couldn't write registers with sys_voutb(): %d", s);
1317 
1318   return(OK);
1319 }
1320 /*===========================================================================*
1321  *				setup_dma				     *
1322  *===========================================================================*/
1323 static int setup_dma(
1324   unsigned *sizep,
1325   endpoint_t proc_nr,
1326   iovec_t *iov,
1327   size_t addr_offset,
1328   int UNUSED(do_write)
1329 )
1330 {
1331 	phys_bytes user_phys;
1332 	unsigned n, offset, size;
1333 	int i, j, r;
1334 	u32_t v;
1335 	struct wini *wn = w_wn;
1336 
1337 	/* First try direct scatter/gather to the supplied buffers */
1338 	size= *sizep;
1339 	i= 0;	/* iov index */
1340 	j= 0;	/* prdt index */
1341 	offset= 0;	/* Offset in current iov */
1342 
1343 #if VERBOSE_DMA
1344 	printf("at_wini: setup_dma: proc_nr %d\n", proc_nr);
1345 #endif
1346 
1347 	while (size > 0)
1348 	{
1349 #if VERBOSE_DMA
1350 		printf(
1351 	"at_wini: setup_dma: iov[%d]: addr 0x%lx, size %ld offset %d, size %d\n",
1352 			i, iov[i].iov_addr, iov[i].iov_size, offset, size);
1353 #endif
1354 
1355 		n= iov[i].iov_size-offset;
1356 		if (n > size)
1357 			n= size;
1358 		if (n == 0 || (n & 1))
1359 			panic("bad size in iov: 0x%lx", iov[i].iov_size);
1360 		if(proc_nr != SELF) {
1361 			r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,
1362 				&user_phys);
1363 			if (r != 0)
1364 				panic("can't map user buffer (VM_GRANT): %d", r);
1365 			user_phys += offset + addr_offset;
1366 		} else {
1367 			r= sys_umap(proc_nr, VM_D,
1368 				iov[i].iov_addr+offset+addr_offset, n,
1369 				&user_phys);
1370 			if (r != 0)
1371 				panic("can't map user buffer (VM_D): %d", r);
1372 		}
1373 		if (user_phys & 1)
1374 		{
1375 			/* Buffer is not aligned */
1376 			printf("setup_dma: user buffer is not aligned\n");
1377 			return 0;
1378 		}
1379 
1380 		/* vector is not allowed to cross a 64K boundary */
1381 		if (user_phys/0x10000 != (user_phys+n-1)/0x10000)
1382 			n= ((user_phys/0x10000)+1)*0x10000 - user_phys;
1383 
1384 		/* vector is not allowed to be bigger than 64K, but we get that
1385 		 * for free.
1386 		 */
1387 
1388 		if (j >= N_PRDTE)
1389 		{
1390 			/* Too many entries */
1391 			printf("setup_dma: user buffer has too many entries\n");
1392 			return 0;
1393 		}
1394 
1395 		prdt[j].prdte_base= user_phys;
1396 		prdt[j].prdte_count= n;
1397 		prdt[j].prdte_reserved= 0;
1398 		prdt[j].prdte_flags= 0;
1399 		j++;
1400 
1401 		offset += n;
1402 		if (offset >= iov[i].iov_size)
1403 		{
1404 			i++;
1405 			offset= 0;
1406 			addr_offset= 0;
1407 		}
1408 
1409 		size -= n;
1410 	}
1411 
1412 	if (j <= 0 || j > N_PRDTE)
1413 		panic("bad prdt index: %d", j);
1414 	prdt[j-1].prdte_flags |= PRDTE_FL_EOT;
1415 
1416 #if VERBOSE_DMA
1417 	printf("dma not bad\n");
1418 	for (i= 0; i<j; i++) {
1419 		printf("prdt[%d]: base 0x%lx, size %d, flags 0x%x\n",
1420 			i, prdt[i].prdte_base, prdt[i].prdte_count,
1421 			prdt[i].prdte_flags);
1422 	}
1423 #endif
1424 
1425 	/* Verify that the bus master is not active */
1426 	r= sys_inb(wn->base_dma + DMA_STATUS, &v);
1427 	if (r != 0) panic("setup_dma: sys_inb failed: %d", r);
1428 	if (v & DMA_ST_BM_ACTIVE)
1429 		panic("Bus master IDE active");
1430 
1431 	if (prdt_phys & 3)
1432 		panic("prdt not aligned: 0x%lx", prdt_phys);
1433 	r= sys_outl(wn->base_dma + DMA_PRDTP, prdt_phys);
1434 	if (r != 0) panic("setup_dma: sys_outl failed: %d", r);
1435 
1436 	/* Clear interrupt and error flags */
1437 	r= sys_outb(wn->base_dma + DMA_STATUS, DMA_ST_INT | DMA_ST_ERROR);
1438 	if (r != 0) panic("setup_dma: sys_outb failed: %d", r);
1439 
1440 	return 1;
1441 }
1442 
1443 
1444 /*===========================================================================*
1445  *				w_need_reset				     *
1446  *===========================================================================*/
1447 static void w_need_reset(void)
1448 {
1449 /* The controller needs to be reset. */
1450   struct wini *wn;
1451 
1452   for (wn = wini; wn < &wini[MAX_DRIVES]; wn++) {
1453 	if (wn->base_cmd == w_wn->base_cmd) {
1454 		wn->state |= DEAF;
1455 		wn->state &= ~INITIALIZED;
1456 	}
1457   }
1458 }
1459 
1460 /*===========================================================================*
1461  *				w_do_close				     *
1462  *===========================================================================*/
1463 static int w_do_close(devminor_t minor)
1464 {
1465 /* Device close: Release a device. */
1466   if (w_prepare(minor) == NULL)
1467   	return(ENXIO);
1468   w_wn->open_ct--;
1469   if (w_wn->open_ct == 0 && (w_wn->state & ATAPI)) atapi_close();
1470   return(OK);
1471 }
1472 
1473 /*===========================================================================*
1474  *				com_simple				     *
1475  *===========================================================================*/
1476 static int com_simple(cmd)
1477 struct command *cmd;		/* Command block */
1478 {
1479 /* A simple controller command, only one interrupt and no data-out phase. */
1480   int r;
1481 
1482   if (w_wn->state & IGNORING) return ERR;
1483 
1484   if ((r = com_out(cmd)) == OK) r = at_intr_wait();
1485   w_command = CMD_IDLE;
1486   return(r);
1487 }
1488 
1489 /*===========================================================================*
1490  *				w_timeout				     *
1491  *===========================================================================*/
1492 static void w_timeout(void)
1493 {
1494   struct wini *wn = w_wn;
1495 
1496   switch (w_command) {
1497   case CMD_IDLE:
1498 	break;		/* fine */
1499   case CMD_READ:
1500   case CMD_READ_EXT:
1501   case CMD_WRITE:
1502   case CMD_WRITE_EXT:
1503 	/* Impossible, but not on PC's:  The controller does not respond. */
1504 
1505 	/* Limiting multisector I/O seems to help. */
1506 	if (wn->max_count > 8 * SECTOR_SIZE) {
1507 		wn->max_count = 8 * SECTOR_SIZE;
1508 	} else {
1509 		wn->max_count = SECTOR_SIZE;
1510 	}
1511 	/*FALL THROUGH*/
1512   default:
1513 	/* Some other command. */
1514 	if (w_testing)  wn->state |= IGNORING;	/* Kick out this drive. */
1515 	else if (!w_silent) printf("%s: timeout on command 0x%02x\n",
1516 		w_name(), w_command);
1517 	w_need_reset();
1518 	wn->w_status = 0;
1519   }
1520 }
1521 
1522 /*===========================================================================*
1523  *				w_reset					     *
1524  *===========================================================================*/
1525 static int w_reset(void)
1526 {
1527 /* Issue a reset to the controller.  This is done after any catastrophe,
1528  * like the controller refusing to respond.
1529  */
1530   int s;
1531   struct wini *wn = w_wn;
1532 
1533   /* Don't bother if this drive is forgotten. */
1534   if (w_wn->state & IGNORING) return ERR;
1535 
1536   /* Wait for any internal drive recovery. */
1537   tickdelay(RECOVERY_TICKS);
1538 
1539   /* Strobe reset bit */
1540   if ((s=sys_outb(wn->base_ctl + REG_CTL, CTL_RESET)) != OK)
1541   	panic("Couldn't strobe reset bit: %d", s);
1542   tickdelay(DELAY_TICKS);
1543   if ((s=sys_outb(wn->base_ctl + REG_CTL, 0)) != OK)
1544   	panic("Couldn't strobe reset bit: %d", s);
1545   tickdelay(DELAY_TICKS);
1546 
1547   /* Wait for controller ready */
1548   if (!w_waitfor(STATUS_BSY, 0)) {
1549 	printf("%s: reset failed, drive busy\n", w_name());
1550 	return(ERR);
1551   }
1552 
1553   /* The error register should be checked now, but some drives mess it up. */
1554 
1555   for (wn = wini; wn < &wini[MAX_DRIVES]; wn++) {
1556 	if (wn->base_cmd == w_wn->base_cmd) {
1557 		wn->state &= ~DEAF;
1558 		if (w_wn->native) {
1559 		    	/* Make sure irq is actually enabled.. */
1560 	  		sys_irqenable(&w_wn->irq_hook_id);
1561 		}
1562 	}
1563   }
1564 
1565   return(OK);
1566 }
1567 
1568 /*===========================================================================*
1569  *				w_intr_wait				     *
1570  *===========================================================================*/
1571 static void w_intr_wait(void)
1572 {
1573 /* Wait for a task completion interrupt. */
1574 
1575   int r;
1576   u32_t w_status;
1577   message m;
1578   int ipc_status;
1579 
1580   if (w_wn->state & IDENTIFIED) {
1581 	/* Wait for an interrupt that sets w_status to "not busy".
1582 	 * (w_timeout() also clears w_status.)
1583 	 */
1584 	while (w_wn->w_status & (STATUS_ADMBSY|STATUS_BSY)) {
1585 		if ((r=driver_receive(ANY, &m, &ipc_status)) != OK)
1586 			panic("driver_receive failed: %d", r);
1587 		if (is_ipc_notify(ipc_status)) {
1588 			switch (_ENDPOINT_P(m.m_source)) {
1589 				case CLOCK:
1590 					/* Timeout. */
1591 					w_timeout(); /* a.o. set w_status */
1592 					break;
1593 				case HARDWARE:
1594 					/* Interrupt. */
1595 					r= sys_inb(w_wn->base_cmd +
1596 							REG_STATUS, &w_status);
1597 					if (r != 0)
1598 						panic("sys_inb failed: %d", r);
1599 					w_wn->w_status= w_status;
1600 					w_hw_int(m.m_notify.interrupts);
1601 					break;
1602 				default:
1603 					/*
1604 					 * unhandled message.  queue it and
1605 					 * handle it in the blockdriver loop.
1606 					 */
1607 					blockdriver_mq_queue(&m, ipc_status);
1608 			}
1609 		}
1610 		else {
1611 			/*
1612 			 * unhandled message.  queue it and handle it in the
1613 			 * blockdriver loop.
1614 			 */
1615 			blockdriver_mq_queue(&m, ipc_status);
1616 		}
1617 	}
1618   } else {
1619 	/* Device not yet identified; use polling. */
1620 	(void) w_waitfor(STATUS_BSY, 0);
1621   }
1622 }
1623 
1624 /*===========================================================================*
1625  *				at_intr_wait				     *
1626  *===========================================================================*/
1627 static int at_intr_wait(void)
1628 {
1629 /* Wait for an interrupt, study the status bits and return error/success. */
1630   int r, s;
1631   u32_t inbval;
1632 
1633   w_intr_wait();
1634   if ((w_wn->w_status & (STATUS_BSY | STATUS_WF | STATUS_ERR)) == 0) {
1635 	r = OK;
1636   } else {
1637   	if ((s=sys_inb(w_wn->base_cmd + REG_ERROR, &inbval)) != OK)
1638   		panic("Couldn't read register: %d", s);
1639   	if ((w_wn->w_status & STATUS_ERR) && (inbval & ERROR_BB)) {
1640   		r = ERR_BAD_SECTOR;	/* sector marked bad, retries won't help */
1641   	} else {
1642   		r = ERR;		/* any other error */
1643   	}
1644   }
1645   w_wn->w_status |= STATUS_ADMBSY;	/* assume still busy with I/O */
1646   return(r);
1647 }
1648 
1649 /*===========================================================================*
1650  *				w_waitfor				     *
1651  *===========================================================================*/
1652 static int w_waitfor(mask, value)
1653 int mask;			/* status mask */
1654 int value;			/* required status */
1655 {
1656 /* Wait until controller is in the required state.  Return zero on timeout.
1657  */
1658   u32_t w_status;
1659   spin_t spin;
1660   int s;
1661 
1662   SPIN_FOR(&spin, timeout_usecs) {
1663 	if ((s=sys_inb(w_wn->base_cmd + REG_STATUS, &w_status)) != OK)
1664 		panic("Couldn't read register: %d", s);
1665 	w_wn->w_status= w_status;
1666 	if ((w_wn->w_status & mask) == value) {
1667         	return 1;
1668 	}
1669   }
1670 
1671   w_need_reset();			/* controller gone deaf */
1672   return(0);
1673 }
1674 
1675 /*===========================================================================*
1676  *				w_waitfor_dma				     *
1677  *===========================================================================*/
1678 static int w_waitfor_dma(mask, value)
1679 unsigned int mask;		/* status mask */
1680 unsigned value;			/* required status */
1681 {
1682 /* Wait until controller is in the required state.  Return zero on timeout.
1683  */
1684   u32_t w_status;
1685   spin_t spin;
1686   int s;
1687 
1688   SPIN_FOR(&spin, timeout_usecs) {
1689 	if ((s=sys_inb(w_wn->base_dma + DMA_STATUS, &w_status)) != OK)
1690 		panic("Couldn't read register: %d", s);
1691 	if ((w_status & mask) == value) {
1692         	return 1;
1693 	}
1694   }
1695 
1696   return(0);
1697 }
1698 
1699 /*===========================================================================*
1700  *				w_geometry				     *
1701  *===========================================================================*/
1702 static void w_geometry(devminor_t minor, struct part_geom *entry)
1703 {
1704   struct wini *wn;
1705 
1706   if (w_prepare(minor) == NULL) return;
1707 
1708   wn = w_wn;
1709 
1710   if (wn->state & ATAPI) {		/* Make up some numbers. */
1711 	entry->cylinders = (unsigned long)(wn->part[0].dv_size / SECTOR_SIZE) / (64*32);
1712 	entry->heads = 64;
1713 	entry->sectors = 32;
1714   } else {				/* Return logical geometry. */
1715 	entry->cylinders = wn->cylinders;
1716 	entry->heads = wn->heads;
1717 	entry->sectors = wn->sectors;
1718 	while (entry->cylinders > 1024) {
1719 		entry->heads *= 2;
1720 		entry->cylinders /= 2;
1721 	}
1722   }
1723 }
1724 
1725 /*===========================================================================*
1726  *				atapi_open				     *
1727  *===========================================================================*/
1728 static int atapi_open(void)
1729 {
1730 /* Should load and lock the device and obtain its size.  For now just set the
1731  * size of the device to something big.  What is really needed is a generic
1732  * SCSI layer that does all this stuff for ATAPI and SCSI devices (kjb). (XXX)
1733  */
1734   w_wn->part[0].dv_size = (u64_t)(800L*1024) * 1024;
1735   return(OK);
1736 }
1737 
1738 /*===========================================================================*
1739  *				atapi_close				     *
1740  *===========================================================================*/
1741 static void atapi_close(void)
1742 {
1743 /* Should unlock the device.  For now do nothing.  (XXX) */
1744 }
1745 
1746 static void sense_request(void)
1747 {
1748 	int r, i;
1749 	static u8_t sense[100], packet[ATAPI_PACKETSIZE];
1750 
1751 	packet[0] = SCSI_SENSE;
1752 	packet[1] = 0;
1753 	packet[2] = 0;
1754 	packet[3] = 0;
1755 	packet[4] = SENSE_PACKETSIZE;
1756 	packet[5] = 0;
1757 	packet[7] = 0;
1758 	packet[8] = 0;
1759 	packet[9] = 0;
1760 	packet[10] = 0;
1761 	packet[11] = 0;
1762 
1763 	for(i = 0; i < SENSE_PACKETSIZE; i++) sense[i] = 0xff;
1764 	r = atapi_sendpacket(packet, SENSE_PACKETSIZE, 0);
1765 	if (r != OK) { printf("request sense command failed\n"); return; }
1766 	if (atapi_intr_wait(0, 0) <= 0) { printf("WARNING: request response failed\n"); }
1767 
1768 	if (sys_insw(w_wn->base_cmd + REG_DATA, SELF, (void *) sense, SENSE_PACKETSIZE) != OK)
1769 		printf("WARNING: sense reading failed\n");
1770 
1771 	printf("sense data:");
1772 	for(i = 0; i < SENSE_PACKETSIZE; i++) printf(" %02x", sense[i]);
1773 	printf("\n");
1774 }
1775 
1776 /*===========================================================================*
1777  *				atapi_transfer				     *
1778  *===========================================================================*/
1779 static int atapi_transfer(
1780   int do_write,			/* read or write? */
1781   u64_t position,		/* offset on device to read or write */
1782   endpoint_t proc_nr,		/* process doing the request */
1783   iovec_t *iov,			/* pointer to read or write request vector */
1784   unsigned int nr_req		/* length of request vector */
1785 )
1786 {
1787   struct wini *wn = w_wn;
1788   iovec_t *iop, *iov_end = iov + nr_req;
1789   int r, s, errors, fresh;
1790   u64_t pos;
1791   unsigned long block;
1792   u64_t dv_size = w_dv->dv_size;
1793   unsigned nbytes, nblocks, before, chunk;
1794   static u8_t packet[ATAPI_PACKETSIZE];
1795   size_t addr_offset = 0;
1796   int dmabytes = 0, piobytes = 0;
1797   ssize_t total = 0;
1798 
1799   if (do_write) return(EINVAL);
1800 
1801   errors = fresh = 0;
1802 
1803   while (nr_req > 0 && !fresh) {
1804 	int do_dma = wn->dma && w_atapi_dma;
1805 	/* The Minix block size is smaller than the CD block size, so we
1806 	 * may have to read extra before or after the good data.
1807 	 */
1808 	pos = w_dv->dv_base + position;
1809 	block = (unsigned long)(pos / CD_SECTOR_SIZE);
1810 	before = (unsigned)(pos % CD_SECTOR_SIZE);
1811 
1812 	if (before)
1813 		do_dma = 0;
1814 
1815 	/* How many bytes to transfer? */
1816 	nbytes = 0;
1817 	for (iop = iov; iop < iov_end; iop++) {
1818 		nbytes += iop->iov_size;
1819 		if (iop->iov_size % CD_SECTOR_SIZE)
1820 			do_dma = 0;
1821 	}
1822 
1823 	/* Data comes in as words, so we have to enforce even byte counts. */
1824 	if ((before | nbytes) & 1) return(EINVAL);
1825 
1826 	/* Which block on disk and how close to EOF? */
1827 	if (position >= dv_size) return(total);	/* At EOF */
1828 	if (position + nbytes > dv_size)
1829 		nbytes = (unsigned)(dv_size - position);
1830 
1831 	nblocks = (before + nbytes + CD_SECTOR_SIZE - 1) / CD_SECTOR_SIZE;
1832 
1833 	/* First check to see if a reinitialization is needed. */
1834 	if (!(wn->state & INITIALIZED) && w_specify() != OK) return(EIO);
1835 
1836 	/* Build an ATAPI command packet. */
1837 	packet[0] = SCSI_READ10;
1838 	packet[1] = 0;
1839 	packet[2] = (block >> 24) & 0xFF;
1840 	packet[3] = (block >> 16) & 0xFF;
1841 	packet[4] = (block >>  8) & 0xFF;
1842 	packet[5] = (block >>  0) & 0xFF;
1843 	packet[6] = 0;
1844 	packet[7] = (nblocks >> 8) & 0xFF;
1845 	packet[8] = (nblocks >> 0) & 0xFF;
1846 	packet[9] = 0;
1847 	packet[10] = 0;
1848 	packet[11] = 0;
1849 
1850 	if(do_dma) {
1851 		stop_dma(wn);
1852 		if (!setup_dma(&nbytes, proc_nr, iov, addr_offset, 0)) {
1853 			do_dma = 0;
1854 		} else if(nbytes != nblocks * CD_SECTOR_SIZE) {
1855 			stop_dma(wn);
1856 			do_dma = 0;
1857 		}
1858 	}
1859 
1860 	/* Tell the controller to execute the packet command. */
1861 	r = atapi_sendpacket(packet, nblocks * CD_SECTOR_SIZE, do_dma);
1862 	if (r != OK) goto err;
1863 
1864 	if(do_dma) {
1865 		wn->dma_intseen = 0;
1866 		start_dma(wn, 0);
1867 		w_intr_wait();
1868 		if(!wn->dma_intseen) {
1869 			if(w_waitfor_dma(DMA_ST_INT, DMA_ST_INT)) {
1870 				wn->dma_intseen = 1;
1871 			}
1872 		}
1873 		if(error_dma(wn)) {
1874 			printf("Disabling DMA (ATAPI)\n");
1875 			wn->dma = 0;
1876 		} else {
1877 			dmabytes += nbytes;
1878 			while (nbytes > 0) {
1879 				chunk = nbytes;
1880 
1881 				if (chunk > iov->iov_size)
1882 					chunk = iov->iov_size;
1883 				position = position + chunk;
1884 				nbytes -= chunk;
1885 				total += chunk;
1886 				if ((iov->iov_size -= chunk) == 0) {
1887 					iov++;
1888 					nr_req--;
1889 				}
1890 			}
1891 		}
1892 		continue;
1893 	}
1894 
1895 	/* Read chunks of data. */
1896 	while ((r = atapi_intr_wait(do_dma, nblocks * CD_SECTOR_SIZE)) > 0) {
1897 		size_t count;
1898 		count = r;
1899 
1900 		while (before > 0 && count > 0) {	/* Discard before. */
1901 			chunk = before;
1902 			if (chunk > count) chunk = count;
1903 			if (chunk > DMA_BUF_SIZE) chunk = DMA_BUF_SIZE;
1904 			if ((s=sys_insw(wn->base_cmd + REG_DATA,
1905 				SELF, tmp_buf, chunk)) != OK)
1906 				panic("Call to sys_insw() failed: %d", s);
1907 			before -= chunk;
1908 			count -= chunk;
1909 		}
1910 
1911 		while (nbytes > 0 && count > 0) {	/* Requested data. */
1912 			chunk = nbytes;
1913 			if (chunk > count) chunk = count;
1914 			if (chunk > iov->iov_size) chunk = iov->iov_size;
1915 			if(proc_nr != SELF) {
1916 				s=sys_safe_insw(wn->base_cmd + REG_DATA,
1917 					proc_nr, (void *) iov->iov_addr,
1918 					addr_offset, chunk);
1919 			} else {
1920 				s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
1921 					(void *) (iov->iov_addr + addr_offset),
1922 					chunk);
1923 			}
1924 			if (s != OK)
1925 				panic("Call to sys_insw() failed: %d", s);
1926 			position = position + chunk;
1927 			nbytes -= chunk;
1928 			count -= chunk;
1929 			addr_offset += chunk;
1930 			piobytes += chunk;
1931 			fresh = 0;
1932 			total += chunk;
1933 			if ((iov->iov_size -= chunk) == 0) {
1934 				iov++;
1935 				nr_req--;
1936 				fresh = 1;	/* new element is optional */
1937 				addr_offset = 0;
1938 			}
1939 
1940 		}
1941 
1942 		while (count > 0) {		/* Excess data. */
1943 			chunk = count;
1944 			if (chunk > DMA_BUF_SIZE) chunk = DMA_BUF_SIZE;
1945 			if ((s=sys_insw(wn->base_cmd + REG_DATA,
1946 				SELF, tmp_buf, chunk)) != OK)
1947 				panic("Call to sys_insw() failed: %d", s);
1948 			count -= chunk;
1949 		}
1950 	}
1951 
1952 	if (r < 0) {
1953   err:		/* Don't retry if too many errors. */
1954 		if (atapi_debug) sense_request();
1955 		if (++errors == max_errors) {
1956 			w_command = CMD_IDLE;
1957 			if (atapi_debug) printf("giving up (%d)\n", errors);
1958 			return(EIO);
1959 		}
1960 		if (atapi_debug) printf("retry (%d)\n", errors);
1961 	}
1962   }
1963 
1964 #if 0
1965   if(dmabytes) printf("dmabytes %d ", dmabytes);
1966   if(piobytes) printf("piobytes %d", piobytes);
1967   if(dmabytes || piobytes) printf("\n");
1968 #endif
1969 
1970   w_command = CMD_IDLE;
1971   return(total);
1972 }
1973 
1974 /*===========================================================================*
1975  *				atapi_sendpacket			     *
1976  *===========================================================================*/
1977 static int atapi_sendpacket(packet, cnt, do_dma)
1978 u8_t *packet;
1979 unsigned cnt;
1980 int do_dma;
1981 {
1982 /* Send an Atapi Packet Command */
1983   struct wini *wn = w_wn;
1984   pvb_pair_t outbyte[6];		/* vector for sys_voutb() */
1985   int s;
1986 
1987   if (wn->state & IGNORING) return ERR;
1988 
1989   /* Select Master/Slave drive */
1990   if ((s=sys_outb(wn->base_cmd + REG_DRIVE, wn->ldhpref)) != OK)
1991   	panic("Couldn't select master/ slave drive: %d", s);
1992 
1993   if (!w_waitfor(STATUS_BSY | STATUS_DRQ, 0)) {
1994 	printf("%s: atapi_sendpacket: drive not ready\n", w_name());
1995 	return(ERR);
1996   }
1997 
1998   /* Schedule a wakeup call, some controllers are flaky. This is done with
1999    * a synchronous alarm. If a timeout occurs a SYN_ALARM message is sent
2000    * from HARDWARE, so that w_intr_wait() can call w_timeout() in case the
2001    * controller was not able to execute the command. Leftover timeouts are
2002    * simply ignored by the main loop.
2003    */
2004   sys_setalarm(wakeup_ticks, 0);
2005 
2006   if (cnt > 0xFFFE) cnt = 0xFFFE;	/* Max data per interrupt. */
2007 
2008   w_command = ATAPI_PACKETCMD;
2009   pv_set(outbyte[0], wn->base_cmd + REG_FEAT, do_dma ? FEAT_DMA : 0);
2010   pv_set(outbyte[1], wn->base_cmd + REG_IRR, 0);
2011   pv_set(outbyte[2], wn->base_cmd + REG_SAMTAG, 0);
2012   pv_set(outbyte[3], wn->base_cmd + REG_CNT_LO, (cnt >> 0) & 0xFF);
2013   pv_set(outbyte[4], wn->base_cmd + REG_CNT_HI, (cnt >> 8) & 0xFF);
2014   pv_set(outbyte[5], wn->base_cmd + REG_COMMAND, w_command);
2015   if (atapi_debug) printf("cmd: %x  ", w_command);
2016   if ((s=sys_voutb(outbyte,6)) != OK)
2017   	panic("Couldn't write registers with sys_voutb(): %d", s);
2018 
2019   if (!w_waitfor(STATUS_BSY | STATUS_DRQ, STATUS_DRQ)) {
2020 	printf("%s: timeout (BSY|DRQ -> DRQ)\n", w_name());
2021 	return(ERR);
2022   }
2023   wn->w_status |= STATUS_ADMBSY;		/* Command not at all done yet. */
2024 
2025   /* Send the command packet to the device. */
2026   if ((s=sys_outsw(wn->base_cmd + REG_DATA, SELF, packet, ATAPI_PACKETSIZE)) != OK)
2027 	panic("sys_outsw() failed: %d", s);
2028 
2029   return(OK);
2030 }
2031 
2032 /*===========================================================================*
2033  *				w_ioctl					     *
2034  *===========================================================================*/
2035 static int w_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
2036 	cp_grant_id_t grant, endpoint_t UNUSED(user_endpt))
2037 {
2038 	int r, timeout, prev, count;
2039 	struct command cmd;
2040 
2041 	switch (request) {
2042 	case DIOCTIMEOUT:
2043 		r= sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&timeout,
2044 			sizeof(timeout));
2045 
2046 		if(r != OK)
2047 		    return r;
2048 
2049 		if (timeout == 0) {
2050 			/* Restore defaults. */
2051 			timeout_usecs = DEF_TIMEOUT_USECS;
2052 			max_errors = MAX_ERRORS;
2053 			wakeup_ticks = WAKEUP_TICKS;
2054 			w_silent = 0;
2055 		} else if (timeout < 0) {
2056 			return EINVAL;
2057 		} else  {
2058 			prev = wakeup_ticks;
2059 
2060 			if (!w_standard_timeouts) {
2061 				/* Set (lower) timeout, lower error
2062 				 * tolerance and set silent mode.
2063 				 */
2064 				wakeup_ticks = timeout;
2065 				max_errors = 3;
2066 				w_silent = 1;
2067 
2068 				timeout = timeout * 1000000 / sys_hz();
2069 
2070 				if (timeout_usecs > timeout)
2071 					timeout_usecs = timeout;
2072 			}
2073 
2074 			r= sys_safecopyto(endpt, grant, 0, (vir_bytes)&prev,
2075 				sizeof(prev));
2076 
2077 			if(r != OK)
2078 				return r;
2079 		}
2080 
2081 		return OK;
2082 
2083 	case DIOCOPENCT:
2084 		if (w_prepare(minor) == NULL) return ENXIO;
2085 		count = w_wn->open_ct;
2086 		r= sys_safecopyto(endpt, grant, 0, (vir_bytes)&count,
2087 			sizeof(count));
2088 
2089 		if(r != OK)
2090 			return r;
2091 
2092 		return OK;
2093 
2094 	case DIOCFLUSH:
2095 		if (w_prepare(minor) == NULL) return ENXIO;
2096 
2097 		if (w_wn->state & ATAPI) return EINVAL;
2098 
2099 		if (!(w_wn->state & INITIALIZED) && w_specify() != OK)
2100 			return EIO;
2101 
2102 		cmd.command = CMD_FLUSH_CACHE;
2103 
2104 		if (com_simple(&cmd) != OK || !w_waitfor(STATUS_BSY, 0))
2105 			return EIO;
2106 
2107 		return (w_wn->w_status & (STATUS_ERR|STATUS_WF)) ? EIO : OK;
2108 	}
2109 
2110 	return ENOTTY;
2111 }
2112 
2113 /*===========================================================================*
2114  *				w_hw_int				     *
2115  *===========================================================================*/
2116 static void w_hw_int(unsigned int UNUSED(irqs))
2117 {
2118   /* Leftover interrupt(s) received; ack it/them.  For native drives only. */
2119   unsigned int drive;
2120   u32_t w_status;
2121 
2122   for (drive = 0; drive < MAX_DRIVES; drive++) {
2123 	if (!(wini[drive].state & IGNORING) && wini[drive].native) {
2124 		if (sys_inb((wini[drive].base_cmd + REG_STATUS),
2125 			&w_status) != OK)
2126 		{
2127 		  	panic("couldn't ack irq on drive: %d", drive);
2128 		}
2129 		wini[drive].w_status= w_status;
2130   		sys_inb(wini[drive].base_dma + DMA_STATUS, &w_status);
2131   		if(w_status & DMA_ST_INT) {
2132 	  		sys_outb(wini[drive].base_dma + DMA_STATUS, DMA_ST_INT);
2133 	  		wini[drive].dma_intseen = 1;
2134   		}
2135 	 	if (sys_irqenable(&wini[drive].irq_hook_id) != OK)
2136 		  	printf("couldn't re-enable drive %d\n", drive);
2137 	}
2138   }
2139 }
2140 
2141 
2142 #define STSTR(a) if (status & STATUS_ ## a) strlcat(str, #a " ", sizeof(str));
2143 #define ERRSTR(a) if (e & ERROR_ ## a) strlcat(str, #a " ", sizeof(str));
2144 static char *strstatus(int status)
2145 {
2146 	static char str[200];
2147 	str[0] = '\0';
2148 
2149 	STSTR(BSY);
2150 	STSTR(DRDY);
2151 	STSTR(DMADF);
2152 	STSTR(SRVCDSC);
2153 	STSTR(DRQ);
2154 	STSTR(CORR);
2155 	STSTR(CHECK);
2156 	return str;
2157 }
2158 
2159 static char *strerr(int e)
2160 {
2161 	static char str[200];
2162 	str[0] = '\0';
2163 
2164 	ERRSTR(BB);
2165 	ERRSTR(ECC);
2166 	ERRSTR(ID);
2167 	ERRSTR(AC);
2168 	ERRSTR(TK);
2169 	ERRSTR(DM);
2170 
2171 	return str;
2172 }
2173 
2174 /*===========================================================================*
2175  *				atapi_intr_wait				     *
2176  *===========================================================================*/
2177 static int atapi_intr_wait(int UNUSED(do_dma), size_t UNUSED(max))
2178 {
2179 /* Wait for an interrupt and study the results.  Returns a number of bytes
2180  * that need to be transferred, or an error code.
2181  */
2182   struct wini *wn = w_wn;
2183   pvb_pair_t inbyte[4];		/* vector for sys_vinb() */
2184   int s;			/* status for sys_vinb() */
2185   int e;
2186   int len;
2187   int irr;
2188   int r;
2189   int phase;
2190 
2191   w_intr_wait();
2192 
2193   /* Request series of device I/O. */
2194   inbyte[0].port = wn->base_cmd + REG_ERROR;
2195   inbyte[1].port = wn->base_cmd + REG_CNT_LO;
2196   inbyte[2].port = wn->base_cmd + REG_CNT_HI;
2197   inbyte[3].port = wn->base_cmd + REG_IRR;
2198   if ((s=sys_vinb(inbyte, 4)) != OK)
2199   	panic("ATAPI failed sys_vinb(): %d", s);
2200   e = inbyte[0].value;
2201   len = inbyte[1].value;
2202   len |= inbyte[2].value << 8;
2203   irr = inbyte[3].value;
2204 
2205   if (wn->w_status & (STATUS_BSY | STATUS_CHECK)) {
2206 	if (atapi_debug) {
2207 		printf("atapi fail:  S=%x=%s E=%02x=%s L=%04x I=%02x\n", wn->w_status, strstatus(wn->w_status), e, strerr(e), len, irr);
2208 	}
2209   	return ERR;
2210   }
2211 
2212   phase = (wn->w_status & STATUS_DRQ) | (irr & (IRR_COD | IRR_IO));
2213 
2214   switch (phase) {
2215   case IRR_COD | IRR_IO:
2216 	if (ATAPI_DEBUG) printf("ACD: Phase Command Complete\n");
2217 	r = OK;
2218 	break;
2219   case 0:
2220 	if (ATAPI_DEBUG) printf("ACD: Phase Command Aborted\n");
2221 	r = ERR;
2222 	break;
2223   case STATUS_DRQ | IRR_COD:
2224 	if (ATAPI_DEBUG) printf("ACD: Phase Command Out\n");
2225 	r = ERR;
2226 	break;
2227   case STATUS_DRQ:
2228 	if (ATAPI_DEBUG) printf("ACD: Phase Data Out %d\n", len);
2229 	r = len;
2230 	break;
2231   case STATUS_DRQ | IRR_IO:
2232 	if (ATAPI_DEBUG) printf("ACD: Phase Data In %d\n", len);
2233 	r = len;
2234 	break;
2235   default:
2236 	if (ATAPI_DEBUG) printf("ACD: Phase Unknown\n");
2237 	r = ERR;
2238 	break;
2239   }
2240 
2241   wn->w_status |= STATUS_ADMBSY;	/* Assume not done yet. */
2242   return(r);
2243 }
2244