patch-2.3.40 linux/drivers/block/ide.c
Next file: linux/drivers/block/loop.c
Previous file: linux/drivers/block/ide-tape.c
Back to the patch index
Back to the overall index
- Lines: 328
- Date:
Tue Jan 18 18:54:21 2000
- Orig file:
v2.3.39/linux/drivers/block/ide.c
- Orig date:
Tue Jan 11 22:31:39 2000
diff -u --recursive --new-file v2.3.39/linux/drivers/block/ide.c linux/drivers/block/ide.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide.c Version 6.21 November 9, 1999
+ * linux/drivers/block/ide.c Version 6.30 Dec 28, 1999
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/
@@ -108,6 +108,7 @@
* Specifically Promise's PDC20262 chipset.
* Version 6.21 Fixing/Fixed SMP spinlock issue with insight from an old
* hat that clarified original low level driver design.
+ * Version 6.30 Added SMP support; fixed multmode issues. -ml
*
* Some additional driver compile-time options are in ./include/linux/ide.h
*
@@ -116,8 +117,8 @@
*
*/
-#define REVISION "Revision: 6.21"
-#define VERSION "Id: ide.c 6.21 1999/11/10"
+#define REVISION "Revision: 6.30"
+#define VERSION "Id: ide.c 6.30 1999/12/28"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
@@ -169,6 +170,10 @@
static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
static int initializing; /* set while initializing built-in drivers */
+#ifdef CONFIG_BLK_DEV_IDEPCI
+static int ide_scan_direction = 0; /* HELLO, comment me!! */
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+
#if defined(__mc68000__) || defined(CONFIG_APUS)
/*
* ide_lock is used by the Atari code to obtain access to the IDE interrupt,
@@ -542,22 +547,28 @@
return 0;
}
+extern struct block_device_operations ide_fops[];
/*
- * ide_geninit() is called exactly *once* for each major, from genhd.c,
- * at the beginning of the initial partition check for the drives.
+ * ide_geninit() is called exactly *once* for each interface.
*/
-void ide_geninit (struct gendisk *gd)
+void ide_geninit (ide_hwif_t *hwif)
{
unsigned int unit;
- ide_hwif_t *hwif = gd->real_devices;
+ struct gendisk *gd = hwif->gd;
- for (unit = 0; unit < gd->nr_real; ++unit) {
+ for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
- drive->part[0].nr_sects = current_capacity(drive);
- if (!drive->present || (drive->media != ide_disk && drive->media != ide_floppy) ||
- drive->driver == NULL || !drive->part[0].nr_sects)
- drive->part[0].start_sect = -1; /* skip partition check */
+ if (!drive->present)
+ continue;
+ if (drive->media!=ide_disk && drive->media!=ide_floppy)
+ continue;
+ register_disk(gd,MKDEV(hwif->major,unit<<PARTN_BITS),
+#ifdef CONFIG_BLK_DEV_ISAPNP
+ (drive->forced_geom && drive->noprobe) ? 1 :
+#endif /* CONFIG_BLK_DEV_ISAPNP */
+ 1<<PARTN_BITS, ide_fops,
+ current_capacity(drive));
}
}
@@ -669,7 +680,7 @@
* (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
* we set a timer to poll at 50ms intervals.
*/
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
{
unsigned int unit;
unsigned long flags;
@@ -1213,7 +1224,7 @@
* the driver. This makes the driver much more friendlier to shared IRQs
* than previous designs, while remaining 100% (?) SMP safe and capable.
*/
-static void ide_do_request (ide_hwgroup_t *hwgroup)
+static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
{
struct blk_dev_struct *bdev;
ide_drive_t *drive;
@@ -1272,14 +1283,25 @@
drive->service_start = jiffies;
bdev = &blk_dev[hwif->major];
- if( bdev->request_queue.plugged ) /* FIXME: paranoia */
+ if ( bdev->request_queue.plugged ) /* FIXME: paranoia */
printk("%s: Huh? nuking plugged queue\n", drive->name);
bdev->request_queue.current_request = hwgroup->rq = drive->queue.current_request;
+ /*
+ * Some systems have trouble with IDE IRQs arriving while
+ * the driver is still setting things up. So, here we disable
+ * the IRQ used by this interface while the request is being started.
+ * This may look bad at first, but pretty much the same thing
+ * happens anyway when any interrupt comes in, IDE or otherwise
+ * -- the kernel masks the IRQ while it is being handled.
+ */
+ if (hwif->irq != masked_irq)
+ disable_irq_nosync(hwif->irq);
spin_unlock(&io_request_lock);
- if (!hwif->serialized) /* play it safe with buggy hardware */
- ide__sti();
+ ide__sti(); /* allow other IRQs while we start this request */
startstop = start_request(drive);
spin_lock_irq(&io_request_lock);
+ if (hwif->irq != masked_irq)
+ enable_irq(hwif->irq);
if (startstop == ide_stopped)
hwgroup->busy = 0;
}
@@ -1297,69 +1319,69 @@
void do_ide0_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[0].hwgroup);
+ ide_do_request (ide_hwifs[0].hwgroup, 0);
}
#if MAX_HWIFS > 1
void do_ide1_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[1].hwgroup);
+ ide_do_request (ide_hwifs[1].hwgroup, 0);
}
#endif /* MAX_HWIFS > 1 */
#if MAX_HWIFS > 2
void do_ide2_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[2].hwgroup);
+ ide_do_request (ide_hwifs[2].hwgroup, 0);
}
#endif /* MAX_HWIFS > 2 */
#if MAX_HWIFS > 3
void do_ide3_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[3].hwgroup);
+ ide_do_request (ide_hwifs[3].hwgroup, 0);
}
#endif /* MAX_HWIFS > 3 */
#if MAX_HWIFS > 4
void do_ide4_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[4].hwgroup);
+ ide_do_request (ide_hwifs[4].hwgroup, 0);
}
#endif /* MAX_HWIFS > 4 */
#if MAX_HWIFS > 5
void do_ide5_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[5].hwgroup);
+ ide_do_request (ide_hwifs[5].hwgroup, 0);
}
#endif /* MAX_HWIFS > 5 */
#if MAX_HWIFS > 6
void do_ide6_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[6].hwgroup);
+ ide_do_request (ide_hwifs[6].hwgroup, 0);
}
#endif /* MAX_HWIFS > 6 */
#if MAX_HWIFS > 7
void do_ide7_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[7].hwgroup);
+ ide_do_request (ide_hwifs[7].hwgroup, 0);
}
#endif /* MAX_HWIFS > 7 */
#if MAX_HWIFS > 8
void do_ide8_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[8].hwgroup);
+ ide_do_request (ide_hwifs[8].hwgroup, 0);
}
#endif /* MAX_HWIFS > 8 */
#if MAX_HWIFS > 9
void do_ide9_request (request_queue_t *q)
{
- ide_do_request (ide_hwifs[9].hwgroup);
+ ide_do_request (ide_hwifs[9].hwgroup, 0);
}
#endif /* MAX_HWIFS > 9 */
@@ -1445,7 +1467,7 @@
hwgroup->busy = 0;
}
}
- ide_do_request(hwgroup);
+ ide_do_request(hwgroup, 0);
spin_unlock_irqrestore(&io_request_lock, flags);
}
@@ -1593,7 +1615,7 @@
if (startstop == ide_stopped) {
if (hwgroup->handler == NULL) { /* paranoia */
hwgroup->busy = 0;
- ide_do_request(hwgroup);
+ ide_do_request(hwgroup, hwif->irq);
} else {
printk("%s: ide_intr: huh? expected NULL handler on exit\n", drive->name);
}
@@ -1608,6 +1630,9 @@
ide_drive_t *get_info_ptr (kdev_t i_rdev)
{
int major = MAJOR(i_rdev);
+#if 0
+ int minor = MINOR(i_rdev) & PARTN_MASK;
+#endif
unsigned int h;
for (h = 0; h < MAX_HWIFS; ++h) {
@@ -1616,7 +1641,11 @@
unsigned unit = DEVICE_NR(i_rdev);
if (unit < MAX_DRIVES) {
ide_drive_t *drive = &hwif->drives[unit];
+#if 0
+ if ((drive->present) && (drive->part[minor].nr_sects))
+#else
if (drive->present)
+#endif
return drive;
}
break;
@@ -1698,7 +1727,7 @@
rq->next = cur_rq->next;
cur_rq->next = rq;
}
- ide_do_request(hwgroup);
+ ide_do_request(hwgroup, 0);
spin_unlock_irqrestore(&io_request_lock, flags);
if (action == ide_wait) {
down(&sem); /* wait for it to be serviced */
@@ -1751,11 +1780,10 @@
drive->part[p].nr_sects = 0;
};
- drive->part[0].nr_sects = current_capacity(drive);
- if ((drive->media != ide_disk && drive->media != ide_floppy) ||
- drive->driver == NULL || !drive->part[0].nr_sects)
- drive->part[0].start_sect = -1;
- resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
+ grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
+ (drive->media != ide_disk &&
+ drive->media != ide_floppy) ? 1 : 1<<PARTN_BITS,
+ current_capacity(drive));
drive->busy = 0;
wake_up(&drive->wqueue);
@@ -2677,6 +2705,7 @@
* for chipsets that are ATA-66 capable, but
* the ablity to bit test for detection is
* currently unknown.
+ * "ide=reverse" : Formerly called to pci sub-system, but now local.
*
* "splitfifo=betweenChan"
* : FIFO Configuration of VIA 82c586(<nothing>,"A"or"B").
@@ -2727,6 +2756,14 @@
}
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
+#ifdef CONFIG_BLK_DEV_IDEPCI
+ if (!strcmp(s, "ide=reverse")) {
+ ide_scan_direction = 1;
+ printk("ide: Enabled support for IDE inverse scan order.\n");
+ return 0;
+ }
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+
init_ide_data ();
/*
@@ -3060,7 +3097,7 @@
if (pci_present())
{
#ifdef CONFIG_BLK_DEV_IDEPCI
- ide_scan_pcibus();
+ ide_scan_pcibus(ide_scan_direction);
#else
#ifdef CONFIG_BLK_DEV_RZ1000
{
@@ -3366,7 +3403,6 @@
EXPORT_SYMBOL(drive_is_flashcard);
EXPORT_SYMBOL(ide_timer_expiry);
EXPORT_SYMBOL(ide_intr);
-EXPORT_SYMBOL(ide_geninit);
EXPORT_SYMBOL(ide_fops);
EXPORT_SYMBOL(ide_get_queue);
EXPORT_SYMBOL(do_ide0_request);
@@ -3448,6 +3484,7 @@
int __init ide_init (void)
{
static char banner_printed = 0;
+ int i;
if (!banner_printed) {
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
@@ -3459,6 +3496,12 @@
initializing = 1;
ide_init_builtin_drivers();
initializing = 0;
+
+ for (i = 0; i < MAX_HWIFS; ++i) {
+ ide_hwif_t *hwif = &ide_hwifs[i];
+ if (hwif->present)
+ ide_geninit(hwif);
+ }
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)