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