Browse Source

Plan 9 from Bell Labs 2003-06-09

David du Colombier 21 years ago
parent
commit
a0c6e8c23f
8 changed files with 640 additions and 360 deletions
  1. 6 6
      dist/replica/plan9.db
  2. 7 0
      dist/replica/plan9.log
  3. 430 291
      sys/src/9/pc/etherigbe.c
  4. 1 0
      sys/src/9/pc/pc
  5. 1 0
      sys/src/9/pc/pccd
  6. 1 1
      sys/src/9/pc/pccpu
  7. 181 59
      sys/src/9/pc/sdata.c
  8. 13 3
      sys/src/9/pc/vganvidia.c

+ 6 - 6
dist/replica/plan9.db

@@ -5131,7 +5131,6 @@ sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1018386992 14056
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
 sys/src/9/pc/ether8139.c - 664 sys sys 1026847639 17884
-sys/src/9/pc/ether82543.c - 664 sys sys 1039803177 38406
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1032052916 32377
 sys/src/9/pc/ether82557.c - 664 sys sys 1032543589 29722
 sys/src/9/pc/ether83815.c - 664 sys sys 1026847640 23050
@@ -5142,6 +5141,7 @@ sys/src/9/pc/etherelnk3.c - 664 sys sys 1026847641 48003
 sys/src/9/pc/etherga620.c - 664 sys sys 1032052917 28786
 sys/src/9/pc/etherga620fw.h - 644 sys sys 1026847642 222295
 sys/src/9/pc/etherif.h - 664 sys sys 1045063564 961
+sys/src/9/pc/etherigbe.c - 664 sys sys 1055090142 42055
 sys/src/9/pc/ethermii.c - 664 sys sys 1039803177 4555
 sys/src/9/pc/ethermii.h - 664 sys sys 1039895684 3259
 sys/src/9/pc/ethersink.c - 664 sys sys 1048644103 1076
@@ -5165,10 +5165,10 @@ sys/src/9/pc/mmu.c - 664 sys sys 1049509456 10014
 sys/src/9/pc/mouse.c - 664 sys sys 1020369766 6315
 sys/src/9/pc/mp.c - 664 sys sys 1048644112 16928
 sys/src/9/pc/mp.h - 664 sys sys 1015014520 6575
-sys/src/9/pc/pc - 664 sys sys 1046359057 1316
+sys/src/9/pc/pc - 664 sys sys 1055090302 1340
 sys/src/9/pc/pcauth - 664 sys sys 1046359058 605
-sys/src/9/pc/pccd - 664 sys sys 1039753495 1278
-sys/src/9/pc/pccpu - 664 sys sys 1048644120 804
+sys/src/9/pc/pccd - 664 sys sys 1055090302 1302
+sys/src/9/pc/pccpu - 664 sys sys 1055090302 803
 sys/src/9/pc/pcdisk - 664 sys sys 1046359059 1374
 sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
 sys/src/9/pc/pcflop - 664 sys sys 1045500133 1386
@@ -5186,7 +5186,7 @@ sys/src/9/pc/screen.h - 664 sys sys 1048644129 3760
 sys/src/9/pc/sd53c8xx.c - 664 sys sys 1033134905 51568
 sys/src/9/pc/sd53c8xx.i - 664 sys sys 1045063730 27355
 sys/src/9/pc/sd53c8xx.n - 664 sys sys 1032059019 12455
-sys/src/9/pc/sdata.c - 664 sys sys 1054088388 46387
+sys/src/9/pc/sdata.c - 664 sys sys 1055087706 49704
 sys/src/9/pc/sdmylex.c - 664 sys sys 1015014523 27750
 sys/src/9/pc/sdscsi.c - 664 sys sys 1015014523 7412
 sys/src/9/pc/trap.c - 664 sys sys 1047261661 18991
@@ -5209,7 +5209,7 @@ sys/src/9/pc/vgamach64xx.c - 664 sys sys 1048644147 29112
 sys/src/9/pc/vgamga2164w.c - 664 sys sys 1015014527 5654
 sys/src/9/pc/vgamga4xx.c - 664 sys sys 1015014527 11122
 sys/src/9/pc/vganeomagic.c - 664 sys sys 1032375144 10693
