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