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