-sys/src/9/pc/vganvidia.c - 664 sys sys 1048858211 6296
+sys/src/9/pc/vganvidia.c - 664 sys sys 1055090312 6543
 sys/src/9/pc/vgargb524.c - 664 sys sys 1015014527 4235
 sys/src/9/pc/vgas3.c - 664 sys sys 1048640451 12064
 sys/src/9/pc/vgasavage.c - 664 sys sys 1046203931 16194

+ 7 - 0
dist/replica/plan9.log

@@ -12039,3 +12039,10 @@
 1054551764 0 c 386/bin/aux/vga - 775 sys sys 1054551530 300312
 1054800131 0 c sys/src/9/bitsy/Booting101 - 664 sys sys 1054798506 8841
 1054926087 0 c 386/bin/upas/deliver - 775 sys sys 1054925546 97154
+1055088085 0 c sys/src/9/pc/sdata.c - 664 sys sys 1055087706 49704
+1055091688 0 a sys/src/9/pc/etherigbe.c - 664 sys sys 1055090142 42055
+1055091688 1 c sys/src/9/pc/pc - 664 sys sys 1055090302 1340
+1055091688 2 c sys/src/9/pc/pccpu - 664 sys sys 1055090302 803
+1055091688 3 c sys/src/9/pc/pccd - 664 sys sys 1055090302 1302
+1055091688 4 c sys/src/9/pc/vganvidia.c - 664 sys sys 1055090312 6543
+1055091688 5 d sys/src/9/pc/ether82543.c - 664 sys sys 1039803177 0

File diff suppressed because it is too large
+ 430 - 291
sys/src/9/pc/etherigbe.c


+ 1 - 0
sys/src/9/pc/pc

@@ -49,6 +49,7 @@ link
 	etherec2t	ether8390
 	etherelnk3	pci
 	etherga620	pci
+	etherigbe	pci ethermii
 	ethersink
 	ethersmc	devi82365 cis
 	etherwavelan	wavelan devi82365 cis pci

+ 1 - 0
sys/src/9/pc/pccd

@@ -45,6 +45,7 @@ link
 	etherec2t	ether8390
 	etherelnk3	pci
 	ether8139	pci
+	etherigbe	pci ethermii
 	ether82543gc	pci
 	etherga620	pci
 	ethersink

+ 1 - 1
sys/src/9/pc/pccpu

@@ -32,12 +32,12 @@ link
 	ether79c970	pci
 	ether8003	ether8390
 	ether8139	pci
-	ether82543	pci ethermii
 	ether82543gc	pci
 	ether82557	pci
 	ether83815	pci
 	etherelnk3	pci
 	etherga620	pci
+	etherigbe	pci ethermii
 	ethersink
 	ethermedium
 	loopbackmedium

+ 181 - 59
sys/src/9/pc/sdata.c

@@ -18,6 +18,7 @@ enum {
 	DbgPROBE	= 0x08,		/* trace device probing */
 	DbgDEBUG	= 0x80,		/* the current problem... */
 	DbgINL		= 0x100,	/* That Inil20+ message we hate */
+	Dbg48BIT	= 0x200,	/* 48-bit LBA */
 };
 #define DEBUG		(DbgDEBUG|DbgSTATE)
 
