patch-1.3.28 linux/drivers/block/ide.c

Next file: linux/drivers/block/ide.h
Previous file: linux/drivers/block/ide-cd.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.27/linux/drivers/block/ide.c linux/drivers/block/ide.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide.c	Version 5.13b  Sep 9, 1995
+ *  linux/drivers/block/ide.c	Version 5.14  Sep 14, 1995
  *
  *  Copyright (C) 1994, 1995  Linus Torvalds & authors (see below)
  */
@@ -141,11 +141,15 @@
  *  Version 5.13	fixed typo ('B'), thanks to houston@boyd.geog.mcgill.ca
  *			fixed ht6560b support
  *  Version 5.13b (sss)	fix problem in calling ide_cdrom_setup()
- *                      don't bother invalidating nonexistent partitions
+ *			don't bother invalidating nonexistent partitions
+ *  Version 5.14	fixes to cmd640 support.. maybe it works now(?)
+ *			added & tested full EZ-DRIVE support -- don't use LILO!
+ *			don't enable 2nd CMD640 PCI port during init - conflict
  *
  *  Driver compile-time options are in ide.h
  *
  *  To do, in likely order of completion:
+ *	- figure out why Mitsumi ATAPI cdroms are having trouble..
  *	- add ioctls to get/set interface timings on cmd640, ht6560b, triton
  *	- modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f
  *	- improved CMD support:  probably handing this off to someone else
