xref: /plan9-contrib/sys/src/9/pc/sdata.c (revision 906943f9f6b8411972abb5e3a03ed19f74be7ccc)
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "ureg.h"
8 #include "../port/error.h"
9 
10 #include "../port/sd.h"
11 
12 #define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
13 #define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
14 
15 extern SDifc sdataifc;
16 
17 enum {
18 	DbgCONFIG	= 0x0001,	/* detected drive config info */
19 	DbgIDENTIFY	= 0x0002,	/* detected drive identify info */
20 	DbgSTATE	= 0x0004,	/* dump state on panic */
21 	DbgPROBE	= 0x0008,	/* trace device probing */
22 	DbgDEBUG	= 0x0080,	/* the current problem... */
23 	DbgINL		= 0x0100,	/* That Inil20+ message we hate */
24 	Dbg48BIT	= 0x0200,	/* 48-bit LBA */
25 	DbgBsy		= 0x0400,	/* interrupt but Bsy (shared IRQ) */
26 };
27 #define DEBUG		(DbgDEBUG|DbgSTATE)
28 
29 enum {					/* I/O ports */
30 	Data		= 0,
31 	Error		= 1,		/* (read) */
32 	Features	= 1,		/* (write) */
33 	Count		= 2,		/* sector count<7-0>, sector count<15-8> */
34 	Ir		= 2,		/* interrupt reason (PACKET) */
35 	Sector		= 3,		/* sector number */
36 	Lbalo		= 3,		/* LBA<7-0>, LBA<31-24> */
37 	Cyllo		= 4,		/* cylinder low */
38 	Bytelo		= 4,		/* byte count low (PACKET) */
39 	Lbamid		= 4,		/* LBA<15-8>, LBA<39-32> */
40 	Cylhi		= 5,		/* cylinder high */
41 	Bytehi		= 5,		/* byte count hi (PACKET) */
42 	Lbahi		= 5,		/* LBA<23-16>, LBA<47-40> */
43 	Dh		= 6,		/* Device/Head, LBA<27-24> */
44 	Status		= 7,		/* (read) */
45 	Command		= 7,		/* (write) */
46 
47 	As		= 2,		/* Alternate Status (read) */
48 	Dc		= 2,		/* Device Control (write) */
49 };
50 
51 enum {					/* Error */
52 	Med		= 0x01,		/* Media error */
53 	Ili		= 0x01,		/* command set specific (PACKET) */
54 	Nm		= 0x02,		/* No Media */
55 	Eom		= 0x02,		/* command set specific (PACKET) */
56 	Abrt		= 0x04,		/* Aborted command */
57 	Mcr		= 0x08,		/* Media Change Request */
58 	Idnf		= 0x10,		/* no user-accessible address */
59 	Mc		= 0x20,		/* Media Change */
60 	Unc		= 0x40,		/* Uncorrectable data error */
61 	Wp		= 0x40,		/* Write Protect */
62 	Icrc		= 0x80,		/* Interface CRC error */
63 };
64 
65 enum {					/* Features */
66 	Dma		= 0x01,		/* data transfer via DMA (PACKET) */
67 	Ovl		= 0x02,		/* command overlapped (PACKET) */
68 };
69 
70 enum {					/* Interrupt Reason */
71 	Cd		= 0x01,		/* Command/Data */
72 	Io		= 0x02,		/* I/O direction */
73 	Rel		= 0x04,		/* Bus Release */
74 };
75 
76 enum {					/* Device/Head */
77 	Dev0		= 0xA0,		/* Master */
78 	Dev1		= 0xB0,		/* Slave */
79 	Lba		= 0x40,		/* LBA mode */
80 };
81 
82 enum {					/* Status, Alternate Status */
83 	Err		= 0x01,		/* Error */
84 	Chk		= 0x01,		/* Check error (PACKET) */
85 	Drq		= 0x08,		/* Data Request */
86 	Dsc		= 0x10,		/* Device Seek Complete */
87 	Serv		= 0x10,		/* Service */
88 	Df		= 0x20,		/* Device Fault */
89 	Dmrd		= 0x20,		/* DMA ready (PACKET) */
90 	Drdy		= 0x40,		/* Device Ready */
91 	Bsy		= 0x80,		/* Busy */
92 };
93 
94 enum {					/* Command */
95 	Cnop		= 0x00,		/* NOP */
96 	Cdr		= 0x08,		/* Device Reset */
97 	Crs		= 0x20,		/* Read Sectors */
98 	Crs48		= 0x24,		/* Read Sectors Ext */
99 	Crd48		= 0x25,		/* Read w/ DMA Ext */
100 	Crdq48		= 0x26,		/* Read w/ DMA Queued Ext */
101 	Crsm48		= 0x29,		/* Read Multiple Ext */
102 	Cws		= 0x30,		/* Write Sectors */
103 	Cws48		= 0x34,		/* Write Sectors Ext */
104 	Cwd48		= 0x35,		/* Write w/ DMA Ext */
105 	Cwdq48		= 0x36,		/* Write w/ DMA Queued Ext */
106 	Cwsm48		= 0x39,		/* Write Multiple Ext */
107 	Cedd		= 0x90,		/* Execute Device Diagnostics */
108 	Cpkt		= 0xA0,		/* Packet */
109 	Cidpkt		= 0xA1,		/* Identify Packet Device */
110 	Crsm		= 0xC4,		/* Read Multiple */
111 	Cwsm		= 0xC5,		/* Write Multiple */
112 	Csm		= 0xC6,		/* Set Multiple */
113 	Crdq		= 0xC7,		/* Read DMA queued */
114 	Crd		= 0xC8,		/* Read DMA */
115 	Cwd		= 0xCA,		/* Write DMA */
116 	Cwdq		= 0xCC,		/* Write DMA queued */
117 	Cstandby	= 0xE2,		/* Standby */
118 	Cid		= 0xEC,		/* Identify Device */
119 	Csf		= 0xEF,		/* Set Features */
120 };
121 
122 enum {					/* Device Control */
123 	Nien		= 0x02,		/* (not) Interrupt Enable */
124 	Srst		= 0x04,		/* Software Reset */
125 	Hob		= 0x80,		/* High Order Bit [sic] */
126 };
127 
128 enum {					/* PCI Configuration Registers */
129 	Bmiba		= 0x20,		/* Bus Master Interface Base Address */
130 	Idetim		= 0x40,		/* IE Timing */
131 	Sidetim		= 0x44,		/* Slave IE Timing */
132 	Udmactl		= 0x48,		/* Ultra DMA/33 Control */
133 	Udmatim		= 0x4A,		/* Ultra DMA/33 Timing */
134 };
135 
136 enum {					/* Bus Master IDE I/O Ports */
137 	Bmicx		= 0,		/* Command */
138 	Bmisx		= 2,		/* Status */
139 	Bmidtpx		= 4,		/* Descriptor Table Pointer */
140 };
141 
142 enum {					/* Bmicx */
143 	Ssbm		= 0x01,		/* Start/Stop Bus Master */
144 	Rwcon		= 0x08,		/* Read/Write Control */
145 };
146 
147 enum {					/* Bmisx */
148 	Bmidea		= 0x01,		/* Bus Master IDE Active */
149 	Idedmae		= 0x02,		/* IDE DMA Error  (R/WC) */
150 	Ideints		= 0x04,		/* IDE Interrupt Status (R/WC) */
151 	Dma0cap		= 0x20,		/* Drive 0 DMA Capable */
152 	Dma1cap		= 0x40,		/* Drive 0 DMA Capable */
153 };
154 enum {					/* Physical Region Descriptor */
155 	PrdEOT		= 0x80000000,	/* End of Transfer */
156 };
157 
158 enum {					/* offsets into the identify info. */
159 	Iconfig		= 0,		/* general configuration */
160 	Ilcyl		= 1,		/* logical cylinders */
161 	Ilhead		= 3,		/* logical heads */
162 	Ilsec		= 6,		/* logical sectors per logical track */
163 	Iserial		= 10,		/* serial number */
164 	Ifirmware	= 23,		/* firmware revision */
165 	Imodel		= 27,		/* model number */
166 	Imaxrwm		= 47,		/* max. read/write multiple sectors */
167 	Icapabilities	= 49,		/* capabilities */
168 	Istandby	= 50,		/* device specific standby timer */
169 	Ipiomode	= 51,		/* PIO data transfer mode number */
170 	Ivalid		= 53,
171 	Iccyl		= 54,		/* cylinders if (valid&0x01) */
172 	Ichead		= 55,		/* heads if (valid&0x01) */
173 	Icsec		= 56,		/* sectors if (valid&0x01) */
174 	Iccap		= 57,		/* capacity if (valid&0x01) */
175 	Irwm		= 59,		/* read/write multiple */
176 	Ilba		= 60,		/* LBA size */
177 	Imwdma		= 63,		/* multiword DMA mode */
178 	Iapiomode	= 64,		/* advanced PIO modes supported */
179 	Iminmwdma	= 65,		/* min. multiword DMA cycle time */
180 	Irecmwdma	= 66,		/* rec. multiword DMA cycle time */
181 	Iminpio		= 67,		/* min. PIO cycle w/o flow control */
182 	Iminiordy	= 68,		/* min. PIO cycle with IORDY */
183 	Ipcktbr		= 71,		/* time from PACKET to bus release */
184 	Iserbsy		= 72,		/* time from SERVICE to !Bsy */
185 	Iqdepth		= 75,		/* max. queue depth */
186 	Imajor		= 80,		/* major version number */
187 	Iminor		= 81,		/* minor version number */
188 	Icsfs		= 82,		/* command set/feature supported */
189 	Icsfe		= 85,		/* command set/feature enabled */
190 	Iudma		= 88,		/* ultra DMA mode */
191 	Ierase		= 89,		/* time for security erase */
192 	Ieerase		= 90,		/* time for enhanced security erase */
193 	Ipower		= 91,		/* current advanced power management */
194 	Ilba48		= 100,		/* 48-bit LBA size (64 bits in 100-103) */
195 	Irmsn		= 127,		/* removable status notification */
196 	Isecstat	= 128,		/* security status */
197 	Icfapwr		= 160,		/* CFA power mode */
198 	Imediaserial	= 176,		/* current media serial number */
199 	Icksum		= 255,		/* checksum */
200 };
201 
202 enum {					/* bit masks for config identify info */
203 	Mpktsz		= 0x0003,	/* packet command size */
204 	Mincomplete	= 0x0004,	/* incomplete information */
205 	Mdrq		= 0x0060,	/* DRQ type */
206 	Mrmdev		= 0x0080,	/* device is removable */
207 	Mtype		= 0x1F00,	/* device type */
208 	Mproto		= 0x8000,	/* command protocol */
209 };
210 
211 enum {					/* bit masks for capabilities identify info */
212 	Mdma		= 0x0100,	/* DMA supported */
213 	Mlba		= 0x0200,	/* LBA supported */
214 	Mnoiordy	= 0x0400,	/* IORDY may be disabled */
215 	Miordy		= 0x0800,	/* IORDY supported */
216 	Msoftrst	= 0x1000,	/* needs soft reset when Bsy */
217 	Mstdby		= 0x2000,	/* standby supported */
218 	Mqueueing	= 0x4000,	/* queueing overlap supported */
219 	Midma		= 0x8000,	/* interleaved DMA supported */
220 };
221 
222 enum {					/* bit masks for supported/enabled features */
223 	Msmart		= 0x0001,
224 	Msecurity	= 0x0002,
225 	Mrmmedia	= 0x0004,
226 	Mpwrmgmt	= 0x0008,
227 	Mpkt		= 0x0010,
228 	Mwcache		= 0x0020,
229 	Mlookahead	= 0x0040,
230 	Mrelirq		= 0x0080,
231 	Msvcirq		= 0x0100,
232 	Mreset		= 0x0200,
233 	Mprotected	= 0x0400,
234 	Mwbuf		= 0x1000,
235 	Mrbuf		= 0x2000,
236 	Mnop		= 0x4000,
237 	Mmicrocode	= 0x0001,
238 	Mqueued		= 0x0002,
239 	Mcfa		= 0x0004,
240 	Mapm		= 0x0008,
241 	Mnotify		= 0x0010,
242 	Mstandby	= 0x0020,
243 	Mspinup		= 0x0040,
244 	Mmaxsec		= 0x0100,
245 	Mautoacoustic	= 0x0200,
246 	Maddr48		= 0x0400,
247 	Mdevconfov	= 0x0800,
248 	Mflush		= 0x1000,
249 	Mflush48	= 0x2000,
250 	Msmarterror	= 0x0001,
251 	Msmartselftest	= 0x0002,
252 	Mmserial	= 0x0004,
253 	Mmpassthru	= 0x0008,
254 	Mlogging	= 0x0020,
255 };
256 
257 typedef struct Ctlr Ctlr;
258 typedef struct Drive Drive;
259 
260 typedef struct Prd {			/* Physical Region Descriptor */
261 	ulong	pa;			/* Physical Base Address */
262 	int	count;
263 } Prd;
264 
265 enum {
266 	BMspan		= 64*1024,	/* must be power of 2 <= 64*1024 */
267 
268 	Nprd		= SDmaxio/BMspan+2,
269 };
270 
271 typedef struct Ctlr {
272 	int	cmdport;
273 	int	ctlport;
274 	int	irq;
275 	int	tbdf;
276 	int	bmiba;			/* bus master interface base address */
277 	int	maxio;			/* sector count transfer maximum */
278 	int	span;			/* don't span this boundary with dma */
279 
280 	Pcidev*	pcidev;
281 	void	(*ienable)(Ctlr*);
282 	void	(*idisable)(Ctlr*);
283 	SDev*	sdev;
284 
285 	Drive*	drive[2];
286 
287 	Prd*	prdt;			/* physical region descriptor table */
288 
289 	QLock;				/* current command */
290 	Drive*	curdrive;
291 	int	command;		/* last command issued (debugging) */
292 	Rendez;
293 	int	done;
294 
295 	Lock;				/* register access */
296 } Ctlr;
297 
298 typedef struct Drive {
299 	Ctlr*	ctlr;
300 
301 	int	dev;
302 	ushort	info[256];
303 	int	c;			/* cylinder */
304 	int	h;			/* head */
305 	int	s;			/* sector */
306 	vlong	sectors;		/* total */
307 	int	secsize;		/* sector size */
308 
309 	int	dma;			/* DMA R/W possible */
310 	int	dmactl;
311 	int	rwm;			/* read/write multiple possible */
312 	int	rwmctl;
313 
314 	int	pkt;			/* PACKET device, length of pktcmd */
315 	uchar	pktcmd[16];
316 	int	pktdma;			/* this PACKET command using dma */
317 
318 	uchar	sense[18];
319 	uchar	inquiry[48];
320 
321 	QLock;				/* drive access */
322 	int	command;		/* current command */
323 	int	write;
324 	uchar*	data;
325 	int	dlen;
326 	uchar*	limit;
327 	int	count;			/* sectors */
328 	int	block;			/* R/W bytes per block */
329 	int	status;
330 	int	error;
331 	int	flags;			/* internal flags */
332 } Drive;
333 
334 enum {					/* internal flags */
335 	Lba48		= 0x1,		/* LBA48 mode */
336 	Lba48always	= 0x2,		/* ... */
337 };
338 
339 static void
340 pc87415ienable(Ctlr* ctlr)
341 {
342 	Pcidev *p;
343 	int x;
344 
345 	p = ctlr->pcidev;
346 	if(p == nil)
347 		return;
348 
349 	x = pcicfgr32(p, 0x40);
350 	if(ctlr->cmdport == p->mem[0].bar)
351 		x &= ~0x00000100;
352 	else
353 		x &= ~0x00000200;
354 	pcicfgw32(p, 0x40, x);
355 }
356 
357 static void
358 atadumpstate(Drive* drive, uchar* cmd, vlong lba, int count)
359 {
360 	Prd *prd;
361 	Pcidev *p;
362 	Ctlr *ctlr;
363 	int i, bmiba;
364 
365 	if(!(DEBUG & DbgSTATE)){
366 		USED(drive, cmd, lba, count);
367 		return;
368 	}
369 
370 	ctlr = drive->ctlr;
371 	print("command %2.2uX\n", ctlr->command);
372 	print("data %8.8p limit %8.8p dlen %d status %uX error %uX\n",
373 		drive->data, drive->limit, drive->dlen,
374 		drive->status, drive->error);
375 	if(cmd != nil){
376 		print("lba %d -> %lld, count %d -> %d (%d)\n",
377 			(cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5], lba,
378 			(cmd[7]<<8)|cmd[8], count, drive->count);
379 	}
380 	if(!(inb(ctlr->ctlport+As) & Bsy)){
381 		for(i = 1; i < 7; i++)
382 			print(" 0x%2.2uX", inb(ctlr->cmdport+i));
383 		print(" 0x%2.2uX\n", inb(ctlr->ctlport+As));
384 	}
385 	if(drive->command == Cwd || drive->command == Crd){
386 		bmiba = ctlr->bmiba;
387 		prd = ctlr->prdt;
388 		print("bmicx %2.2uX bmisx %2.2uX prdt %8.8p\n",
389 			inb(bmiba+Bmicx), inb(bmiba+Bmisx), prd);
390 		for(;;){
391 			print("pa 0x%8.8luX count %8.8uX\n",
392 				prd->pa, prd->count);
393 			if(prd->count & PrdEOT)
394 				break;
395 			prd++;
396 		}
397 	}
398 	if(ctlr->pcidev && ctlr->pcidev->vid == 0x8086){
399 		p = ctlr->pcidev;
400 		print("0x40: %4.4uX 0x42: %4.4uX",
401 			pcicfgr16(p, 0x40), pcicfgr16(p, 0x42));
402 		print("0x48: %2.2uX\n", pcicfgr8(p, 0x48));
403 		print("0x4A: %4.4uX\n", pcicfgr16(p, 0x4A));
404 	}
405 }
406 
407 static int
408 atadebug(int cmdport, int ctlport, char* fmt, ...)
409 {
410 	int i, n;
411 	va_list arg;
412 	char buf[PRINTSIZE];
413 
414 	if(!(DEBUG & DbgPROBE)){
415 		USED(cmdport, ctlport, fmt);
416 		return 0;
417 	}
418 
419 	va_start(arg, fmt);
420 	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
421 	va_end(arg);
422 
423 	if(cmdport){
424 		if(buf[n-1] == '\n')
425 			n--;
426 		n += snprint(buf+n, PRINTSIZE-n, " ataregs 0x%uX:",
427 			cmdport);
428 		for(i = Features; i < Command; i++)
429 			n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
430 				inb(cmdport+i));
431 		if(ctlport)
432 			n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
433 				inb(ctlport+As));
434 		n += snprint(buf+n, PRINTSIZE-n, "\n");
435 	}
436 	putstrn(buf, n);
437 
438 	return n;
439 }
440 
441 static int
442 ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
443 {
444 	int as;
445 
446 	atadebug(cmdport, ctlport, "ataready: dev %uX reset %uX ready %uX",
447 		dev, reset, ready);
448 
449 	for(;;){
450 		/*
451 		 * Wait for the controller to become not busy and
452 		 * possibly for a status bit to become true (usually
453 		 * Drdy). Must change to the appropriate device
454 		 * register set if necessary before testing for ready.
455 		 * Always run through the loop at least once so it
456 		 * can be used as a test for !Bsy.
457 		 */
458 		as = inb(ctlport+As);
459 		if(as & reset){
460 			/* nothing to do */
461 		}
462 		else if(dev){
463 			outb(cmdport+Dh, dev);
464 			dev = 0;
465 		}
466 		else if(ready == 0 || (as & ready)){
467 			atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
468 			return as;
469 		}
470 
471 		if(micro-- <= 0){
472 			atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
473 			break;
474 		}
475 		microdelay(1);
476 	}
477 	atadebug(cmdport, ctlport, "ataready: timeout");
478 
479 	return -1;
480 }
481 
482 /*
483 static int
484 atacsf(Drive* drive, vlong csf, int supported)
485 {
486 	ushort *info;
487 	int cmdset, i, x;
488 
489 	if(supported)
490 		info = &drive->info[Icsfs];
491 	else
492 		info = &drive->info[Icsfe];
493 
494 	for(i = 0; i < 3; i++){
495 		x = (csf>>(16*i)) & 0xFFFF;
496 		if(x == 0)
497 			continue;
498 		cmdset = info[i];
499 		if(cmdset == 0 || cmdset == 0xFFFF)
500 			return 0;
501 		return cmdset & x;
502 	}
503 
504 	return 0;
505 }
506 */
507 
508 static int
509 atadone(void* arg)
510 {
511 	return ((Ctlr*)arg)->done;
512 }
513 
514 static int
515 atarwmmode(Drive* drive, int cmdport, int ctlport, int dev)
516 {
517 	int as, maxrwm, rwm;
518 
519 	maxrwm = (drive->info[Imaxrwm] & 0xFF);
520 	if(maxrwm == 0)
521 		return 0;
522 
523 	/*
524 	 * Sometimes drives come up with the current count set
525 	 * to 0; if so, set a suitable value, otherwise believe
526 	 * the value in Irwm if the 0x100 bit is set.
527 	 */
528 	if(drive->info[Irwm] & 0x100)
529 		rwm = (drive->info[Irwm] & 0xFF);
530 	else
531 		rwm = 0;
532 	if(rwm == 0)
533 		rwm = maxrwm;
534 	if(rwm > 16)
535 		rwm = 16;
536 	if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 102*1000) < 0)
537 		return 0;
538 	outb(cmdport+Count, rwm);
539 	outb(cmdport+Command, Csm);
540 	microdelay(1);
541 	as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 1000);
542 	inb(cmdport+Status);
543 	if(as < 0 || (as & (Df|Err)))
544 		return 0;
545 
546 	drive->rwm = rwm;
547 
548 	return rwm;
549 }
550 
551 static int
552 atadmamode(Drive* drive)
553 {
554 	int dma;
555 
556 	/*
557 	 * Check if any DMA mode enabled.
558 	 * Assumes the BIOS has picked and enabled the best.
559 	 * This is completely passive at the moment, no attempt is
560 	 * made to ensure the hardware is correctly set up.
561 	 */
562 	dma = drive->info[Imwdma] & 0x0707;
563 	drive->dma = (dma>>8) & dma;
564 	if(drive->dma == 0 && (drive->info[Ivalid] & 0x04)){
565 		dma = drive->info[Iudma] & 0x7F7F;
566 		drive->dma = (dma>>8) & dma;
567 		if(drive->dma)
568 			drive->dma |= 'U'<<16;
569 	}
570 
571 	return dma;
572 }
573 
574 static int
575 ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
576 {
577 	int as, command, drdy;
578 
579 	if(pkt){
580 		command = Cidpkt;
581 		drdy = 0;
582 	}
583 	else{
584 		command = Cid;
585 		drdy = Drdy;
586 	}
587 	as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
588 	if(as < 0)
589 		return as;
590 	outb(cmdport+Command, command);
591 	microdelay(1);
592 
593 	as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
594 	if(as < 0)
595 		return -1;
596 	if(as & Err)
597 		return as;
598 
599 	memset(info, 0, 512);
600 	inss(cmdport+Data, info, 256);
601 	inb(cmdport+Status);
602 
603 	if(DEBUG & DbgIDENTIFY){
604 		int i;
605 		ushort *sp;
606 
607 		sp = (ushort*)info;
608 		for(i = 0; i < 256; i++){
609 			if(i && (i%16) == 0)
610 				print("\n");
611 			print(" %4.4uX", *sp);
612 			sp++;
613 		}
614 		print("\n");
615 	}
616 
617 	return 0;
618 }
619 
620 static Drive*
621 atadrive(int cmdport, int ctlport, int dev)
622 {
623 	Drive *drive;
624 	int as, i, pkt;
625 	uchar buf[512], *p;
626 	ushort iconfig, *sp;
627 
628 	atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
629 	pkt = 1;
630 retry:
631 	as = ataidentify(cmdport, ctlport, dev, pkt, buf);
632 	if(as < 0)
633 		return nil;
634 	if(as & Err){
635 		if(pkt == 0)
636 			return nil;
637 		pkt = 0;
638 		goto retry;
639 	}
640 
641 	if((drive = malloc(sizeof(Drive))) == nil)
642 		return nil;
643 	drive->dev = dev;
644 	memmove(drive->info, buf, sizeof(drive->info));
645 	drive->sense[0] = 0x70;
646 	drive->sense[7] = sizeof(drive->sense)-7;
647 
648 	drive->inquiry[2] = 2;
649 	drive->inquiry[3] = 2;
650 	drive->inquiry[4] = sizeof(drive->inquiry)-4;
651 	p = &drive->inquiry[8];
652 	sp = &drive->info[Imodel];
653 	for(i = 0; i < 20; i++){
654 		*p++ = *sp>>8;
655 		*p++ = *sp++;
656 	}
657 
658 	drive->secsize = 512;
659 
660 	/*
661 	 * Beware the CompactFlash Association feature set.
662 	 * Now, why this value in Iconfig just walks all over the bit
663 	 * definitions used in the other parts of the ATA/ATAPI standards
664 	 * is a mystery and a sign of true stupidity on someone's part.
665 	 * Anyway, the standard says if this value is 0x848A then it's
666 	 * CompactFlash and it's NOT a packet device.
667 	 */
668 	iconfig = drive->info[Iconfig];
669 	if(iconfig != 0x848A && (iconfig & 0xC000) == 0x8000){
670 		if(iconfig & 0x01)
671 			drive->pkt = 16;
672 		else
673 			drive->pkt = 12;
674 	}
675 	else{
676 		if(drive->info[Ivalid] & 0x0001){
677 			drive->c = drive->info[Iccyl];
678 			drive->h = drive->info[Ichead];
679 			drive->s = drive->info[Icsec];
680 		}
681 		else{
682 			drive->c = drive->info[Ilcyl];
683 			drive->h = drive->info[Ilhead];
684 			drive->s = drive->info[Ilsec];
685 		}
686 		if(drive->info[Icapabilities] & Mlba){
687 			if(drive->info[Icsfs+1] & Maddr48){
688 				drive->sectors = drive->info[Ilba48]
689 					| (drive->info[Ilba48+1]<<16)
690 					| ((vlong)drive->info[Ilba48+2]<<32);
691 				drive->flags |= Lba48;
692 			}
693 			else{
694 				drive->sectors = (drive->info[Ilba+1]<<16)
695 					 |drive->info[Ilba];
696 			}
697 			drive->dev |= Lba;
698 		}
699 		else
700 			drive->sectors = drive->c*drive->h*drive->s;
701 		atarwmmode(drive, cmdport, ctlport, dev);
702 	}
703 	atadmamode(drive);
704 
705 	if(DEBUG & DbgCONFIG){
706 		print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
707 			dev, cmdport, iconfig, drive->info[Icapabilities]);
708 		print(" mwdma %4.4uX", drive->info[Imwdma]);
709 		if(drive->info[Ivalid] & 0x04)
710 			print(" udma %4.4uX", drive->info[Iudma]);
711 		print(" dma %8.8uX rwm %ud", drive->dma, drive->rwm);
712 		if(drive->flags&Lba48)
713 			print("\tLLBA sectors %lld", drive->sectors);
714 		print("\n");
715 	}
716 
717 	return drive;
718 }
719 
720 static void
721 atasrst(int ctlport)
722 {
723 	/*
724 	 * Srst is a big stick and may cause problems if further
725 	 * commands are tried before the drives become ready again.
726 	 * Also, there will be problems here if overlapped commands
727 	 * are ever supported.
728 	 */
729 	microdelay(5);
730 	outb(ctlport+Dc, Srst);
731 	microdelay(5);
732 	outb(ctlport+Dc, 0);
733 	microdelay(2*1000);
734 }
735 
736 static SDev*
737 ataprobe(int cmdport, int ctlport, int irq)
738 {
739 	Ctlr* ctlr;
740 	SDev *sdev;
741 	Drive *drive;
742 	int dev, error, rhi, rlo;
743 	static int nonlegacy = 'C';
744 
745 	if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
746 		print("ataprobe: Cannot allocate %X\n", cmdport);
747 		return nil;
748 	}
749 	if(ioalloc(ctlport+As, 1, 0, "atactl") < 0){
750 		print("ataprobe: Cannot allocate %X\n", ctlport + As);
751 		iofree(cmdport);
752 		return nil;
753 	}
754 
755 	/*
756 	 * Try to detect a floating bus.
757 	 * Bsy should be cleared. If not, see if the cylinder registers
758 	 * are read/write capable.
759 	 * If the master fails, try the slave to catch slave-only
760 	 * configurations.
761 	 * There's no need to restore the tested registers as they will
762 	 * be reset on any detected drives by the Cedd command.
763 	 * All this indicates is that there is at least one drive on the
764 	 * controller; when the non-existent drive is selected in a
765 	 * single-drive configuration the registers of the existing drive
766 	 * are often seen, only command execution fails.
767 	 */
768 	dev = Dev0;
769 	if(inb(ctlport+As) & Bsy){
770 		outb(cmdport+Dh, dev);
771 		microdelay(1);
772 trydev1:
773 		atadebug(cmdport, ctlport, "ataprobe bsy");
774 		outb(cmdport+Cyllo, 0xAA);
775 		outb(cmdport+Cylhi, 0x55);
776 		outb(cmdport+Sector, 0xFF);
777 		rlo = inb(cmdport+Cyllo);
778 		rhi = inb(cmdport+Cylhi);
779 		if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)){
780 			if(dev == Dev1){
781 release:
782 				iofree(cmdport);
783 				iofree(ctlport+As);
784 				return nil;
785 			}
786 			dev = Dev1;
787 			if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
788 				goto trydev1;
789 		}
790 	}
791 
792 	/*
793 	 * Disable interrupts on any detected controllers.
794 	 */
795 	outb(ctlport+Dc, Nien);
796 tryedd1:
797 	if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
798 		/*
799 		 * There's something there, but it didn't come up clean,
800 		 * so try hitting it with a big stick. The timing here is
801 		 * wrong but this is a last-ditch effort and it sometimes
802 		 * gets some marginal hardware back online.
803 		 */
804 		atasrst(ctlport);
805 		if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
806 			goto release;
807 	}
808 
809 	/*
810 	 * Can only get here if controller is not busy.
811 	 * If there are drives Bsy will be set within 400nS,
812 	 * must wait 2mS before testing Status.
813 	 * Wait for the command to complete (6 seconds max).
814 	 */
815 	outb(cmdport+Command, Cedd);
816 	delay(2);
817 	if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
818 		goto release;
819 
820 	/*
821 	 * If bit 0 of the error register is set then the selected drive
822 	 * exists. This is enough to detect single-drive configurations.
823 	 * However, if the master exists there is no way short of executing
824 	 * a command to determine if a slave is present.
825 	 * It appears possible to get here testing Dev0 although it doesn't
826 	 * exist and the EDD won't take, so try again with Dev1.
827 	 */
828 	error = inb(cmdport+Error);
829 	atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
830 	if((error & ~0x80) != 0x01){
831 		if(dev == Dev1)
832 			goto release;
833 		dev = Dev1;
834 		goto tryedd1;
835 	}
836 
837 	/*
838 	 * At least one drive is known to exist, try to
839 	 * identify it. If that fails, don't bother checking
840 	 * any further.
841 	 * If the one drive found is Dev0 and the EDD command
842 	 * didn't indicate Dev1 doesn't exist, check for it.
843 	 */
844 	if((drive = atadrive(cmdport, ctlport, dev)) == nil)
845 		goto release;
846 	if((ctlr = malloc(sizeof(Ctlr))) == nil){
847 		free(drive);
848 		goto release;
849 	}
850 	memset(ctlr, 0, sizeof(Ctlr));
851 	if((sdev = malloc(sizeof(SDev))) == nil){
852 		free(ctlr);
853 		free(drive);
854 		goto release;
855 	}
856 	memset(sdev, 0, sizeof(SDev));
857 	drive->ctlr = ctlr;
858 	if(dev == Dev0){
859 		ctlr->drive[0] = drive;
860 		if(!(error & 0x80)){
861 			/*
862 			 * Always leave Dh pointing to a valid drive,
863 			 * otherwise a subsequent call to ataready on
864 			 * this controller may try to test a bogus Status.
865 			 * Ataprobe is the only place possibly invalid
866 			 * drives should be selected.
867 			 */
868 			drive = atadrive(cmdport, ctlport, Dev1);
869 			if(drive != nil){
870 				drive->ctlr = ctlr;
871 				ctlr->drive[1] = drive;
872 			}
873 			else{
874 				outb(cmdport+Dh, Dev0);
875 				microdelay(1);
876 			}
877 		}
878 	}
879 	else
880 		ctlr->drive[1] = drive;
881 
882 	ctlr->cmdport = cmdport;
883 	ctlr->ctlport = ctlport;
884 	ctlr->irq = irq;
885 	ctlr->tbdf = BUSUNKNOWN;
886 	ctlr->command = Cedd;		/* debugging */
887 
888 	switch(cmdport){
889 	default:
890 		sdev->idno = nonlegacy;
891 		break;
892 	case 0x1F0:
893 		sdev->idno = 'C';
894 		nonlegacy = 'E';
895 		break;
896 	case 0x170:
897 		sdev->idno = 'D';
898 		nonlegacy = 'E';
899 		break;
900 	}
901 	sdev->ifc = &sdataifc;
902 	sdev->ctlr = ctlr;
903 	sdev->nunit = 2;
904 	ctlr->sdev = sdev;
905 
906 	return sdev;
907 }
908 
909 static void
910 ataclear(SDev *sdev)
911 {
912 	Ctlr* ctlr;
913 
914 	ctlr = sdev->ctlr;
915 	iofree(ctlr->cmdport);
916 	iofree(ctlr->ctlport + As);
917 
918 	if (ctlr->drive[0])
919 		free(ctlr->drive[0]);
920 	if (ctlr->drive[1])
921 		free(ctlr->drive[1]);
922 	if (sdev->name)
923 		free(sdev->name);
924 	if (sdev->unitflg)
925 		free(sdev->unitflg);
926 	if (sdev->unit)
927 		free(sdev->unit);
928 	free(ctlr);
929 	free(sdev);
930 }
931 
932 static char *
933 atastat(SDev *sdev, char *p, char *e)
934 {
935 	Ctlr *ctlr = sdev->ctlr;
936 
937 	return seprint(p, e, "%s ata port %X ctl %X irq %d\n",
938 		    	       sdev->name, ctlr->cmdport, ctlr->ctlport, ctlr->irq);
939 }
940 
941 static SDev*
942 ataprobew(DevConf *cf)
943 {
944 	char *p;
945 	ISAConf isa;
946 
947 	if (cf->nports != 2)
948 		error(Ebadarg);
949 
950 	memset(&isa, 0, sizeof isa);
951 	isa.port = cf->ports[0].port;
952 	isa.irq = cf->intnum;
953 	if((p=strchr(cf->type, '/')) == nil || pcmspecial(p+1, &isa) < 0)
954 		error("cannot find controller");
955 
956 	return ataprobe(cf->ports[0].port, cf->ports[1].port, cf->intnum);
957 }
958 
959 /*
960  * These are duplicated with sdsetsense, etc., in devsd.c, but
961  * those assume that the disk is not SCSI while in fact here
962  * ata drives are not SCSI but ATAPI ones kind of are.
963  */
964 static int
965 atasetsense(Drive* drive, int status, int key, int asc, int ascq)
966 {
967 	drive->sense[2] = key;
968 	drive->sense[12] = asc;
969 	drive->sense[13] = ascq;
970 
971 	return status;
972 }
973 
974 static int
975 atamodesense(Drive* drive, uchar* cmd)
976 {
977 	int len;
978 
979 	/*
980 	 * Fake a vendor-specific request with page code 0,
981 	 * return the drive info.
982 	 */
983 	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
984 		return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
985 	len = (cmd[7]<<8)|cmd[8];
986 	if(len == 0)
987 		return SDok;
988 	if(len < 8+sizeof(drive->info))
989 		return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
990 	if(drive->data == nil || drive->dlen < len)
991 		return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
992 	memset(drive->data, 0, 8);
993 	drive->data[0] = sizeof(drive->info)>>8;
994 	drive->data[1] = sizeof(drive->info);
995 	memmove(drive->data+8, drive->info, sizeof(drive->info));
996 	drive->data += 8+sizeof(drive->info);
997 
998 	return SDok;
999 }
1000 
1001 static int
1002 atastandby(Drive* drive, int period)
1003 {
1004 	Ctlr* ctlr;
1005 	int cmdport, done;
1006 
1007 	ctlr = drive->ctlr;
1008 	drive->command = Cstandby;
1009 	qlock(ctlr);
1010 
1011 	cmdport = ctlr->cmdport;
1012 	ilock(ctlr);
1013 	outb(cmdport+Count, period);
1014 	outb(cmdport+Dh, drive->dev);
1015 	ctlr->done = 0;
1016 	ctlr->curdrive = drive;
1017 	ctlr->command = Cstandby;	/* debugging */
1018 	outb(cmdport+Command, Cstandby);
1019 	iunlock(ctlr);
1020 
1021 	while(waserror())
1022 		;
1023 	tsleep(ctlr, atadone, ctlr, 60*1000);
1024 	poperror();
1025 
1026 	done = ctlr->done;
1027 	qunlock(ctlr);
1028 
1029 	if(!done || (drive->status & Err))
1030 		return atasetsense(drive, SDcheck, 4, 8, drive->error);
1031 	return SDok;
1032 }
1033 
1034 static void
1035 atanop(Drive* drive, int subcommand)
1036 {
1037 	Ctlr* ctlr;
1038 	int as, cmdport, ctlport, timeo;
1039 
1040 	/*
1041 	 * Attempt to abort a command by using NOP.
1042 	 * In response, the drive is supposed to set Abrt
1043 	 * in the Error register, set (Drdy|Err) in Status
1044 	 * and clear Bsy when done. However, some drives
1045 	 * (e.g. ATAPI Zip) just go Bsy then clear Status
1046 	 * when done, hence the timeout loop only on Bsy
1047 	 * and the forced setting of drive->error.
1048 	 */
1049 	ctlr = drive->ctlr;
1050 	cmdport = ctlr->cmdport;
1051 	outb(cmdport+Features, subcommand);
1052 	outb(cmdport+Dh, drive->dev);
1053 	ctlr->command = Cnop;		/* debugging */
1054 	outb(cmdport+Command, Cnop);
1055 
1056 	microdelay(1);
1057 	ctlport = ctlr->ctlport;
1058 	for(timeo = 0; timeo < 1000; timeo++){
1059 		as = inb(ctlport+As);
1060 		if(!(as & Bsy))
1061 			break;
1062 		microdelay(1);
1063 	}
1064 	drive->error |= Abrt;
1065 }
1066 
1067 static void
1068 ataabort(Drive* drive, int dolock)
1069 {
1070 	/*
1071 	 * If NOP is available (packet commands) use it otherwise
1072 	 * must try a software reset.
1073 	 */
1074 	if(dolock)
1075 		ilock(drive->ctlr);
1076 	if(drive->info[Icsfs] & Mnop)
1077 		atanop(drive, 0);
1078 	else{
1079 		atasrst(drive->ctlr->ctlport);
1080 		drive->error |= Abrt;
1081 	}
1082 	if(dolock)
1083 		iunlock(drive->ctlr);
1084 }
1085 
1086 static int
1087 atadmasetup(Drive* drive, int len)
1088 {
1089 	Prd *prd;
1090 	ulong pa;
1091 	Ctlr *ctlr;
1092 	int bmiba, bmisx, count, i, span;
1093 
1094 	ctlr = drive->ctlr;
1095 	pa = PCIWADDR(drive->data);
1096 	if(pa & 0x03)
1097 		return -1;
1098 
1099 	/*
1100 	 * Sometimes drives identify themselves as being DMA capable
1101 	 * although they are not on a busmastering controller.
1102 	 */
1103 	prd = ctlr->prdt;
1104 	if(prd == nil){
1105 		drive->dmactl = 0;
1106 		print("disabling dma: not on a busmastering controller\n");
1107 		return -1;
1108 	}
1109 
1110 	for(i = 0; len && i < Nprd; i++){
1111 		prd->pa = pa;
1112 		span = ROUNDUP(pa, ctlr->span);
1113 		if(span == pa)
1114 			span += ctlr->span;
1115 		count = span - pa;
1116 		if(count >= len){
1117 			prd->count = PrdEOT|len;
1118 			break;
1119 		}
1120 		prd->count = count;
1121 		len -= count;
1122 		pa += count;
1123 		prd++;
1124 	}
1125 	if(i == Nprd)
1126 		(prd-1)->count |= PrdEOT;
1127 
1128 	bmiba = ctlr->bmiba;
1129 	outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
1130 	if(drive->write)
1131 		outb(ctlr->bmiba+Bmicx, 0);
1132 	else
1133 		outb(ctlr->bmiba+Bmicx, Rwcon);
1134 	bmisx = inb(bmiba+Bmisx);
1135 	outb(bmiba+Bmisx, bmisx|Ideints|Idedmae);
1136 
1137 	return 0;
1138 }
1139 
1140 static void
1141 atadmastart(Ctlr* ctlr, int write)
1142 {
1143 	if(write)
1144 		outb(ctlr->bmiba+Bmicx, Ssbm);
1145 	else
1146 		outb(ctlr->bmiba+Bmicx, Rwcon|Ssbm);
1147 }
1148 
1149 static int
1150 atadmastop(Ctlr* ctlr)
1151 {
1152 	int bmiba;
1153 
1154 	bmiba = ctlr->bmiba;
1155 	outb(bmiba+Bmicx, inb(bmiba+Bmicx) & ~Ssbm);
1156 
1157 	return inb(bmiba+Bmisx);
1158 }
1159 
1160 static void
1161 atadmainterrupt(Drive* drive, int count)
1162 {
1163 	Ctlr* ctlr;
1164 	int bmiba, bmisx;
1165 
1166 	ctlr = drive->ctlr;
1167 	bmiba = ctlr->bmiba;
1168 	bmisx = inb(bmiba+Bmisx);
1169 	switch(bmisx & (Ideints|Idedmae|Bmidea)){
1170 	case Bmidea:
1171 		/*
1172 		 * Data transfer still in progress, nothing to do
1173 		 * (this should never happen).
1174 		 */
1175 		return;
1176 
1177 	case Ideints:
1178 	case Ideints|Bmidea:
1179 		/*
1180 		 * Normal termination, tidy up.
1181 		 */
1182 		drive->data += count;
1183 		break;
1184 
1185 	default:
1186 		/*
1187 		 * What's left are error conditions (memory transfer
1188 		 * problem) and the device is not done but the PRD is
1189 		 * exhausted. For both cases must somehow tell the
1190 		 * drive to abort.
1191 		 */
1192 		ataabort(drive, 0);
1193 		break;
1194 	}
1195 	atadmastop(ctlr);
1196 	ctlr->done = 1;
1197 }
1198 
1199 static void
1200 atapktinterrupt(Drive* drive)
1201 {
1202 	Ctlr* ctlr;
1203 	int cmdport, len;
1204 
1205 	ctlr = drive->ctlr;
1206 	cmdport = ctlr->cmdport;
1207 	switch(inb(cmdport+Ir) & (/*Rel|*/Io|Cd)){
1208 	case Cd:
1209 		outss(cmdport+Data, drive->pktcmd, drive->pkt/2);
1210 		break;
1211 
1212 	case 0:
1213 		len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
1214 		if(drive->data+len > drive->limit){
1215 			atanop(drive, 0);
1216 			break;
1217 		}
1218 		outss(cmdport+Data, drive->data, len/2);
1219 		drive->data += len;
1220 		break;
1221 
1222 	case Io:
1223 		len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
1224 		if(drive->data+len > drive->limit){
1225 			atanop(drive, 0);
1226 			break;
1227 		}
1228 		inss(cmdport+Data, drive->data, len/2);
1229 		drive->data += len;
1230 		break;
1231 
1232 	case Io|Cd:
1233 		if(drive->pktdma)
1234 			atadmainterrupt(drive, drive->dlen);
1235 		else
1236 			ctlr->done = 1;
1237 		break;
1238 	}
1239 }
1240 
1241 static int
1242 atapktio(Drive* drive, uchar* cmd, int clen)
1243 {
1244 	Ctlr *ctlr;
1245 	int as, cmdport, ctlport, len, r, timeo;
1246 
1247 	if(cmd[0] == 0x5A && (cmd[2] & 0x3F) == 0)
1248 		return atamodesense(drive, cmd);
1249 
1250 	r = SDok;
1251 
1252 	drive->command = Cpkt;
1253 	memmove(drive->pktcmd, cmd, clen);
1254 	memset(drive->pktcmd+clen, 0, drive->pkt-clen);
1255 	drive->limit = drive->data+drive->dlen;
1256 
1257 	ctlr = drive->ctlr;
1258 	cmdport = ctlr->cmdport;
1259 	ctlport = ctlr->ctlport;
1260 
1261 	qlock(ctlr);
1262 
1263 	as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 107*1000);
1264 	/* used to test as&Chk as failure too, but some CD readers use that for media change */
1265 	if(as < 0){
1266 		qunlock(ctlr);
1267 		return -1;
1268 	}
1269 
1270 	ilock(ctlr);
1271 	if(drive->dlen && drive->dmactl && !atadmasetup(drive, drive->dlen))
1272 		drive->pktdma = Dma;
1273 	else
1274 		drive->pktdma = 0;
1275 
1276 	outb(cmdport+Features, drive->pktdma);
1277 	outb(cmdport+Count, 0);
1278 	outb(cmdport+Sector, 0);
1279 	len = 16*drive->secsize;
1280 	outb(cmdport+Bytelo, len);
1281 	outb(cmdport+Bytehi, len>>8);
1282 	outb(cmdport+Dh, drive->dev);
1283 	ctlr->done = 0;
1284 	ctlr->curdrive = drive;
1285 	ctlr->command = Cpkt;		/* debugging */
1286 	if(drive->pktdma)
1287 		atadmastart(ctlr, drive->write);
1288 	outb(cmdport+Command, Cpkt);
1289 
1290 	if((drive->info[Iconfig] & Mdrq) != 0x0020){
1291 		microdelay(1);
1292 		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
1293 		if(as < 0 || (as & (Bsy|Chk))){
1294 			drive->status = as<0 ? 0 : as;
1295 			ctlr->curdrive = nil;
1296 			ctlr->done = 1;
1297 			r = SDtimeout;
1298 		}else
1299 			atapktinterrupt(drive);
1300 	}
1301 	iunlock(ctlr);
1302 
1303 	while(waserror())
1304 		;
1305 	if(!drive->pktdma)
1306 		sleep(ctlr, atadone, ctlr);
1307 	else for(timeo = 0; !ctlr->done; timeo++){
1308 		tsleep(ctlr, atadone, ctlr, 1000);
1309 		if(ctlr->done)
1310 			break;
1311 		ilock(ctlr);
1312 		atadmainterrupt(drive, 0);
1313 		if(!drive->error && timeo > 20){
1314 			ataabort(drive, 0);
1315 			atadmastop(ctlr);
1316 			drive->dmactl = 0;
1317 			drive->error |= Abrt;
1318 		}
1319 		if(drive->error){
1320 			drive->status |= Chk;
1321 			ctlr->curdrive = nil;
1322 		}
1323 		iunlock(ctlr);
1324 	}
1325 	poperror();
1326 
1327 	qunlock(ctlr);
1328 
1329 	if(drive->status & Chk)
1330 		r = SDcheck;
1331 
1332 	return r;
1333 }
1334 
1335 static uchar cmd48[256] = {
1336 	[Crs]	Crs48,
1337 	[Crd]	Crd48,
1338 	[Crdq]	Crdq48,
1339 	[Crsm]	Crsm48,
1340 	[Cws]	Cws48,
1341 	[Cwd]	Cwd48,
1342 	[Cwdq]	Cwdq48,
1343 	[Cwsm]	Cwsm48,
1344 };
1345 
1346 static int
1347 atageniostart(Drive* drive, vlong lba)
1348 {
1349 	Ctlr *ctlr;
1350 	uchar cmd;
1351 	int as, c, cmdport, ctlport, h, len, s, use48;
1352 
1353 	use48 = 0;
1354 	if((drive->flags&Lba48always) || (lba>>28) || drive->count > 256){
1355 		if(!(drive->flags & Lba48))
1356 			return -1;
1357 		use48 = 1;
1358 		c = h = s = 0;
1359 	}
1360 	else if(drive->dev & Lba){
1361 		c = (lba>>8) & 0xFFFF;
1362 		h = (lba>>24) & 0x0F;
1363 		s = lba & 0xFF;
1364 	}
1365 	else{
1366 		c = lba/(drive->s*drive->h);
1367 		h = ((lba/drive->s) % drive->h);
1368 		s = (lba % drive->s) + 1;
1369 	}
1370 
1371 	ctlr = drive->ctlr;
1372 	cmdport = ctlr->cmdport;
1373 	ctlport = ctlr->ctlport;
1374 	if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 101*1000) < 0)
1375 		return -1;
1376 
1377 	ilock(ctlr);
1378 	if(drive->dmactl && !atadmasetup(drive, drive->count*drive->secsize)){
1379 		if(drive->write)
1380 			drive->command = Cwd;
1381 		else
1382 			drive->command = Crd;
1383 	}
1384 	else if(drive->rwmctl){
1385 		drive->block = drive->rwm*drive->secsize;
1386 		if(drive->write)
1387 			drive->command = Cwsm;
1388 		else
1389 			drive->command = Crsm;
1390 	}
1391 	else{
1392 		drive->block = drive->secsize;
1393 		if(drive->write)
1394 			drive->command = Cws;
1395 		else
1396 			drive->command = Crs;
1397 	}
1398 	drive->limit = drive->data + drive->count*drive->secsize;
1399 	cmd = drive->command;
1400 	if(use48){
1401 		outb(cmdport+Count, (drive->count>>8) & 0xFF);
1402 		outb(cmdport+Count, drive->count & 0XFF);
1403 		outb(cmdport+Lbalo, (lba>>24) & 0xFF);
1404 		outb(cmdport+Lbalo, lba & 0xFF);
1405 		outb(cmdport+Lbamid, (lba>>32) & 0xFF);
1406 		outb(cmdport+Lbamid, (lba>>8) & 0xFF);
1407 		outb(cmdport+Lbahi, (lba>>40) & 0xFF);
1408 		outb(cmdport+Lbahi, (lba>>16) & 0xFF);
1409 		outb(cmdport+Dh, drive->dev|Lba);
1410 		cmd = cmd48[cmd];
1411 
1412 		if(DEBUG & Dbg48BIT)
1413 			print("using 48-bit commands\n");
1414 	}
1415 	else{
1416 		outb(cmdport+Count, drive->count);
1417 		outb(cmdport+Sector, s);
1418 		outb(cmdport+Cyllo, c);
1419 		outb(cmdport+Cylhi, c>>8);
1420 		outb(cmdport+Dh, drive->dev|h);
1421 	}
1422 	ctlr->done = 0;
1423 	ctlr->curdrive = drive;
1424 	ctlr->command = drive->command;	/* debugging */
1425 	outb(cmdport+Command, cmd);
1426 
1427 	switch(drive->command){
1428 	case Cws:
1429 	case Cwsm:
1430 		microdelay(1);
1431 		/* 10*1000 for flash ide drives - maybe detect them? */
1432 		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 10*1000);
1433 		if(as < 0 || (as & Err)){
1434 			iunlock(ctlr);
1435 			return -1;
1436 		}
1437 		len = drive->block;
1438 		if(drive->data+len > drive->limit)
1439 			len = drive->limit-drive->data;
1440 		outss(cmdport+Data, drive->data, len/2);
1441 		break;
1442 
1443 	case Crd:
1444 	case Cwd:
1445 		atadmastart(ctlr, drive->write);
1446 		break;
1447 	}
1448 	iunlock(ctlr);
1449 
1450 	return 0;
1451 }
1452 
1453 static int
1454 atagenioretry(Drive* drive)
1455 {
1456 	if(drive->dmactl){
1457 		drive->dmactl = 0;
1458 		print("atagenioretry: disabling dma\n");
1459 	}
1460 	else if(drive->rwmctl)
1461 		drive->rwmctl = 0;
1462 	else
1463 		return atasetsense(drive, SDcheck, 4, 8, drive->error);
1464 
1465 	return SDretry;
1466 }
1467 
1468 static int
1469 atagenio(Drive* drive, uchar* cmd, int)
1470 {
1471 	uchar *p;
1472 	Ctlr *ctlr;
1473 	vlong lba, len;
1474 	int count, maxio;
1475 
1476 	/*
1477 	 * Map SCSI commands into ATA commands for discs.
1478 	 * Fail any command with a LUN except INQUIRY which
1479 	 * will return 'logical unit not supported'.
1480 	 */
1481 	if((cmd[1]>>5) && cmd[0] != 0x12)
1482 		return atasetsense(drive, SDcheck, 0x05, 0x25, 0);
1483 
1484 	switch(cmd[0]){
1485 	default:
1486 		return atasetsense(drive, SDcheck, 0x05, 0x20, 0);
1487 
1488 	case 0x00:			/* test unit ready */
1489 		return SDok;
1490 
1491 	case 0x03:			/* request sense */
1492 		if(cmd[4] < sizeof(drive->sense))
1493 			len = cmd[4];
1494 		else
1495 			len = sizeof(drive->sense);
1496 		if(drive->data && drive->dlen >= len){
1497 			memmove(drive->data, drive->sense, len);
1498 			drive->data += len;
1499 		}
1500 		return SDok;
1501 
1502 	case 0x12:			/* inquiry */
1503 		if(cmd[4] < sizeof(drive->inquiry))
1504 			len = cmd[4];
1505 		else
1506 			len = sizeof(drive->inquiry);
1507 		if(drive->data && drive->dlen >= len){
1508 			memmove(drive->data, drive->inquiry, len);
1509 			drive->data += len;
1510 		}
1511 		return SDok;
1512 
1513 	case 0x1B:			/* start/stop unit */
1514 		/*
1515 		 * NOP for now, can use the power management feature
1516 		 * set later.
1517 		 */
1518 		return SDok;
1519 
1520 	case 0x25:			/* read capacity */
1521 		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1522 			return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1523 		if(drive->data == nil || drive->dlen < 8)
1524 			return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1525 		/*
1526 		 * Read capacity returns the LBA of the last sector.
1527 		 */
1528 		len = drive->sectors-1;
1529 		p = drive->data;
1530 		*p++ = len>>24;
1531 		*p++ = len>>16;
1532 		*p++ = len>>8;
1533 		*p++ = len;
1534 		len = drive->secsize;
1535 		*p++ = len>>24;
1536 		*p++ = len>>16;
1537 		*p++ = len>>8;
1538 		*p = len;
1539 		drive->data += 8;
1540 		return SDok;
1541 
1542 	case 0x9E:			/* long read capacity */
1543 		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1544 			return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1545 		if(drive->data == nil || drive->dlen < 8)
1546 			return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1547 		/*
1548 		 * Read capacity returns the LBA of the last sector.
1549 		 */
1550 		len = drive->sectors-1;
1551 		p = drive->data;
1552 		*p++ = len>>56;
1553 		*p++ = len>>48;
1554 		*p++ = len>>40;
1555 		*p++ = len>>32;
1556 		*p++ = len>>24;
1557 		*p++ = len>>16;
1558 		*p++ = len>>8;
1559 		*p++ = len;
1560 		len = drive->secsize;
1561 		*p++ = len>>24;
1562 		*p++ = len>>16;
1563 		*p++ = len>>8;
1564 		*p = len;
1565 		drive->data += 12;
1566 		return SDok;
1567 
1568 	case 0x28:			/* read */
1569 	case 0x2A:			/* write */
1570 		break;
1571 
1572 	case 0x5A:
1573 		return atamodesense(drive, cmd);
1574 	}
1575 
1576 	ctlr = drive->ctlr;
1577 	lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
1578 	count = (cmd[7]<<8)|cmd[8];
1579 	if(drive->data == nil)
1580 		return SDok;
1581 	if(drive->dlen < count*drive->secsize)
1582 		count = drive->dlen/drive->secsize;
1583 	qlock(ctlr);
1584 	if(ctlr->maxio)
1585 		maxio = ctlr->maxio;
1586 	else if(drive->flags & Lba48)
1587 		maxio = 65536;
1588 	else
1589 		maxio = 256;
1590 	while(count){
1591 		if(count > maxio)
1592 			drive->count = maxio;
1593 		else
1594 			drive->count = count;
1595 		if(atageniostart(drive, lba)){
1596 			ilock(ctlr);
1597 			atanop(drive, 0);
1598 			iunlock(ctlr);
1599 			qunlock(ctlr);
1600 			return atagenioretry(drive);
1601 		}
1602 
1603 		while(waserror())
1604 			;
1605 		tsleep(ctlr, atadone, ctlr, 60*1000);
1606 		poperror();
1607 		if(!ctlr->done){
1608 			/*
1609 			 * What should the above timeout be? In
1610 			 * standby and sleep modes it could take as
1611 			 * long as 30 seconds for a drive to respond.
1612 			 * Very hard to get out of this cleanly.
1613 			 */
1614 			atadumpstate(drive, cmd, lba, count);
1615 			ataabort(drive, 1);
1616 			qunlock(ctlr);
1617 			return atagenioretry(drive);
1618 		}
1619 
1620 		if(drive->status & Err){
1621 			qunlock(ctlr);
1622 			return atasetsense(drive, SDcheck, 4, 8, drive->error);
1623 		}
1624 		count -= drive->count;
1625 		lba += drive->count;
1626 	}
1627 	qunlock(ctlr);
1628 
1629 	return SDok;
1630 }
1631 
1632 static int
1633 atario(SDreq* r)
1634 {
1635 	Ctlr *ctlr;
1636 	Drive *drive;
1637 	SDunit *unit;
1638 	uchar cmd10[10], *cmdp, *p;
1639 	int clen, reqstatus, status;
1640 
1641 	unit = r->unit;
1642 	if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil){
1643 		r->status = SDtimeout;
1644 		return SDtimeout;
1645 	}
1646 	drive = ctlr->drive[unit->subno];
1647 
1648 	/*
1649 	 * Most SCSI commands can be passed unchanged except for
1650 	 * the padding on the end. The few which require munging
1651 	 * are not used internally. Mode select/sense(6) could be
1652 	 * converted to the 10-byte form but it's not worth the
1653 	 * effort. Read/write(6) are easy.
1654 	 */
1655 	switch(r->cmd[0]){
1656 	case 0x08:			/* read */
1657 	case 0x0A:			/* write */
1658 		cmdp = cmd10;
1659 		memset(cmdp, 0, sizeof(cmd10));
1660 		cmdp[0] = r->cmd[0]|0x20;
1661 		cmdp[1] = r->cmd[1] & 0xE0;
1662 		cmdp[5] = r->cmd[3];
1663 		cmdp[4] = r->cmd[2];
1664 		cmdp[3] = r->cmd[1] & 0x0F;
1665 		cmdp[8] = r->cmd[4];
1666 		clen = sizeof(cmd10);
1667 		break;
1668 
1669 	default:
1670 		cmdp = r->cmd;
1671 		clen = r->clen;
1672 		break;
1673 	}
1674 
1675 	qlock(drive);
1676 retry:
1677 	drive->write = r->write;
1678 	drive->data = r->data;
1679 	drive->dlen = r->dlen;
1680 
1681 	drive->status = 0;
1682 	drive->error = 0;
1683 	if(drive->pkt)
1684 		status = atapktio(drive, cmdp, clen);
1685 	else
1686 		status = atagenio(drive, cmdp, clen);
1687 	if(status == SDretry){
1688 		if(DbgDEBUG)
1689 			print("%s: retry: dma %8.8uX rwm %4.4uX\n",
1690 				unit->name, drive->dmactl, drive->rwmctl);
1691 		goto retry;
1692 	}
1693 	if(status == SDok){
1694 		atasetsense(drive, SDok, 0, 0, 0);
1695 		if(drive->data){
1696 			p = r->data;
1697 			r->rlen = drive->data - p;
1698 		}
1699 		else
1700 			r->rlen = 0;
1701 	}
1702 	else if(status == SDcheck && !(r->flags & SDnosense)){
1703 		drive->write = 0;
1704 		memset(cmd10, 0, sizeof(cmd10));
1705 		cmd10[0] = 0x03;
1706 		cmd10[1] = r->lun<<5;
1707 		cmd10[4] = sizeof(r->sense)-1;
1708 		drive->data = r->sense;
1709 		drive->dlen = sizeof(r->sense)-1;
1710 		drive->status = 0;
1711 		drive->error = 0;
1712 		if(drive->pkt)
1713 			reqstatus = atapktio(drive, cmd10, 6);
1714 		else
1715 			reqstatus = atagenio(drive, cmd10, 6);
1716 		if(reqstatus == SDok){
1717 			r->flags |= SDvalidsense;
1718 			atasetsense(drive, SDok, 0, 0, 0);
1719 		}
1720 	}
1721 	qunlock(drive);
1722 	r->status = status;
1723 	if(status != SDok)
1724 		return status;
1725 
1726 	/*
1727 	 * Fix up any results.
1728 	 * Many ATAPI CD-ROMs ignore the LUN field completely and
1729 	 * return valid INQUIRY data. Patch the response to indicate
1730 	 * 'logical unit not supported' if the LUN is non-zero.
1731 	 */
1732 	switch(cmdp[0]){
1733 	case 0x12:			/* inquiry */
1734 		if((p = r->data) == nil)
1735 			break;
1736 		if((cmdp[1]>>5) && (!drive->pkt || (p[0] & 0x1F) == 0x05))
1737 			p[0] = 0x7F;
1738 		/*FALLTHROUGH*/
1739 	default:
1740 		break;
1741 	}
1742 
1743 	return SDok;
1744 }
1745 
1746 static void
1747 atainterrupt(Ureg*, void* arg)
1748 {
1749 	Ctlr *ctlr;
1750 	Drive *drive;
1751 	int cmdport, len, status;
1752 
1753 	ctlr = arg;
1754 
1755 	ilock(ctlr);
1756 	if(inb(ctlr->ctlport+As) & Bsy){
1757 		iunlock(ctlr);
1758 		if(DEBUG & DbgBsy)
1759 			print("IBsy+");
1760 		return;
1761 	}
1762 	cmdport = ctlr->cmdport;
1763 	status = inb(cmdport+Status);
1764 	if((drive = ctlr->curdrive) == nil){
1765 		iunlock(ctlr);
1766 		if((DEBUG & DbgINL) && ctlr->command != Cedd)
1767 			print("Inil%2.2uX+", ctlr->command);
1768 		return;
1769 	}
1770 
1771 	if(status & Err)
1772 		drive->error = inb(cmdport+Error);
1773 	else switch(drive->command){
1774 	default:
1775 		drive->error = Abrt;
1776 		break;
1777 
1778 	case Crs:
1779 	case Crsm:
1780 		if(!(status & Drq)){
1781 			drive->error = Abrt;
1782 			break;
1783 		}
1784 		len = drive->block;
1785 		if(drive->data+len > drive->limit)
1786 			len = drive->limit-drive->data;
1787 		inss(cmdport+Data, drive->data, len/2);
1788 		drive->data += len;
1789 		if(drive->data >= drive->limit)
1790 			ctlr->done = 1;
1791 		break;
1792 
1793 	case Cws:
1794 	case Cwsm:
1795 		len = drive->block;
1796 		if(drive->data+len > drive->limit)
1797 			len = drive->limit-drive->data;
1798 		drive->data += len;
1799 		if(drive->data >= drive->limit){
1800 			ctlr->done = 1;
1801 			break;
1802 		}
1803 		if(!(status & Drq)){
1804 			drive->error = Abrt;
1805 			break;
1806 		}
1807 		len = drive->block;
1808 		if(drive->data+len > drive->limit)
1809 			len = drive->limit-drive->data;
1810 		outss(cmdport+Data, drive->data, len/2);
1811 		break;
1812 
1813 	case Cpkt:
1814 		atapktinterrupt(drive);
1815 		break;
1816 
1817 	case Crd:
1818 	case Cwd:
1819 		atadmainterrupt(drive, drive->count*drive->secsize);
1820 		break;
1821 
1822 	case Cstandby:
1823 		ctlr->done = 1;
1824 		break;
1825 	}
1826 	iunlock(ctlr);
1827 
1828 	if(drive->error){
1829 		status |= Err;
1830 		ctlr->done = 1;
1831 	}
1832 
1833 	if(ctlr->done){
1834 		ctlr->curdrive = nil;
1835 		drive->status = status;
1836 		wakeup(ctlr);
1837 	}
1838 }
1839 
1840 static SDev*
1841 atapnp(void)
1842 {
1843 	Ctlr *ctlr;
1844 	Pcidev *p;
1845 	SDev *legacy[2], *sdev, *head, *tail;
1846 	int channel, ispc87415, maxio, pi, r, span;
1847 
1848 	legacy[0] = legacy[1] = head = tail = nil;
1849 	if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
1850 		head = tail = sdev;
1851 		legacy[0] = sdev;
1852 	}
1853 	if(sdev = ataprobe(0x170, 0x374, IrqATA1)){
1854 		if(head != nil)
1855 			tail->next = sdev;
1856 		else
1857 			head = sdev;
1858 		tail = sdev;
1859 		legacy[1] = sdev;
1860 	}
1861 
1862 	p = nil;
1863 	while(p = pcimatch(p, 0, 0)){
1864 		/*
1865 		 * Look for devices with the correct class and sub-class
1866 		 * code and known device and vendor ID; add native-mode
1867 		 * channels to the list to be probed, save info for the
1868 		 * compatibility mode channels.
1869 		 * Note that the legacy devices should not be considered
1870 		 * PCI devices by the interrupt controller.
1871 		 * For both native and legacy, save info for busmastering
1872 		 * if capable.
1873 		 * Promise Ultra ATA/66 (PDC20262) appears to
1874 		 * 1) give a sub-class of 'other mass storage controller'
1875 		 *    instead of 'IDE controller', regardless of whether it's
1876 		 *    the only controller or not;
1877 		 * 2) put 0 in the programming interface byte (probably
1878 		 *    as a consequence of 1) above).
1879 		 * Sub-class code 0x04 is 'RAID controller', e.g. VIA VT8237.
1880 		 */
1881 		if(p->ccrb != 0x01)
1882 			continue;
1883 		if(p->ccru != 0x01 && p->ccru != 0x04 && p->ccru != 0x80)
1884 			continue;
1885 		pi = p->ccrp;
1886 		ispc87415 = 0;
1887 		maxio = 0;
1888 		span = BMspan;
1889 
1890 		switch((p->did<<16)|p->vid){
1891 		default:
1892 			continue;
1893 
1894 		case (0x0002<<16)|0x100B:	/* NS PC87415 */
1895 			/*
1896 			 * Disable interrupts on both channels until
1897 			 * after they are probed for drives.
1898 			 * This must be called before interrupts are
1899 			 * enabled because the IRQ may be shared.
1900 			 */
1901 			ispc87415 = 1;
1902 			pcicfgw32(p, 0x40, 0x00000300);
1903 			break;
1904 		case (0x1000<<16)|0x1042:	/* PC-Tech RZ1000 */
1905 			/*
1906 			 * Turn off prefetch. Overkill, but cheap.
1907 			 */
1908 			r = pcicfgr32(p, 0x40);
1909 			r &= ~0x2000;
1910 			pcicfgw32(p, 0x40, r);
1911 			break;
1912 		case (0x4D38<<16)|0x105A:	/* Promise PDC20262 */
1913 		case (0x4D30<<16)|0x105A:	/* Promise PDC202xx */
1914 		case (0x4D68<<16)|0x105A:	/* Promise PDC20268 */
1915 		case (0x4D69<<16)|0x105A:	/* Promise Ultra/133 TX2 */
1916 		case (0x3373<<16)|0x105A:	/* Promise 20378 RAID */
1917 		case (0x3149<<16)|0x1106:	/* VIA VT8237 SATA/RAID */
1918 		case (0x4379<<16)|0x1002:	/* ATI 4379 SATA*/
1919 		case (0x3112<<16)|0x1095:	/* SiI 3112 SATA/RAID */
1920 			maxio = 15;
1921 			span = 8*1024;
1922 			/*FALLTHROUGH*/
1923 		case (0x3114<<16)|0x1095:	/* SiI 3114 SATA/RAID */
1924 			pi = 0x85;
1925 			break;
1926 		case (0x0004<<16)|0x1103:	/* HighPoint HPT366 */
1927 			pi = 0x85;
1928 			/*
1929 			 * Turn off fast interrupt prediction.
1930 			 */
1931 			if((r = pcicfgr8(p, 0x51)) & 0x80)
1932 				pcicfgw8(p, 0x51, r & ~0x80);
1933 			if((r = pcicfgr8(p, 0x55)) & 0x80)
1934 				pcicfgw8(p, 0x55, r & ~0x80);
1935 			break;
1936 		case (0x0640<<16)|0x1095:	/* CMD 640B */
1937 			/*
1938 			 * Bugfix code here...
1939 			 */
1940 			break;
1941 		case (0x7441<<16)|0x1022:	/* AMD 768 */
1942 			/*
1943 			 * Set:
1944 			 *	0x41	prefetch, postwrite;
1945 			 *	0x43	FIFO configuration 1/2 and 1/2;
1946 			 *	0x44	status register read retry;
1947 			 *	0x46	DMA read and end of sector flush.
1948 			 */
1949 			r = pcicfgr8(p, 0x41);
1950 			pcicfgw8(p, 0x41, r|0xF0);
1951 			r = pcicfgr8(p, 0x43);
1952 			pcicfgw8(p, 0x43, (r & 0x90)|0x2A);
1953 			r = pcicfgr8(p, 0x44);
1954 			pcicfgw8(p, 0x44, r|0x08);
1955 			r = pcicfgr8(p, 0x46);
1956 			pcicfgw8(p, 0x46, (r & 0x0C)|0xF0);
1957 			/*FALLTHROUGH*/
1958 		case (0x7401<<16)|0x1022:	/* AMD 755 Cobra */
1959 		case (0x7409<<16)|0x1022:	/* AMD 756 Viper */
1960 		case (0x7410<<16)|0x1022:	/* AMD 766 Viper Plus */
1961 		case (0x7469<<16)|0x1022:	/* AMD 3111 */
1962 			/*
1963 			 * This can probably be lumped in with the 768 above.
1964 			 */
1965 			/*FALLTHROUGH*/
1966 		case (0x209A<<16)|0x1022:	/* AMD CS5536 */
1967 		case (0x01BC<<16)|0x10DE:	/* nVidia nForce1 */
1968 		case (0x0065<<16)|0x10DE:	/* nVidia nForce2 */
1969 		case (0x0085<<16)|0x10DE:	/* nVidia nForce2 MCP */
1970 		case (0x00E3<<16)|0x10DE:	/* nVidia nForce2 250 SATA */
1971 		case (0x00D5<<16)|0x10DE:	/* nVidia nForce3 */
1972 		case (0x00E5<<16)|0x10DE:	/* nVidia nForce3 Pro */
1973 		case (0x00EE<<16)|0x10DE:	/* nVidia nForce3 250 SATA */
1974 		case (0x0035<<16)|0x10DE:	/* nVidia nForce3 MCP */
1975 		case (0x0053<<16)|0x10DE:	/* nVidia nForce4 */
1976 		case (0x0054<<16)|0x10DE:	/* nVidia nForce4 SATA */
1977 		case (0x0055<<16)|0x10DE:	/* nVidia nForce4 SATA */
1978 		case (0x0266<<16)|0x10DE:	/* nVidia nForce4 430 SATA */
1979 		case (0x0267<<16)|0x10DE:	/* nVidia nForce 55 MCP SATA */
1980 		case (0x03EC<<16)|0x10DE:	/* nVidia nForce 61 MCP SATA */
1981 		case (0x0448<<16)|0x10DE:	/* nVidia nForce 65 MCP SATA */
1982 		case (0x0560<<16)|0x10DE:	/* nVidia nForce 69 MCP SATA */
1983 			/*
1984 			 * Ditto, although it may have a different base
1985 			 * address for the registers (0x50?).
1986 			 */
1987 			/*FALLTHROUGH*/
1988 		case (0x1002<<16)|0x4372:	/* ATI SB400 */
1989 		case (0x4376<<16)|0x1002:	/* ATI Radeon Xpress 200M */
1990 			break;
1991 		case (0x0211<<16)|0x1166:	/* ServerWorks IB6566 */
1992 			{
1993 				Pcidev *sb;
1994 
1995 				sb = pcimatch(nil, 0x1166, 0x0200);
1996 				if(sb == nil)
1997 					break;
1998 				r = pcicfgr32(sb, 0x64);
1999 				r &= ~0x2000;
2000 				pcicfgw32(sb, 0x64, r);
2001 			}
2002 			span = 32*1024;
2003 			break;
2004 		case (0x5229<<16)|0x10B9:	/* ALi M1543 */
2005 		case (0x5288<<16)|0x10B9:	/* ALi M5288 SATA */
2006 			/*FALLTHROUGH*/
2007 		case (0x5513<<16)|0x1039:	/* SiS 962 */
2008 		case (0x0646<<16)|0x1095:	/* CMD 646 */
2009 		case (0x0571<<16)|0x1106:	/* VIA 82C686 */
2010 		case (0x1230<<16)|0x8086:	/* 82371FB (PIIX) */
2011 		case (0x7010<<16)|0x8086:	/* 82371SB (PIIX3) */
2012 		case (0x7111<<16)|0x8086:	/* 82371[AE]B (PIIX4[E]) */
2013 		case (0x2411<<16)|0x8086:	/* 82801AA (ICH) */
2014 		case (0x2421<<16)|0x8086:	/* 82801AB (ICH0) */
2015 		case (0x244A<<16)|0x8086:	/* 82801BA (ICH2, Mobile) */
2016 		case (0x244B<<16)|0x8086:	/* 82801BA (ICH2, High-End) */
2017 		case (0x248A<<16)|0x8086:	/* 82801CA (ICH3, Mobile) */
2018 		case (0x248B<<16)|0x8086:	/* 82801CA (ICH3, High-End) */
2019 		case (0x24CA<<16)|0x8086:	/* 82801DBM (ICH4, Mobile) */
2020 		case (0x24CB<<16)|0x8086:	/* 82801DB (ICH4, High-End) */
2021 		case (0x24DB<<16)|0x8086:	/* 82801EB (ICH5) */
2022 		case (0x25A3<<16)|0x8086:	/* 6300ESB (E7210) */
2023 		case (0x266F<<16)|0x8086:	/* 82801FB (ICH6) */
2024 		case (0x27DF<<16)|0x8086:	/* 82801G SATA (ICH7) */
2025 		case (0x27C0<<16)|0x8086:	/* 82801GB SATA AHCI (ICH7) */
2026 //		case (0x27C4<<16)|0x8086:	/* 82801GBM SATA (ICH7) */
2027 		case (0x27C5<<16)|0x8086:	/* 82801GBM SATA AHCI (ICH7) */
2028 		case (0x2920<<16)|0x8086:	/* 82801(IB)/IR/IH/IO SATA IDE (ICH9) */
2029 			break;
2030 		}
2031 
2032 		for(channel = 0; channel < 2; channel++){
2033 			if(pi & (1<<(2*channel))){
2034 				sdev = ataprobe(p->mem[0+2*channel].bar & ~0x01,
2035 						p->mem[1+2*channel].bar & ~0x01,
2036 						p->intl);
2037 				if(sdev == nil)
2038 					continue;
2039 
2040 				ctlr = sdev->ctlr;
2041 				if(ispc87415) {
2042 					ctlr->ienable = pc87415ienable;
2043 					print("pc87415disable: not yet implemented\n");
2044 				}
2045 
2046 				if(head != nil)
2047 					tail->next = sdev;
2048 				else
2049 					head = sdev;
2050 				tail = sdev;
2051 				ctlr->tbdf = p->tbdf;
2052 			}
2053 			else if((sdev = legacy[channel]) == nil)
2054 				continue;
2055 			else
2056 				ctlr = sdev->ctlr;
2057 
2058 			ctlr->pcidev = p;
2059 			ctlr->maxio = maxio;
2060 			ctlr->span = span;
2061 			if(!(pi & 0x80))
2062 				continue;
2063 			ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
2064 		}
2065 	}
2066 
2067 if(0){
2068 	int port;
2069 	ISAConf isa;
2070 
2071 	/*
2072 	 * Hack for PCMCIA drives.
2073 	 * This will be tidied once we figure out how the whole
2074 	 * removeable device thing is going to work.
2075 	 */
2076 	memset(&isa, 0, sizeof(isa));
2077 	isa.port = 0x180;		/* change this for your machine */
2078 	isa.irq = 11;			/* change this for your machine */
2079 
2080 	port = isa.port+0x0C;
2081 	channel = pcmspecial("MK2001MPL", &isa);
2082 	if(channel == -1)
2083 		channel = pcmspecial("SunDisk", &isa);
2084 	if(channel == -1){
2085 		isa.irq = 10;
2086 		channel = pcmspecial("CF", &isa);
2087 	}
2088 	if(channel == -1){
2089 		isa.irq = 10;
2090 		channel = pcmspecial("OLYMPUS", &isa);
2091 	}
2092 	if(channel == -1){
2093 		port = isa.port+0x204;
2094 		channel = pcmspecial("ATA/ATAPI", &isa);
2095 	}
2096 	if(channel >= 0 && (sdev = ataprobe(isa.port, port, isa.irq)) != nil){
2097 		if(head != nil)
2098 			tail->next = sdev;
2099 		else
2100 			head = sdev;
2101 	}
2102 }
2103 	return head;
2104 }
2105 
2106 static SDev*
2107 atalegacy(int port, int irq)
2108 {
2109 	return ataprobe(port, port+0x204, irq);
2110 }
2111 
2112 static int
2113 ataenable(SDev* sdev)
2114 {
2115 	Ctlr *ctlr;
2116 	char name[32];
2117 
2118 	ctlr = sdev->ctlr;
2119 
2120 	if(ctlr->bmiba){
2121 #define ALIGN	(4 * 1024)
2122 		if(ctlr->pcidev != nil)
2123 			pcisetbme(ctlr->pcidev);
2124 		ctlr->prdt = mallocalign(Nprd*sizeof(Prd), 4, 0, 4*1024);
2125 	}
2126 	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
2127 	intrenable(ctlr->irq, atainterrupt, ctlr, ctlr->tbdf, name);
2128 	outb(ctlr->ctlport+Dc, 0);
2129 	if(ctlr->ienable)
2130 		ctlr->ienable(ctlr);
2131 
2132 	return 1;
2133 }
2134 
2135 static int
2136 atadisable(SDev *sdev)
2137 {
2138 	Ctlr *ctlr;
2139 	char name[32];
2140 
2141 	ctlr = sdev->ctlr;
2142 	outb(ctlr->ctlport+Dc, Nien);		/* disable interrupts */
2143 	if (ctlr->idisable)
2144 		ctlr->idisable(ctlr);
2145 	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
2146 	intrdisable(ctlr->irq, atainterrupt, ctlr, ctlr->tbdf, name);
2147 	if (ctlr->bmiba) {
2148 		if (ctlr->pcidev)
2149 			pciclrbme(ctlr->pcidev);
2150 		free(ctlr->prdt);
2151 	}
2152 	return 0;
2153 }
2154 
2155 static int
2156 atarctl(SDunit* unit, char* p, int l)
2157 {
2158 	int n;
2159 	Ctlr *ctlr;
2160 	Drive *drive;
2161 
2162 	if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
2163 		return 0;
2164 	drive = ctlr->drive[unit->subno];
2165 
2166 	qlock(drive);
2167 	n = snprint(p, l, "config %4.4uX capabilities %4.4uX",
2168 		drive->info[Iconfig], drive->info[Icapabilities]);
2169 	if(drive->dma)
2170 		n += snprint(p+n, l-n, " dma %8.8uX dmactl %8.8uX",
2171 			drive->dma, drive->dmactl);
2172 	if(drive->rwm)
2173 		n += snprint(p+n, l-n, " rwm %ud rwmctl %ud",
2174 			drive->rwm, drive->rwmctl);
2175 	if(drive->flags&Lba48)
2176 		n += snprint(p+n, l-n, " lba48always %s",
2177 			(drive->flags&Lba48always) ? "on" : "off");
2178 	n += snprint(p+n, l-n, "\n");
2179 	if(drive->sectors){
2180 		n += snprint(p+n, l-n, "geometry %lld %d",
2181 			drive->sectors, drive->secsize);
2182 		if(drive->pkt == 0)
2183 			n += snprint(p+n, l-n, " %d %d %d",
2184 				drive->c, drive->h, drive->s);
2185 		n += snprint(p+n, l-n, "\n");
2186 	}
2187 	qunlock(drive);
2188 
2189 	return n;
2190 }
2191 
2192 static int
2193 atawctl(SDunit* unit, Cmdbuf* cb)
2194 {
2195 	int period;
2196 	Ctlr *ctlr;
2197 	Drive *drive;
2198 
2199 	if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
2200 		return 0;
2201 	drive = ctlr->drive[unit->subno];
2202 
2203 	qlock(drive);
2204 	if(waserror()){
2205 		qunlock(drive);
2206 		nexterror();
2207 	}
2208 
2209 	/*
2210 	 * Dma and rwm control is passive at the moment,
2211 	 * i.e. it is assumed that the hardware is set up
2212 	 * correctly already either by the BIOS or when
2213 	 * the drive was initially identified.
2214 	 */
2215 	if(strcmp(cb->f[0], "dma") == 0){
2216 		if(cb->nf != 2 || drive->dma == 0)
2217 			error(Ebadctl);
2218 		if(strcmp(cb->f[1], "on") == 0)
2219 			drive->dmactl = drive->dma;
2220 		else if(strcmp(cb->f[1], "off") == 0)
2221 			drive->dmactl = 0;
2222 		else
2223 			error(Ebadctl);
2224 	}
2225 	else if(strcmp(cb->f[0], "rwm") == 0){
2226 		if(cb->nf != 2 || drive->rwm == 0)
2227 			error(Ebadctl);
2228 		if(strcmp(cb->f[1], "on") == 0)
2229 			drive->rwmctl = drive->rwm;
2230 		else if(strcmp(cb->f[1], "off") == 0)
2231 			drive->rwmctl = 0;
2232 		else
2233 			error(Ebadctl);
2234 	}
2235 	else if(strcmp(cb->f[0], "standby") == 0){
2236 		switch(cb->nf){
2237 		default:
2238 			error(Ebadctl);
2239 		case 2:
2240 			period = strtol(cb->f[1], 0, 0);
2241 			if(period && (period < 30 || period > 240*5))
2242 				error(Ebadctl);
2243 			period /= 5;
2244 			break;
2245 		}
2246 		if(atastandby(drive, period) != SDok)
2247 			error(Ebadctl);
2248 	}
2249 	else if(strcmp(cb->f[0], "lba48always") == 0){
2250 		if(cb->nf != 2 || !(drive->flags&Lba48))
2251 			error(Ebadctl);
2252 		if(strcmp(cb->f[1], "on") == 0)
2253 			drive->flags |= Lba48always;
2254 		else if(strcmp(cb->f[1], "off") == 0)
2255 			drive->flags &= ~Lba48always;
2256 		else
2257 			error(Ebadctl);
2258 	}
2259 	else
2260 		error(Ebadctl);
2261 	qunlock(drive);
2262 	poperror();
2263 
2264 	return 0;
2265 }
2266 
2267 SDifc sdataifc = {
2268 	"ata",				/* name */
2269 
2270 	atapnp,				/* pnp */
2271 	atalegacy,			/* legacy */
2272 	ataenable,			/* enable */
2273 	atadisable,			/* disable */
2274 
2275 	scsiverify,			/* verify */
2276 	scsionline,			/* online */
2277 	atario,				/* rio */
2278 	atarctl,			/* rctl */
2279 	atawctl,			/* wctl */
2280 
2281 	scsibio,			/* bio */
2282 	ataprobew,			/* probe */
2283 	ataclear,			/* clear */
2284 	atastat,			/* rtopctl */
2285 	nil,				/* wtopctl */
2286 };
2287