u8 max_multsect = id[ATA_ID_MAX_MULTSECT] & 0xff;
if (max_multsect) {
-#ifdef CONFIG_IDEDISK_MULTI_MODE
if ((max_multsect / 2) > 1)
id[ATA_ID_MULTSECT] = max_multsect | 0x100;
else
id[ATA_ID_MULTSECT] &= ~0x1ff;
drive->mult_req = id[ATA_ID_MULTSECT] & 0xff;
-#endif
- if ((id[ATA_ID_MULTSECT] & 0x100) &&
- (id[ATA_ID_MULTSECT] & 0xff))
+
+ if (drive->mult_req)
drive->special.b.set_multmode = 1;
}
}
ide_hwif_t *hwif = HWIF(drive);
u16 *id = drive->id;
char *m = (char *)&id[ATA_ID_PROD];
- int bswap = 1;
+ int bswap = 1, is_cfa;
/* read 512 bytes of id info */
hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
ide_fix_driveid(id);
/*
- * WIN_IDENTIFY returns little-endian info,
- * WIN_PIDENTIFY *usually* returns little-endian info.
+ * ATA_CMD_ID_ATA returns little-endian info,
+ * ATA_CMD_ID_ATAPI *usually* returns little-endian info.
*/
- if (cmd == WIN_PIDENTIFY) {
+ if (cmd == ATA_CMD_ID_ATAPI) {
if ((m[0] == 'N' && m[1] == 'E') || /* NEC */
(m[0] == 'F' && m[1] == 'X') || /* Mitsumi */
(m[0] == 'P' && m[1] == 'i')) /* Pioneer */
/*
* Check for an ATAPI device
*/
- if (cmd == WIN_PIDENTIFY) {
+ if (cmd == ATA_CMD_ID_ATAPI) {
u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;
printk(KERN_CONT "ATAPI ");
* Not an ATAPI device: looks like a "regular" hard disk
*/
- /*
- * 0x848a = CompactFlash device
- * These are *not* removable in Linux definition of the term
- */
- if (id[ATA_ID_CONFIG] != 0x848a && (id[ATA_ID_CONFIG] & (1 << 7)))
+ is_cfa = ata_id_is_cfa(id);
+
+ /* CF devices are *not* removable in Linux definition of the term */
+ if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))
drive->removable = 1;
drive->media = ide_disk;
- printk(KERN_CONT "%s DISK drive\n",
- (id[ATA_ID_CONFIG] == 0x848a) ? "CFA" : "ATA");
+ printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA");
return;
if (io_ports->ctl_addr) {
a = tp_ops->read_altstatus(hwif);
s = tp_ops->read_status(hwif);
- if ((a ^ s) & ~INDEX_STAT)
+ if ((a ^ s) & ~ATA_IDX)
/* ancient Seagate drives, broken interfaces */
printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
"instead of ALTSTATUS(0x%02x)\n",
/* set features register for atapi
* identify command to be sure of reply
*/
- if (cmd == WIN_PIDENTIFY) {
+ if (cmd == ATA_CMD_ID_ATAPI) {
ide_task_t task;
memset(&task, 0, sizeof(task));
/* ask drive for ID */
tp_ops->exec_command(hwif, cmd);
- timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
- timeout += jiffies;
- do {
- if (time_after(jiffies, timeout)) {
- /* drive timed-out */
- return 1;
- }
- /* give drive a breather */
- msleep(50);
- s = use_altstatus ? tp_ops->read_altstatus(hwif)
- : tp_ops->read_status(hwif);
- } while (s & BUSY_STAT);
+ timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
+
+ if (ide_busy_sleep(hwif, timeout, use_altstatus))
+ return 1;
- /* wait for IRQ and DRQ_STAT */
+ /* wait for IRQ and ATA_DRQ */
msleep(50);
s = tp_ops->read_status(hwif);
- if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) {
+ if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
unsigned long flags;
/* local CPU only; some systems need this */
return retval;
}
-static int ide_busy_sleep(ide_hwif_t *hwif)
+int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
{
- unsigned long timeout = jiffies + WAIT_WORSTCASE;
u8 stat;
+ timeout += jiffies;
+
do {
- msleep(50);
- stat = hwif->tp_ops->read_status(hwif);
- if ((stat & BUSY_STAT) == 0)
+ msleep(50); /* give drive a breather */
+ stat = altstatus ? hwif->tp_ops->read_altstatus(hwif)
+ : hwif->tp_ops->read_status(hwif);
+ if ((stat & ATA_BUSY) == 0)
return 0;
} while (time_before(jiffies, timeout));
- return 1;
+ return 1; /* drive timed-out */
}
static u8 ide_read_device(ide_drive_t *drive)
if (drive->present) {
/* avoid waiting for inappropriate probes */
- if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
+ if (drive->media != ide_disk && cmd == ATA_CMD_ID_ATA)
return 4;
}
#ifdef DEBUG
printk(KERN_INFO "probing for %s: present=%d, media=%d, probetype=%s\n",
drive->name, drive->present, drive->media,
- (cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI");
+ (cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI");
#endif
/* needed for some systems
if (drive->select.b.unit != 0) {
/* exit with drive0 selected */
SELECT_DRIVE(&hwif->drives[0]);
- /* allow BUSY_STAT to assert & clear */
+ /* allow ATA_BUSY to assert & clear */
msleep(50);
}
/* no i/f present: mmm.. this should be a 4 -ml */
stat = tp_ops->read_status(hwif);
- if (OK_STAT(stat, READY_STAT, BUSY_STAT) ||
- drive->present || cmd == WIN_PIDENTIFY) {
+ if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
+ drive->present || cmd == ATA_CMD_ID_ATAPI) {
/* send cmd and wait */
if ((rc = try_to_identify(drive, cmd))) {
/* failed: try again */
stat = tp_ops->read_status(hwif);
- if (stat == (BUSY_STAT | READY_STAT))
+ if (stat == (ATA_BUSY | ATA_DRDY))
return 4;
- if (rc == 1 && cmd == WIN_PIDENTIFY) {
+ if (rc == 1 && cmd == ATA_CMD_ID_ATAPI) {
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
SELECT_DRIVE(drive);
msleep(50);
- tp_ops->exec_command(hwif, WIN_SRST);
- (void)ide_busy_sleep(hwif);
+ tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
+ (void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
rc = try_to_identify(drive, cmd);
}
SELECT_DRIVE(drive);
msleep(50);
- tp_ops->exec_command(hwif, EXABYTE_ENABLE_NEST);
+ tp_ops->exec_command(hwif, ATA_EXABYTE_ENABLE_NEST);
- if (ide_busy_sleep(hwif)) {
+ if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 0)) {
printk(KERN_CONT "failed (timeout)\n");
return;
}
printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
else
printk(KERN_CONT "success\n");
-
- /* if !(success||timed-out) */
- if (do_probe(drive, WIN_IDENTIFY) >= 2) {
- /* look for ATAPI device */
- (void) do_probe(drive, WIN_PIDENTIFY);
- }
}
/**
* Also note that 0 everywhere means "can't do X"
*/
- drive->id = kzalloc(SECTOR_WORDS *4, GFP_KERNEL);
+ drive->id = kzalloc(SECTOR_SIZE, GFP_KERNEL);
drive->id_read = 0;
if(drive->id == NULL)
{
strcpy(m, "UNKNOWN");
/* skip probing? */
- if (!drive->noprobe)
- {
+ if (!drive->noprobe) {
+retry:
/* if !(success||timed-out) */
- if (do_probe(drive, WIN_IDENTIFY) >= 2) {
+ if (do_probe(drive, ATA_CMD_ID_ATA) >= 2)
/* look for ATAPI device */
- (void) do_probe(drive, WIN_PIDENTIFY);
- }
+ (void)do_probe(drive, ATA_CMD_ID_ATAPI);
+
if (!drive->present)
/* drive not found */
return 0;
- if (strstr(m, "E X A B Y T E N E S T"))
+ if (strstr(m, "E X A B Y T E N E S T")) {
enable_nest(drive);
-
+ goto retry;
+ }
+
/* identification failed? */
if (!drive->id_read) {
if (drive->media == ide_disk) {
}
}
-#if MAX_HWIFS > 1
/*
* save_match() is used to simplify logic in init_irq() below.
*
if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
*match = new;
}
-#endif /* MAX_HWIFS > 1 */
/*
* init request queue
ide_hwgroup_t *hwgroup;
ide_hwif_t *match = NULL;
-
- BUG_ON(in_interrupt());
- BUG_ON(irqs_disabled());
- BUG_ON(hwif == NULL);
-
mutex_lock(&ide_cfg_mtx);
hwif->hwgroup = NULL;
-#if MAX_HWIFS > 1
+
/*
* Group up with any other hwifs that share our irq(s).
*/
}
}
}
-#endif /* MAX_HWIFS > 1 */
+
/*
* If we are still without a hwgroup, then form a new one
*/
sa = IRQF_SHARED;
#endif /* __mc68000__ */
- if (IDE_CHIPSET_IS_PCI(hwif->chipset))
+ if (hwif->chipset == ide_pci || hwif->chipset == ide_cmd646 ||
+ hwif->chipset == ide_ali14xx)
sa = IRQF_SHARED;
if (io_ports->ctl_addr)
if (!drive->present)
continue;
- ide_add_generic_settings(drive);
-
snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i);
dev->parent = &hwif->gendev;
dev->bus = &ide_bus_type;
* ports 0x1f0/0x170 (the ide0/ide1 defaults).
*/
mutex_lock(&ide_cfg_mtx);
- if (MAX_HWIFS == 1) {
- if (ide_indexes == 0 && i == 0)
- idx = 1;
+ if (bootable) {
+ if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
+ idx = ffz(ide_indexes | i);
} else {
- if (bootable) {
- if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
- idx = ffz(ide_indexes | i);
- } else {
- if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
- idx = ffz(ide_indexes | 3);
- else if ((ide_indexes & 3) != 3)
- idx = ffz(ide_indexes);
- }
+ if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
+ idx = ffz(ide_indexes | 3);
+ else if ((ide_indexes & 3) != 3)
+ idx = ffz(ide_indexes);
}
if (idx >= 0)
ide_indexes |= (1 << idx);
if (hws[0])
host->dev[0] = hws[0]->dev;
- if (d)
+ if (d) {
+ host->init_chipset = d->init_chipset;
host->host_flags = d->host_flags;
+ }
return host;
}