@@ -1318,10 +1322,11 @@
 #ifdef DEBUG
 	printk("%s: ide_do_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
 #endif
-	minor = MINOR(rq->dev);
+	minor = MINOR(rq->rq_dev);
 	unit = minor >> PARTN_BITS;
-	if (MAJOR(rq->dev) != hwif->major || unit >= MAX_DRIVES) {
-		printk("%s: bad device number: 0x%04x\n", hwif->name, rq->dev);
+	if (MAJOR(rq->rq_dev) != hwif->major || unit >= MAX_DRIVES) {
+		printk("%s: bad device number: %s\n",
+		       hwif->name, kdevname(rq->rq_dev));
 		goto kill_rq;
 	}
 	drive = &hwif->drives[unit];
@@ -1339,6 +1344,12 @@
 		goto kill_rq;
 	}
 	block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
+#if FAKE_FDISK_FOR_EZDRIVE
+	if (block == 0 && drive->ezdrive) {
+		block = 1;
+		printk("%s: [EZD] accessing sector 1 instead of sector 0\n", drive->name);
+	}
+#endif /* FAKE_FDISK_FOR_EZDRIVE */
 	((ide_hwgroup_t *)hwif->hwgroup)->drive = drive;
 #if (DISK_RECOVERY_TIME > 0)
 	while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
@@ -1407,7 +1418,7 @@
 			hwgroup->drive = NULL;	/* paranoia */
 			do {
 				rq = blk_dev[hwif->major].current_request;
-				if (rq != NULL && rq->dev != -1)
+				if (rq != NULL && rq->rq_status != RQ_INACTIVE)
 					goto got_rq;
 			} while ((hwif = hwif->next) != hwgroup->hwif);
 			return;		/* no work left for this hwgroup */
@@ -1575,7 +1586,7 @@
  * get_info_ptr() returns the (ide_drive_t *) for a given device number.
  * It returns NULL if the given device number does not match any present drives.
  */
-static ide_drive_t *get_info_ptr (int i_rdev)
+static ide_drive_t *get_info_ptr (kdev_t i_rdev)
 {
 	int		major = MAJOR(i_rdev);
 	unsigned int	h;
@@ -1605,7 +1616,7 @@
  * If arg is NULL, it goes through all the motions,
  * but without actually sending a command to the drive.
  */
-int ide_do_drive_cmd(int rdev, char *args)
+int ide_do_drive_cmd(kdev_t rdev, char *args)
 {
 	unsigned long flags;
 	unsigned int major = MAJOR(rdev);
@@ -1624,7 +1635,8 @@
 	rq.bh = NULL;
 	rq.bhtail = NULL;
 	rq.next = NULL;
-	rq.dev = rdev;
+	rq.rq_status = RQ_ACTIVE;
+	rq.rq_dev = rdev;
 	bdev = &blk_dev[major];
 
 	save_flags(flags);
@@ -1701,7 +1713,7 @@
  * usage == 1 (we need an open channel to use an ioctl :-), so this
  * is our limit.
  */
-static int revalidate_disk(dev_t  i_rdev)
+static int revalidate_disk(kdev_t i_rdev)
 {
 	ide_drive_t *drive;
 	unsigned int p, major, minor;
@@ -1710,7 +1722,7 @@
 	if ((drive = get_info_ptr(i_rdev)) == NULL)
 		return -ENODEV;
 
-	major = MAJOR(i_rdev) << 8;
+	major = MAJOR(i_rdev);
 	minor = drive->select.b.unit << PARTN_BITS;
 	save_flags(flags);
 	cli();
@@ -1723,9 +1735,10 @@
 
 	for (p = 0; p < (1<<PARTN_BITS); ++p) {
 		if (drive->part[p].nr_sects > 0) {
-			sync_dev           (major | (minor + p));
-			invalidate_inodes  (major | (minor + p));
-			invalidate_buffers (major | (minor + p));
+			kdev_t devp = MKDEV(major, minor+p);
+			sync_dev           (devp);
+			invalidate_inodes  (devp);
+			invalidate_buffers (devp);
 		}
 		drive->part[p].start_sect = 0;
 		drive->part[p].nr_sects   = 0;
@@ -1760,7 +1773,7 @@
 	ide_drive_t *drive;
 	unsigned long flags;
 
-	if (!inode || !inode->i_rdev)
+	if (!inode || !(inode->i_rdev))
 		return -EINVAL;
 	if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
 		return -ENODEV;
@@ -1772,7 +1785,7 @@
 			put_user(drive->bios_head, (byte *) &loc->heads);
 			put_user(drive->bios_sect, (byte *) &loc->sectors);
 			put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders);
-			put_user((unsigned)drive->part[inode->i_rdev&PARTN_MASK].start_sect,
+			put_user((unsigned)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].start_sect,
 				(unsigned long *) &loc->start);
 			return 0;
 
@@ -1792,7 +1805,7 @@
 			return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]);
 
          	case BLKGETSIZE:   /* Return device size */
-			return write_fs_long(arg, drive->part[inode->i_rdev&PARTN_MASK].nr_sects);
+			return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects);
 		case BLKRRPART: /* Re-read partition tables */
 			return revalidate_disk(inode->i_rdev);
 
@@ -1812,7 +1825,7 @@
 			return write_fs_long(arg, drive->mult_count);
 
 		case HDIO_GET_IDENTITY:
-			if (!arg || (inode->i_rdev & PARTN_MASK))
+			if (!arg || (MINOR(inode->i_rdev) & PARTN_MASK))
 				return -EINVAL;
 			if (drive->id == NULL)
 				return -ENOMSG;
@@ -1837,7 +1850,7 @@
 		case HDIO_SET_CHIPSET:
 			if (!suser())
 				return -EACCES;
-			if ((inode->i_rdev & PARTN_MASK))
+			if ((MINOR(inode->i_rdev) & PARTN_MASK))
 				return -EINVAL;
 			save_flags(flags);
 			cli();
@@ -1874,7 +1887,7 @@
 		case HDIO_SET_MULTCOUNT:
 			if (!suser())
 				return -EACCES;
-			if (inode->i_rdev & PARTN_MASK)
+			if (MINOR(inode->i_rdev) & PARTN_MASK)
 				return -EINVAL;
 			if ((drive->id != NULL) && (arg > drive->id->max_multsect))
 				return -EINVAL;
@@ -1920,7 +1933,7 @@
 	}
 }
 
-static int ide_check_media_change (dev_t i_rdev)
+static int ide_check_media_change (kdev_t i_rdev)
 {
 	ide_drive_t *drive;
 
@@ -2302,7 +2315,7 @@
 #ifdef CONFIG_BLK_DEV_IDECD
 			if (drive->present && drive->media == cdrom)
 				ide_cdrom_setup(drive);
-#endif	/* CONFIG_BLK_DEV_IDECD */
+#endif /* CONFIG_BLK_DEV_IDECD */
 		}
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			ide_drive_t *drive = &hwif->drives[unit];
@@ -2422,6 +2435,7 @@
 		}
 	}
 	write_cmd640_vlb(port, 0x51, read_cmd640_vlb(port, 0x51)|0xc8);
+	write_cmd640_vlb(port, 0x57, read_cmd640_vlb(port, 0x57)|0x0c);
 	printk("disabled read-ahead, enabled secondary\n");
 
 }
@@ -2642,7 +2656,7 @@
  * to "convert" a drive to a logical geometry with fewer than 1024 cyls
  * It mimics the method used by Ontrack Disk Manager.
  */
-int ide_xlate_1024 (dev_t i_rdev, int need_offset, const char *msg)
+int ide_xlate_1024 (kdev_t i_rdev, int offset, const char *msg)
 {
 	ide_drive_t *drive;
 	static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
@@ -2665,12 +2679,19 @@
 		if (0 == *++heads)
 			break;
 	}
