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