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