-	if (need_offset) {
-		drive->sect0 = 63;
-		drive->bios_cyl = (tracks - 1) / drive->bios_head;
+	if (offset) {
+#if FAKE_FDISK_FOR_EZDRIVE
+		if (offset == -1)
+			drive->ezdrive = 1;
+		else
+#endif /* FAKE_FDISK_FOR_EZDRIVE */
+		{
+			drive->sect0 = 63;
+			drive->bios_cyl = (tracks - 1) / drive->bios_head;
+		}
 	}
 	drive->part[0].nr_sects = current_capacity(drive);
-	printk("%s [+%d,%d/%d/%d]", msg, drive->sect0, drive->bios_cyl, drive->bios_head, drive->bios_sect);
+	printk("%s [%d/%d/%d]", msg, drive->bios_cyl, drive->bios_head, drive->bios_sect);
 	return 1;
 }
 
@@ -2824,11 +2845,17 @@
 	unsigned short reg;
 
 	printk("ide: buggy RZ1000 interface: ");
-	if ((rc = pcibios_read_config_word(bus, fn, 0x40, &reg))
-	 || (rc =  pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff)))
-		buggy_interface_fallback (rc);
-	else
-		printk("disabled read-ahead\n");
+	if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &reg))) {
+		ide_pci_access_error (rc);
+	} else if (!(reg & 1)) {
+		printk("not enabled\n");
+	} else {
+		if ((rc = pcibios_read_config_word(bus, fn, 0x40, &reg))
+		 || (rc =  pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff)))
+			buggy_interface_fallback (rc);
+		else
+			printk("disabled read-ahead\n");
+	}
 }
 #endif /* SUPPORT_RZ1000 */
 
@@ -2840,11 +2867,34 @@
 
 	single_threaded = 1;
 	printk("ide: buggy CMD640 interface: ");
+
+#if 0	/* funny.. the cmd640b I tried this on claimed to not be enabled.. */
+	unsigned short sreg;
+	if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &sreg))) {
+		ide_pci_access_error (rc);
+	} else if (!(sreg & 1)) {
+		printk("not enabled\n");
+	} else {
+#endif /* 0 */
+
+	/*
+	 * The first part is undocumented magic from the DOS driver.
+	 * According to the datasheet, there is no port 0x5b on the cmd640.
+	 */
+	(void) pcibios_write_config_byte(bus, fn, 0x5b, 0xbd);
+	if (pcibios_write_config_byte(bus, fn, 0x5b, 0xbd) != 0xbd)
+		printk("init_cmd640: huh? 0x5b read back wrong\n");
+	(void) pcibios_write_config_byte(bus, fn, 0x5b, 0);
+	/*
+	 * The rest is from the cmd640b datasheet.
+	 */
 	if ((rc = pcibios_read_config_byte(bus, fn, 0x51, &reg))
-	 || (rc =  pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc8)))
+	 || (rc =  pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc0)) /* 0xc8 to enable 2nd i/f */
+	 || (rc =  pcibios_read_config_byte(bus, fn, 0x57, &reg))
+	 || (rc =  pcibios_write_config_byte(bus, fn, 0x57, reg | 0x0c)))
 		buggy_interface_fallback (rc);
 	else
-		printk("serialized, disabled read-ahead, enabled secondary\n");
+		printk("serialized, disabled read-ahead\n");
 }
 #endif /* SUPPORT_CMD640 */
 
@@ -2857,19 +2907,13 @@
 static void ide_probe_pci (unsigned short vendor, unsigned short device, ide_pci_init_proc_t *init)
 {
 	unsigned long flags;
-	unsigned index = 0;
+	unsigned index;
 	byte fn, bus;
-	int rc;
 
 	save_flags(flags);
 	cli();
 	for (index = 0; !pcibios_find_device (vendor, device, index, &bus, &fn); ++index) {
-		unsigned short command;
-		if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &command))) {
-			ide_pci_access_error (rc);
-		} else if (command & 1) {	/* is device enabled? */
-			init (bus, fn);
-		}
+		init (bus, fn);
 	}
 	restore_flags(flags);
 }
@@ -2889,7 +2933,7 @@
 	ide_probe_pci (PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, &init_cmd640);
 #endif
 #ifdef CONFIG_BLK_DEV_TRITON
-	ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371, &ide_init_triton);
+	ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_1, &ide_init_triton);
 #endif
 }
 #endif /* CONFIG_PCI */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this