@@ -25,13 +26,16 @@ enum {					/* I/O ports */
 	Data		= 0,
 	Error		= 1,		/* (read) */
 	Features	= 1,		/* (write) */
-	Count		= 2,		/* sector count */
+	Count		= 2,		/* sector count<7-0>, sector count<15-8> */
 	Ir		= 2,		/* interrupt reason (PACKET) */
-	Sector		= 3,		/* sector number, LBA<7-0> */
-	Cyllo		= 4,		/* cylinder low, LBA<15-8> */
+	Sector		= 3,		/* sector number */
+	Lbalo		= 3,		/* LBA<7-0>, LBA<31-24> */
+	Cyllo		= 4,		/* cylinder low */
 	Bytelo		= 4,		/* byte count low (PACKET) */
-	Cylhi		= 5,		/* cylinder high, LBA<23-16> */
+	Lbamid		= 4,		/* LBA<15-8>, LBA<39-32> */
+	Cylhi		= 5,		/* cylinder high */
 	Bytehi		= 5,		/* byte count hi (PACKET) */
+	Lbahi		= 5,		/* LBA<23-16>, LBA<47-40> */
 	Dh		= 6,		/* Device/Head, LBA<32-14> */
 	Status		= 7,		/* (read) */
 	Command		= 7,		/* (write) */
@@ -57,9 +61,6 @@ enum {					/* Error */
 enum {					/* Features */
 	Dma		= 0x01,		/* data transfer via DMA (PACKET) */
 	Ovl		= 0x02,		/* command overlapped (PACKET) */
-
-	Lba48a	= 0x02,		/* first write of 48-bit LBA */
-	Lba48b	= 0x03,		/* second write of 48-bit LBA */
 };
 
 enum {					/* Interrupt Reason */
@@ -72,7 +73,11 @@ enum {					/* Device/Head */
 	Dev0		= 0xA0,		/* Master */
 	Dev1		= 0xB0,		/* Slave */
 	Lba		= 0x40,		/* LBA mode */
-	Lba48	= 0x100,		/* LBA48 mode (internal use only) */
+};
+
+enum {					/* internal flags */
+	Lba48		= 0x1,		/* LBA48 mode */
+	Lba48always	= 0x2,		/* ... */
 };
 
 enum {					/* Status, Alternate Status */
@@ -91,7 +96,15 @@ enum {					/* Command */
 	Cnop		= 0x00,		/* NOP */
 	Cdr		= 0x08,		/* Device Reset */
 	Crs		= 0x20,		/* Read Sectors */
+	Crs48		= 0x24,		/* Read Sectors Ext */
+	Crd48		= 0x25,		/* Read w/ DMA Ext */
+	Crdq48		= 0x26,		/* Read w/ DMA Queued Ext */
+	Crsm48		= 0x29,		/* Read Multiple Ext */
 	Cws		= 0x30,		/* Write Sectors */
+	Cws48		= 0x34,		/* Write Sectors Ext */
+	Cwd48		= 0x35,		/* Write w/ DMA Ext */
+	Cwdq48		= 0x36,		/* Write w/ DMA Queued Ext */
+	Cwsm48		= 0x39,		/* Write Multiple Ext */
 	Cedd		= 0x90,		/* Execute Device Diagnostics */
 	Cpkt		= 0xA0,		/* Packet */
 	Cidpkt		= 0xA1,		/* Identify Packet Device */
@@ -110,6 +123,7 @@ enum {					/* Command */
 enum {					/* Device Control */
 	Nien		= 0x02,		/* (not) Interrupt Enable */
 	Srst		= 0x04,		/* Software Reset */
+	Hob		= 0x80,		/* High Order Bit [sic] */
 };
 
 enum {					/* PCI Configuration Registers */
@@ -160,8 +174,7 @@ enum {					/* offsets into the identify info. */
 	Icsec		= 56,		/* sectors if (valid&0x01) */
 	Iccap		= 57,		/* capacity if (valid&0x01) */
 	Irwm		= 59,		/* read/write multiple */
-	Ilba0		= 60,		/* LBA size */
-	Ilba1		= 61,		/* LBA size */
+	Ilba		= 60,		/* LBA size */
 	Imwdma		= 63,		/* multiword DMA mode */
 	Iapiomode	= 64,		/* advanced PIO modes supported */
 	Iminmwdma	= 65,		/* min. multiword DMA cycle time */
@@ -179,9 +192,67 @@ enum {					/* offsets into the identify info. */
 	Ierase		= 89,		/* time for security erase */
 	Ieerase		= 90,		/* time for enhanced security erase */
 	Ipower		= 91,		/* current advanced power management */
-	Ilba48		= 100,		/* LBA 48-bit size (64 bits in 100-103) */
+	Ilba48		= 100,		/* 48-bit LBA size (64 bits in 100-103) */
 	Irmsn		= 127,		/* removable status notification */
-	Istatus		= 128,		/* security status */
+	Isecstat	= 128,		/* security status */
+	Icfapwr		= 160,		/* CFA power mode */
+	Imediaserial	= 176,		/* current media serial number */
+	Icksum		= 255,		/* checksum */
+};
+
+enum {					/* bit masks for config identify info */
+	Mpktsz		= 0x0003,	/* packet command size */
+	Mincomplete	= 0x0004,	/* incomplete information */
+	Mdrq		= 0x0060,	/* DRQ type */
+	Mrmdev		= 0x0080,	/* device is removable */
+	Mtype		= 0x1F00,	/* device type */
+	Mproto		= 0x8000,	/* command protocol */
+};
+
+enum {					/* bit masks for capabilities identify info */
+	Mdma		= 0x0100,	/* DMA supported */
+	Mlba		= 0x0200,	/* LBA supported */
+	Mnoiordy	= 0x0400,	/* IORDY may be disabled */
+	Miordy		= 0x0800,	/* IORDY supported */
+	Msoftrst	= 0x1000,	/* needs soft reset when Bsy */
+	Mstdby		= 0x2000,	/* standby supported */
+	Mqueueing	= 0x4000,	/* queueing overlap supported */
+	Midma		= 0x8000,	/* interleaved DMA supported */
+};
+
+enum {					/* bit masks for supported/enabled features */
+	Msmart		= 0x0001,
+	Msecurity	= 0x0002,
+	Mrmmedia	= 0x0004,
+	Mpwrmgmt	= 0x0008,
+	Mpkt		= 0x0010,
+	Mwcache		= 0x0020,
+	Mlookahead	= 0x0040,
+	Mrelirq		= 0x0080,
+	Msvcirq		= 0x0100,
+	Mreset		= 0x0200,
+	Mprotected	= 0x0400,
+	Mwbuf		= 0x1000,
+	Mrbuf		= 0x2000,
+	Mnop		= 0x4000,
+	Mmicrocode	= 0x0001,
+	Mqueued		= 0x0002,
+	Mcfa		= 0x0004,
+	Mapm		= 0x0008,
+	Mnotify		= 0x0010,
+	Mstandby	= 0x0020,
+	Mspinup		= 0x0040,
+	Mmaxsec		= 0x0100,
+	Mautoacoustic	= 0x0200,
+	Maddr48		= 0x0400,
+	Mdevconfov	= 0x0800,
+	Mflush		= 0x1000,
+	Mflush48	= 0x2000,
+	Msmarterror	= 0x0001,
+	Msmartselftest	= 0x0002,
+	Mmserial	= 0x0004,
+	Mmpassthru	= 0x0008,
+	Mlogging	= 0x0020,
 };
 
 typedef struct Ctlr Ctlr;
@@ -255,6 +326,7 @@ typedef struct Drive {
 	int	block;			/* R/W bytes per block */
 	int	status;
 	int	error;
+	int	flags;			/* internal flags */
 } Drive;
 
 static void
@@ -276,7 +348,7 @@ pc87415ienable(Ctlr* ctlr)
 }
 
 static void
-atadumpstate(Drive* drive, uchar* cmd, ulong lba, int count)
+atadumpstate(Drive* drive, uchar* cmd, vlong lba, int count)
 {
 	Prd *prd;
 	Pcidev *p;
@@ -294,7 +366,7 @@ atadumpstate(Drive* drive, uchar* cmd, ulong lba, int count)
 		drive->data, drive->limit, drive->dlen,
 		drive->status, drive->error);
 	if(cmd != nil){
-		print("lba %d -> %lud, count %d -> %d (%d)\n",
+		print("lba %d -> %lld, count %d -> %d (%d)\n",
 			(cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5], lba,
 			(cmd[7]<<8)|cmd[8], count, drive->count);
 	}
@@ -400,6 +472,7 @@ ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
 	return -1;
 }
 
+/*
 static int
 atacsf(Drive* drive, vlong csf, int supported)
 {
@@ -423,6 +496,7 @@ atacsf(Drive* drive, vlong csf, int supported)
 
 	return 0;
 }
+*/
 
 static int
 atadone(void* arg)
@@ -543,7 +617,6 @@ atadrive(int cmdport, int ctlport, int dev)
 	int as, i, pkt;
 	uchar buf[512], *p;
 	ushort iconfig, *sp;
-	vlong sectors;
 
 	atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
 	pkt = 1;
@@ -597,28 +670,22 @@ retry:
 			drive->c = drive->info[Iccyl];
 			drive->h = drive->info[Ichead];
 			drive->s = drive->info[Icsec];
-		}
-		else{
+		}else{
 			drive->c = drive->info[Ilcyl];
 			drive->h = drive->info[Ilhead];
 			drive->s = drive->info[Ilsec];
 		}
-		if(drive->info[Icapabilities] & 0x0200){
-			drive->sectors = (drive->info[Ilba1]<<16)
-					 |drive->info[Ilba0];
-			drive->dev |= Lba;
-			print("LBA %llux\n", drive->sectors);
-			if(drive->info[Icapabilities] & 0x0400){
-				sectors = drive->info[Ilba48]
+		if(drive->info[Icapabilities] & Mlba){
+			if(drive->info[Icsfs+1] & Maddr48){
+				drive->sectors = drive->info[Ilba48]
 					| (drive->info[Ilba48+1]<<16)
 					| ((vlong)drive->info[Ilba48+2]<<32);
-				if(sectors){
-					drive->sectors = sectors;
-					drive->dev |= Lba48|Lba;
-					print("LLBA %llux\n", sectors);
-				}
-				
+				drive->flags |= Lba48;
+			}else{
+				drive->sectors = (drive->info[Ilba+1]<<16)
+					 |drive->info[Ilba];
 			}
+			drive->dev |= Lba;
 		}else
 			drive->sectors = drive->c*drive->h*drive->s;
 		atarwmmode(drive, cmdport, ctlport, dev);
@@ -628,11 +695,13 @@ retry:
 	if(DEBUG & DbgCONFIG){
 		print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
 			dev, cmdport,
-			iconfig, drive->info[Icapabilities]);
+			drive->info[Iconfig], drive->info[Icapabilities]);
 		print(" mwdma %4.4uX", drive->info[Imwdma]);
 		if(drive->info[Ivalid] & 0x04)
 			print(" udma %4.4uX", drive->info[Iudma]);
 		print(" dma %8.8uX rwm %ud\n", drive->dma, drive->rwm);
+		if(drive->flags&Lba48)
+			print("\tLLBA sectors %lld\n", drive->sectors);
 	}
 
 	return drive;
@@ -966,7 +1035,7 @@ ataabort(Drive* drive, int dolock)
 	 */
 	if(dolock)
 		ilock(drive->ctlr);
-	if(atacsf(drive, 0x0000000000004000LL, 0))
+	if(drive->info[Icsfs] & Mnop)
 		atanop(drive, 0);
 	else{
 		atasrst(drive->ctlr->ctlport);
@@ -1173,7 +1242,7 @@ atapktio(Drive* drive, uchar* cmd, int clen)
 		atadmastart(ctlr, drive->write);
 	outb(cmdport+Command, Cpkt);
 
-	if((drive->info[Iconfig] & 0x0060) != 0x0020){
+	if((drive->info[Iconfig] & Mdrq) != 0x0020){
 		microdelay(1);
 		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
 		if(as < 0)
@@ -1217,15 +1286,27 @@ atapktio(Drive* drive, uchar* cmd, int clen)
 	return r;
 }
 
+static uchar cmd48[256] = {
+	[Crs]	Crs48,
+	[Crd]	Crd48,
+	[Crdq]	Crdq48,
+	[Crsm]	Crsm48,
+	[Cws]	Cws48,
+	[Cwd]	Cwd48,
+	[Cwdq]	Cwdq48,
+	[Cwsm]	Cwsm48,
+};
+
 static int
-atageniostart(Drive* drive, ulong lba)
+atageniostart(Drive* drive, vlong lba)
 {
 	Ctlr *ctlr;
+	uchar cmd;
 	int as, c, cmdport, ctlport, h, len, s, use48;
 
 	use48 = 0;
-	if(lba>>28){
-		if(!(drive->dev & Lba48))
+	if((drive->flags&Lba48always) || (lba>>28) || drive->count > 256){
+		if(!(drive->flags & Lba48))
 			return -1;
 		use48 = 1;
 		c = h = s = 0;
@@ -1267,32 +1348,32 @@ atageniostart(Drive* drive, ulong lba)
 			drive->command = Crs;
 	}
 	drive->limit = drive->data + drive->count*drive->secsize;
-
+	cmd = drive->command;
 	if(use48){
-		outb(cmdport+Features, Lba48a);
-		outb(cmdport+Count, lba);
-		outb(cmdport+Sector, lba>>8);
-		outb(cmdport+Cyllo, lba>>16);
-		outb(cmdport+Cylhi, lba>>24);
-		outb(cmdport+Dh, drive->dev);
-
-		outb(cmdport+Features, Lba48b);
-		outb(cmdport+Count, drive->count);
-		outb(cmdport+Sector, drive->count>>8);
-		outb(cmdport+Cyllo, 0);	/* lba>>32 if lba were a vlong */
-		outb(cmdport+Cylhi, 0);	/* lba>>40 if lba were a vlong */
-		outb(cmdport+Dh, drive->dev);
+		outb(cmdport+Count, (drive->count>>8) & 0xFF);
+		outb(cmdport+Count, drive->count & 0XFF);
+		outb(cmdport+Lbalo, (lba>>24) & 0xFF);
+		outb(cmdport+Lbalo, lba & 0xFF);
+		outb(cmdport+Lbamid, (lba>>32) & 0xFF);
+		outb(cmdport+Lbamid, (lba>>8) & 0xFF);
+		outb(cmdport+Lbahi, (lba>>40) & 0xFF);
+		outb(cmdport+Lbahi, (lba>>16) & 0xFF);
+		outb(cmdport+Dh, drive->dev|Lba);
+		cmd = cmd48[cmd];
+
+		if(DEBUG & Dbg48BIT)
+			print("using 48-bit commands\n");
 	}else{
 		outb(cmdport+Count, drive->count);
 		outb(cmdport+Sector, s);
-		outb(cmdport+Dh, drive->dev|h);
 		outb(cmdport+Cyllo, c);
 		outb(cmdport+Cylhi, c>>8);
+		outb(cmdport+Dh, drive->dev|h);
 	}
 	ctlr->done = 0;
 	ctlr->curdrive = drive;
 	ctlr->command = drive->command;	/* debugging */
-	outb(cmdport+Command, drive->command);
+	outb(cmdport+Command, cmd);
 
 	switch(drive->command){
 	case Cws:
@@ -1339,8 +1420,8 @@ atagenio(Drive* drive, uchar* cmd, int)
 {
 	uchar *p;
 	Ctlr *ctlr;
-	int count, len;
-	ulong lba;
+	int count, max;
+	vlong lba, len;
 
 	/*
 	 * Map SCSI commands into ATA commands for discs.
@@ -1408,6 +1489,32 @@ atagenio(Drive* drive, uchar* cmd, int)
 		drive->data += 8;
 		return SDok;
 
+	case 0x9E:			/* long read capacity */
+		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
+			return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
+		if(drive->data == nil || drive->dlen < 8)
+			return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
+		/*
+		 * Read capacity returns the LBA of the last sector.
+		 */
+		len = drive->sectors-1;
+		p = drive->data;
+		*p++ = len>>56;
+		*p++ = len>>48;
+		*p++ = len>>40;
+		*p++ = len>>32;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		len = drive->secsize;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p = len;
+		drive->data += 8;
+		return SDok;
+
 	case 0x28:			/* read */
 	case 0x2A:			/* write */
 		break;
@@ -1425,8 +1532,9 @@ atagenio(Drive* drive, uchar* cmd, int)
 		count = drive->dlen/drive->secsize;
 	qlock(ctlr);
 	while(count){
-		if(count > 256)
-			drive->count = 256;
+		max = (drive->flags&Lba48) ? 65536 : 256;
+		if(count > max)
+			drive->count = max;
 		else
 			drive->count = count;
 		if(atageniostart(drive, lba)){
@@ -1743,6 +1851,7 @@ atapnp(void)
 			break;
 		case (0x4D38<<16)|0x105A:	/* Promise PDC20262 */
 		case (0x4D30<<16)|0x105A:	/* Promise PDC202xx */
+		case (0x4D68<<16)|0x105A:	/* Promise PDC20268 */
 			pi = 0x85;
 			break;
 		case (0x0004<<16)|0x1103:	/* HighPoint HPT-370 */
@@ -1959,10 +2068,13 @@ atarctl(SDunit* unit, char* p, int l)
 	if(drive->rwm)
 		n += snprint(p+n, l-n, " rwm %ud rwmctl %ud",
 			drive->rwm, drive->rwmctl);
+	if(drive->flags&Lba48)
+		n += snprint(p+n, l-n, " lba48always %s",
+			(drive->flags&Lba48always) ? "on" : "off");
 	n += snprint(p+n, l-n, "\n");
-	if(unit->sectors){
-		n += snprint(p+n, l-n, "geometry %ld %ld",
-			unit->sectors, unit->secsize);
+	if(drive->sectors){
+		n += snprint(p+n, l-n, "geometry %lld %d",
+			drive->sectors, drive->secsize);
 		if(drive->pkt == 0)
 			n += snprint(p+n, l-n, " %d %d %d",
 				drive->c, drive->h, drive->s);
@@ -2030,6 +2142,16 @@ atawctl(SDunit* unit, Cmdbuf* cb)
 		if(atastandby(drive, period) != SDok)
 			error(Ebadctl);
 	}
+	else if(strcmp(cb->f[0], "lba48always") == 0){
+		if(cb->nf != 2 || !(drive->flags&Lba48))
+			error(Ebadctl);
+		if(strcmp(cb->f[1], "on") == 0)
+			drive->flags |= Lba48always;
+		else if(strcmp(cb->f[1], "off") == 0)
+			drive->flags &= ~Lba48always;
+		else
+			error(Ebadctl);
+	}
 	else
 		error(Ebadctl);
 	qunlock(drive);

+ 13 - 3
sys/src/9/pc/vganvidia.c

@@ -94,6 +94,7 @@ nvidiaenable(VGAscr* scr)
 	p = nvidiapci();
 	if(p == nil)
 		return;
+	scr->id = p->did;
 
 	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
 	if(scr->io == 0)
@@ -123,7 +124,7 @@ static void
 nvidiacurload(VGAscr* scr, Cursor* curs)
 {
 	ulong*	p;
-	int		i,j;
+	int	i,j;
 	ushort	c,s;
 	ulong	tmp;
 
@@ -135,8 +136,17 @@ nvidiacurload(VGAscr* scr, Cursor* curs)
 	p = KADDR(scr->io + hwCurImage);
 
 	for(i=0; i<16; i++) {
-		c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
-		s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
+		switch(scr->id){
+		default:
+			c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
+			s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
+			break;
+		case 0x171:		/* for Geforece4 MX bug, K.Okamoto */
+		case 0x181:
+			c = (curs->clr[2 * i+1] << 8) | curs->clr[2 * i];
+			s = (curs->set[2 * i+1] << 8) | curs->set[2 * i];
+			break;
+		}
 		tmp = 0;
 		for (j=0; j<16; j++){
 			if(s&0x8000)

Some files were not shown because too many files changed in this diff