Commit 61b238c6 authored by Jens Axboe's avatar Jens Axboe

ide-probe updates:

o byte -> u8
o drive_is_flashcard() moved to probe code
o ide-iops changes
o various cleanups
o remove useless ide_lock debug stuff
parent 9fd68c4e
...@@ -52,46 +52,69 @@ ...@@ -52,46 +52,69 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
static inline void do_identify (ide_drive_t *drive, byte cmd) /*
* CompactFlash cards and their brethern pretend to be removable
* hard disks, except:
* (1) they never have a slave unit, and
* (2) they don't have doorlock mechanisms.
* This test catches them, and is invoked elsewhere when setting
* appropriate config bits.
*
* FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD)
* devices, so in linux 2.3.x we should change this to just treat all PCMCIA
* drives this way, and get rid of the model-name tests below
* (too big of an interface change for 2.2.x).
* At that time, we might also consider parameterizing the timeouts and retries,
* since these are MUCH faster than mechanical drives. -M.Lord
*/
inline int drive_is_flashcard (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
if (drive->removable && id != NULL) {
if (id->config == 0x848a) return 1; /* CompactFlash */
if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */
|| !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */
|| !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */
|| !strncmp(id->model, "HAGIWARA HPC", 12) /* Hagiwara */
|| !strncmp(id->model, "LEXAR ATA_FLASH", 15) /* Lexar */
|| !strncmp(id->model, "ATA_FLASH", 9)) /* Simple Tech */
{
return 1; /* yes, it is a flash memory card */
}
}
return 0; /* no, it is not a flash memory card */
}
static inline void do_identify (ide_drive_t *drive, u8 cmd)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
int bswap = 1; int bswap = 1;
struct hd_driveid *id; struct hd_driveid *id;
id = drive->id = kmalloc (SECTOR_WORDS*4, GFP_ATOMIC); /* called with interrupts disabled! */ /* called with interrupts disabled! */
id = drive->id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
if (!id) { if (!id) {
printk(KERN_WARNING "(ide-probe::do_identify) Out of memory.\n"); printk(KERN_WARNING "(ide-probe::do_identify) "
"Out of memory.\n");
goto err_kmalloc; goto err_kmalloc;
} }
/* read 512 bytes of id info */ /* read 512 bytes of id info */
#if 1 hwif->ata_input_data(drive, id, SECTOR_WORDS);
ata_input_data(drive, id, SECTOR_WORDS);
#else
{
unsigned long *ptr = (unsigned long *)id ;
unsigned long lcount = 256/2 ;
// printk("IDE_DATA_REG = %#lx",IDE_DATA_REG);
while( lcount-- )
*ptr++ = inl(IDE_DATA_REG);
}
#endif
local_irq_enable(); local_irq_enable();
ide_fix_driveid(id); ide_fix_driveid(id);
if (id->word156 == 0x4d42) {
printk("%s: drive->id->word156 == 0x%04x \n",
drive->name, drive->id->word156);
}
if (!drive->forced_lun) if (!drive->forced_lun)
drive->last_lun = id->last_lun & 0x7; drive->last_lun = id->last_lun & 0x7;
#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
/* /*
* EATA SCSI controllers do a hardware ATA emulation: * EATA SCSI controllers do a hardware ATA emulation:
* Ignore them if there is a driver for them available. * Ignore them if there is a driver for them available.
*/ */
if ((id->model[0] == 'P' && id->model[1] == 'M') if ((id->model[0] == 'P' && id->model[1] == 'M') ||
|| (id->model[0] == 'S' && id->model[1] == 'K')) { (id->model[0] == 'S' && id->model[1] == 'K')) {
printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
goto err_misc; goto err_misc;
} }
...@@ -105,16 +128,18 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -105,16 +128,18 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */ if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */
|| (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */ || (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */
|| (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */ || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */
bswap ^= 1; /* Vertos drives may still be weird */ /* Vertos drives may still be weird */
bswap ^= 1;
} }
ide_fixstring (id->model, sizeof(id->model), bswap); ide_fixstring(id->model, sizeof(id->model), bswap);
ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap); ide_fixstring(id->fw_rev, sizeof(id->fw_rev), bswap);
ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);
if (strstr(id->model, "E X A B Y T E N E S T")) if (strstr(id->model, "E X A B Y T E N E S T"))
goto err_misc; goto err_misc;
id->model[sizeof(id->model)-1] = '\0'; /* we depend on this a lot! */ /* we depend on this a lot! */
id->model[sizeof(id->model)-1] = '\0';
printk("%s: %s, ", drive->name, id->model); printk("%s: %s, ", drive->name, id->model);
drive->present = 1; drive->present = 1;
...@@ -122,7 +147,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -122,7 +147,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
* Check for an ATAPI device * Check for an ATAPI device
*/ */
if (cmd == WIN_PIDENTIFY) { if (cmd == WIN_PIDENTIFY) {
byte type = (id->config >> 8) & 0x1f; u8 type = (id->config >> 8) & 0x1f;
printk("ATAPI "); printk("ATAPI ");
#ifdef CONFIG_BLK_DEV_PDC4030 #ifdef CONFIG_BLK_DEV_PDC4030
if (hwif->channel == 1 && hwif->chipset == ide_pdc4030) { if (hwif->channel == 1 && hwif->chipset == ide_pdc4030) {
...@@ -142,7 +167,8 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -142,7 +167,8 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
break; break;
} }
} }
type = ide_cdrom; /* Early cdrom models used zero */ /* Early cdrom models used zero */
type = ide_cdrom;
case ide_cdrom: case ide_cdrom:
drive->removable = 1; drive->removable = 1;
#ifdef CONFIG_PPC #ifdef CONFIG_PPC
...@@ -182,16 +208,18 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -182,16 +208,18 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
* slave drive if the hwif is actually a flash memory card of * slave drive if the hwif is actually a flash memory card of
* some variety: * some variety:
*/ */
drive->is_flash = 0;
if (drive_is_flashcard(drive)) { if (drive_is_flashcard(drive)) {
ide_drive_t *mate = &hwif->drives[1^drive->select.b.unit]; ide_drive_t *mate = &hwif->drives[1^drive->select.b.unit];
if (!mate->ata_flash) { if (!mate->ata_flash) {
mate->present = 0; mate->present = 0;
mate->noprobe = 1; mate->noprobe = 1;
} }
drive->is_flash = 1;
} }
drive->media = ide_disk; drive->media = ide_disk;
printk("ATA DISK drive\n"); printk("%s DISK drive\n", (drive->is_flash) ? "CFA" : "ATA" );
QUIRK_LIST(hwif, drive); QUIRK_LIST(drive);
return; return;
err_misc: err_misc:
...@@ -211,68 +239,80 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -211,68 +239,80 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
* 1 device timed-out (no response to identify request) * 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself) * 2 device aborted the command (refused to identify itself)
*/ */
static int actual_try_to_identify (ide_drive_t *drive, byte cmd) static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
{ {
// ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
int rc; int rc;
ide_ioreg_t hd_status; ide_ioreg_t hd_status;
unsigned long timeout; unsigned long timeout;
byte s, a; u8 s = 0, a = 0;
if (IDE_CONTROL_REG) { if (IDE_CONTROL_REG) {
/* take a deep breath */ /* take a deep breath */
ide_delay_50ms(); ide_delay_50ms();
a = IN_BYTE(IDE_ALTSTATUS_REG); a = hwif->INB(IDE_ALTSTATUS_REG);
s = IN_BYTE(IDE_STATUS_REG); s = hwif->INB(IDE_STATUS_REG);
if ((a ^ s) & ~INDEX_STAT) { if ((a ^ s) & ~INDEX_STAT) {
printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a); printk("%s: probing with STATUS(0x%02x) instead of "
hd_status = IDE_STATUS_REG; /* ancient Seagate drives, broken interfaces */ "ALTSTATUS(0x%02x)\n", drive->name, s, a);
/* ancient Seagate drives, broken interfaces */
hd_status = IDE_STATUS_REG;
} else { } else {
hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */ /* use non-intrusive polling */
hd_status = IDE_ALTSTATUS_REG;
} }
} else { } else {
ide_delay_50ms(); ide_delay_50ms();
hd_status = IDE_STATUS_REG; hd_status = IDE_STATUS_REG;
} }
/* set features register for atapi identify command to be sure of reply */ /* set features register for atapi
* identify command to be sure of reply
*/
if ((cmd == WIN_PIDENTIFY)) if ((cmd == WIN_PIDENTIFY))
OUT_BYTE(0,IDE_FEATURE_REG); /* disable dma & overlap */ /* disable dma & overlap */
hwif->OUTB(0, IDE_FEATURE_REG);
#if CONFIG_BLK_DEV_PDC4030 if (hwif->identify != NULL) {
if (HWIF(drive)->chipset == ide_pdc4030) { if (hwif->identify(drive))
/* DC4030 hosted drives need their own identify... */
extern int pdc4030_identify(ide_drive_t *);
if (pdc4030_identify(drive)) {
return 1; return 1;
} } else {
} else /* ask drive for ID */
#endif /* CONFIG_BLK_DEV_PDC4030 */ hwif->OUTB(cmd, IDE_COMMAND_REG);
OUT_BYTE(cmd,IDE_COMMAND_REG); /* ask drive for ID */ }
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
timeout += jiffies; timeout += jiffies;
do { do {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
return 1; /* drive timed-out */ /* drive timed-out */
return 1;
} }
ide_delay_50ms(); /* give drive a breather */ /* give drive a breather */
} while (IN_BYTE(hd_status) & BUSY_STAT); ide_delay_50ms();
} while ((hwif->INB(hd_status)) & BUSY_STAT);
ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ /* wait for IRQ and DRQ_STAT */
if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { ide_delay_50ms();
if (OK_STAT((hwif->INB(IDE_STATUS_REG)), DRQ_STAT, BAD_R_STAT)) {
unsigned long flags; unsigned long flags;
/* local CPU only; some systems need this */
local_irq_save(flags); local_irq_save(flags);
/* local CPU only; some systems need this */ /* drive returned ID */
do_identify(drive, cmd); /* drive returned ID */ do_identify(drive, cmd);
rc = 0; /* drive responded with ID */ /* drive responded with ID */
(void) GET_STAT(); /* clear drive IRQ */ rc = 0;
/* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG);
local_irq_restore(flags); local_irq_restore(flags);
} else } else {
rc = 2; /* drive refused ID */ /* drive refused ID */
rc = 2;
}
return rc; return rc;
} }
static int try_to_identify (ide_drive_t *drive, byte cmd) static int try_to_identify (ide_drive_t *drive, u8 cmd)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
int retval; int retval;
...@@ -282,26 +322,34 @@ static int try_to_identify (ide_drive_t *drive, byte cmd) ...@@ -282,26 +322,34 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
if (IDE_CONTROL_REG && !hwif->irq) { if (IDE_CONTROL_REG && !hwif->irq) {
autoprobe = 1; autoprobe = 1;
cookie = probe_irq_on(); cookie = probe_irq_on();
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */ /* enable device irq */
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
} }
retval = actual_try_to_identify(drive, cmd); retval = actual_try_to_identify(drive, cmd);
if (autoprobe) { if (autoprobe) {
int irq; int irq;
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */ /* mask device irq */
(void) GET_STAT(); /* clear drive IRQ */ hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG);
/* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG);
udelay(5); udelay(5);
irq = probe_irq_off(cookie); irq = probe_irq_off(cookie);
if (!hwif->irq) { if (!hwif->irq) {
if (irq > 0) { if (irq > 0) {
hwif->irq = irq; hwif->irq = irq;
} else { /* Mmmm.. multiple IRQs.. don't know which was ours */ } else {
printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie); /* Mmmm.. multiple IRQs..
* don't know which was ours
*/
printk("%s: IRQ probe failed (0x%lx)\n",
drive->name, cookie);
#ifdef CONFIG_BLK_DEV_CMD640 #ifdef CONFIG_BLK_DEV_CMD640
#ifdef CMD640_DUMP_REGS #ifdef CMD640_DUMP_REGS
if (hwif->chipset == ide_cmd640) { if (hwif->chipset == ide_cmd640) {
printk("%s: Hmmm.. probably a driver problem.\n", drive->name); printk("%s: Hmmm.. probably a driver "
"problem.\n", drive->name);
CMD640_DUMP_REGS; CMD640_DUMP_REGS;
} }
#endif /* CMD640_DUMP_REGS */ #endif /* CMD640_DUMP_REGS */
...@@ -329,11 +377,13 @@ static int try_to_identify (ide_drive_t *drive, byte cmd) ...@@ -329,11 +377,13 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
* 3 bad status from device (possible for ATAPI drives) * 3 bad status from device (possible for ATAPI drives)
* 4 probe was not attempted because failure was obvious * 4 probe was not attempted because failure was obvious
*/ */
static int do_probe (ide_drive_t *drive, byte cmd) static int do_probe (ide_drive_t *drive, u8 cmd)
{ {
int rc; int rc;
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
if (drive->present) { /* avoid waiting for inappropriate probes */
if (drive->present) {
/* avoid waiting for inappropriate probes */
if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY)) if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
return 4; return 4;
} }
...@@ -342,43 +392,64 @@ static int do_probe (ide_drive_t *drive, byte cmd) ...@@ -342,43 +392,64 @@ static int do_probe (ide_drive_t *drive, byte cmd)
drive->name, drive->present, drive->media, drive->name, drive->present, drive->media,
(cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI"); (cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI");
#endif #endif
ide_delay_50ms(); /* needed for some systems (e.g. crw9624 as drive0 with disk as slave) */
SELECT_DRIVE(hwif,drive); /* needed for some systems
* (e.g. crw9624 as drive0 with disk as slave)
*/
ide_delay_50ms(); ide_delay_50ms();
if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) { SELECT_DRIVE(drive);
ide_delay_50ms();
if (hwif->INB(IDE_SELECT_REG) != drive->select.all && !drive->present) {
if (drive->select.b.unit != 0) { if (drive->select.b.unit != 0) {
SELECT_DRIVE(hwif,&hwif->drives[0]); /* exit with drive0 selected */ /* exit with drive0 selected */
ide_delay_50ms(); /* allow BUSY_STAT to assert & clear */ SELECT_DRIVE(&hwif->drives[0]);
/* allow BUSY_STAT to assert & clear */
ide_delay_50ms();
} }
return 3; /* no i/f present: mmm.. this should be a 4 -ml */ /* no i/f present: mmm.. this should be a 4 -ml */
return 3;
} }
if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT) || if (OK_STAT((hwif->INB(IDE_STATUS_REG)), READY_STAT, BUSY_STAT) ||
drive->present || cmd == WIN_PIDENTIFY) { drive->present || cmd == WIN_PIDENTIFY) {
if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */ /* send cmd and wait */
rc = try_to_identify(drive,cmd); /* failed: try again */ if ((rc = try_to_identify(drive, cmd))) {
/* failed: try again */
rc = try_to_identify(drive,cmd);
}
if (hwif->INB(IDE_STATUS_REG) == (BUSY_STAT|READY_STAT))
return 4;
if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) { if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) {
unsigned long timeout; unsigned long timeout;
printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT()); printk("%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name,
hwif->INB(IDE_STATUS_REG));
ide_delay_50ms(); ide_delay_50ms();
OUT_BYTE (drive->select.all, IDE_SELECT_REG); hwif->OUTB(drive->select.all, IDE_SELECT_REG);
ide_delay_50ms(); ide_delay_50ms();
OUT_BYTE(WIN_SRST, IDE_COMMAND_REG); hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
timeout = jiffies; timeout = jiffies;
while ((GET_STAT() & BUSY_STAT) && time_before(jiffies, timeout + WAIT_WORSTCASE)) while (((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) &&
time_before(jiffies, timeout + WAIT_WORSTCASE))
ide_delay_50ms(); ide_delay_50ms();
rc = try_to_identify(drive, cmd); rc = try_to_identify(drive, cmd);
} }
if (rc == 1) if (rc == 1)
printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT()); printk("%s: no response (status = 0x%02x)\n",
(void) GET_STAT(); /* ensure drive irq is clear */ drive->name, hwif->INB(IDE_STATUS_REG));
/* ensure drive irq is clear */
(void) hwif->INB(IDE_STATUS_REG);
} else { } else {
rc = 3; /* not present or maybe ATAPI */ /* not present or maybe ATAPI */
rc = 3;
} }
if (drive->select.b.unit != 0) { if (drive->select.b.unit != 0) {
SELECT_DRIVE(hwif,&hwif->drives[0]); /* exit with drive0 selected */ /* exit with drive0 selected */
SELECT_DRIVE(&hwif->drives[0]);
ide_delay_50ms(); ide_delay_50ms();
(void) GET_STAT(); /* ensure drive irq is clear */ /* ensure drive irq is clear */
(void) hwif->INB(IDE_STATUS_REG);
} }
return rc; return rc;
} }
...@@ -392,9 +463,9 @@ static void enable_nest (ide_drive_t *drive) ...@@ -392,9 +463,9 @@ static void enable_nest (ide_drive_t *drive)
unsigned long timeout; unsigned long timeout;
printk("%s: enabling %s -- ", hwif->name, drive->id->model); printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(hwif, drive); SELECT_DRIVE(drive);
ide_delay_50ms(); ide_delay_50ms();
OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE; timeout = jiffies + WAIT_WORSTCASE;
do { do {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
...@@ -402,15 +473,21 @@ static void enable_nest (ide_drive_t *drive) ...@@ -402,15 +473,21 @@ static void enable_nest (ide_drive_t *drive)
return; return;
} }
ide_delay_50ms(); ide_delay_50ms();
} while (GET_STAT() & BUSY_STAT); } while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT);
ide_delay_50ms(); ide_delay_50ms();
if (!OK_STAT(GET_STAT(), 0, BAD_STAT))
printk("failed (status = 0x%02x)\n", GET_STAT()); if (!OK_STAT((hwif->INB(IDE_STATUS_REG)), 0, BAD_STAT)) {
else printk("failed (status = 0x%02x)\n", hwif->INB(IDE_STATUS_REG));
} else {
printk("success\n"); printk("success\n");
}
if (do_probe(drive, WIN_IDENTIFY) >= 2) /* if !(success||timed-out) */ /* if !(success||timed-out) */
(void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */ if (do_probe(drive, WIN_IDENTIFY) >= 2) {
/* look for ATAPI device */
(void) do_probe(drive, WIN_PIDENTIFY);
}
} }
/* /*
...@@ -419,102 +496,99 @@ static void enable_nest (ide_drive_t *drive) ...@@ -419,102 +496,99 @@ static void enable_nest (ide_drive_t *drive)
* Returns: 0 no device was found * Returns: 0 no device was found
* 1 device was found (note: drive->present might still be 0) * 1 device was found (note: drive->present might still be 0)
*/ */
static inline byte probe_for_drive (ide_drive_t *drive) static inline u8 probe_for_drive (ide_drive_t *drive)
{ {
if (drive->noprobe) /* skip probing? */ /* skip probing? */
if (drive->noprobe)
return drive->present; return drive->present;
if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
(void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */ /* if !(success||timed-out) */
if (do_probe(drive, WIN_IDENTIFY) >= 2) {
/* look for ATAPI device */
(void) do_probe(drive, WIN_PIDENTIFY);
} }
if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T")) if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T"))
enable_nest(drive); enable_nest(drive);
if (!drive->present) if (!drive->present)
return 0; /* drive not found */ /* drive not found */
if (drive->id == NULL) { /* identification failed? */ return 0;
/* identification failed? */
if (drive->id == NULL) {
if (drive->media == ide_disk) { if (drive->media == ide_disk) {
printk ("%s: non-IDE drive, CHS=%d/%d/%d\n", printk("%s: non-IDE drive, CHS=%d/%d/%d\n",
drive->name, drive->cyl, drive->head, drive->sect); drive->name, drive->cyl,
drive->head, drive->sect);
} else if (drive->media == ide_cdrom) { } else if (drive->media == ide_cdrom) {
printk("%s: ATAPI cdrom (?)\n", drive->name); printk("%s: ATAPI cdrom (?)\n", drive->name);
} else { } else {
drive->present = 0; /* nuke it */ /* nuke it */
drive->present = 0;
} }
} }
return 1; /* drive was found */ /* drive was found */
return 1;
} }
/* #define hwif_check_region(addr, num) \
* Calculate the region that this interface occupies, ((hwif->mmio) ? check_mem_region((addr),(num)) : check_region((addr),(num)))
* handling interfaces where the registers may not be
* ordered sanely. We deal with the CONTROL register
* separately.
*/
static int hwif_check_regions (ide_hwif_t *hwif) static int hwif_check_regions (ide_hwif_t *hwif)
{ {
int region_errors = 0; u32 i = 0;
int addr_errs = 0;
hwif->straight8 = 0;
region_errors = ide_check_region(hwif->io_ports[IDE_DATA_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_ERROR_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_LCYL_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_HCYL_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_SELECT_OFFSET], 1);
region_errors += ide_check_region(hwif->io_ports[IDE_STATUS_OFFSET], 1);
if (hwif->mmio == 2)
return 0;
addr_errs = hwif_check_region(hwif->io_ports[IDE_DATA_OFFSET], 1);
for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; i++)
addr_errs += hwif_check_region(hwif->io_ports[i], 1);
if (hwif->io_ports[IDE_CONTROL_OFFSET]) if (hwif->io_ports[IDE_CONTROL_OFFSET])
region_errors += ide_check_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); addr_errs += hwif_check_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (hwif->io_ports[IDE_IRQ_OFFSET]) if (hwif->io_ports[IDE_IRQ_OFFSET])
region_errors += ide_check_region(hwif->io_ports[IDE_IRQ_OFFSET], 1); addr_errs += hwif_check_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ #endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
/* /* If any errors are return, we drop the hwif interface. */
* If any errors are return, we drop the hwif interface. hwif->straight8 = 0;
*/ return(addr_errs);
return(region_errors);
} }
//EXPORT_SYMBOL(hwif_check_regions);
#define hwif_request_region(addr, num, name) \
((hwif->mmio) ? request_mem_region((addr),(num),(name)) : request_region((addr),(num),(name)))
static void hwif_register (ide_hwif_t *hwif) static void hwif_register (ide_hwif_t *hwif)
{ {
if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) == u32 i = 0;
((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name); if (hwif->mmio == 2)
hwif->straight8 = 1; return;
goto jump_straight8;
}
if (hwif->io_ports[IDE_DATA_OFFSET])
ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_ERROR_OFFSET])
ide_request_region(hwif->io_ports[IDE_ERROR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_NSECTOR_OFFSET])
ide_request_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_SECTOR_OFFSET])
ide_request_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_LCYL_OFFSET])
ide_request_region(hwif->io_ports[IDE_LCYL_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_HCYL_OFFSET])
ide_request_region(hwif->io_ports[IDE_HCYL_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_SELECT_OFFSET])
ide_request_region(hwif->io_ports[IDE_SELECT_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_STATUS_OFFSET])
ide_request_region(hwif->io_ports[IDE_STATUS_OFFSET], 1, hwif->name);
jump_straight8:
if (hwif->io_ports[IDE_CONTROL_OFFSET]) if (hwif->io_ports[IDE_CONTROL_OFFSET])
ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name); hwif_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name);
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (hwif->io_ports[IDE_IRQ_OFFSET]) if (hwif->io_ports[IDE_IRQ_OFFSET])
ide_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name); hwif_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name);
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ #endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
hwif_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name);
hwif->straight8 = 1;
return;
}
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
hwif_request_region(hwif->io_ports[i], 1, hwif->name);
} }
//EXPORT_SYMBOL(hwif_register);
/* /*
* This routine only knows how to look for drive units 0 and 1 * This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here. * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
*/ */
static void probe_hwif (ide_hwif_t *hwif) void probe_hwif (ide_hwif_t *hwif)
{ {
unsigned int unit; unsigned int unit;
unsigned long flags; unsigned long flags;
...@@ -524,8 +598,7 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -524,8 +598,7 @@ static void probe_hwif (ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDE #ifdef CONFIG_BLK_DEV_IDE
if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) { if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
extern void probe_cmos_for_drives(ide_hwif_t *); extern void probe_cmos_for_drives(ide_hwif_t *);
probe_cmos_for_drives(hwif);
probe_cmos_for_drives (hwif);
} }
#endif #endif
...@@ -534,20 +607,25 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -534,20 +607,25 @@ static void probe_hwif (ide_hwif_t *hwif)
(hwif->chipset != ide_pdc4030 || hwif->channel == 0) && (hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
#endif /* CONFIG_BLK_DEV_PDC4030 */ #endif /* CONFIG_BLK_DEV_PDC4030 */
(hwif_check_regions(hwif))) { (hwif_check_regions(hwif))) {
int msgout = 0; u16 msgout = 0;
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) { if (drive->present) {
drive->present = 0; drive->present = 0;
printk("%s: ERROR, PORTS ALREADY IN USE\n", drive->name); printk("%s: ERROR, PORTS ALREADY IN USE\n",
drive->name);
msgout = 1; msgout = 1;
} }
} }
if (!msgout) if (!msgout)
printk("%s: ports already in use, skipping probe\n", hwif->name); printk("%s: ports already in use, skipping probe\n",
hwif->name);
return; return;
} }
if (hwif->hw.ack_intr && hwif->irq)
disable_irq(hwif->irq);
local_irq_set(flags); local_irq_set(flags);
/* /*
* Second drive should only exist if first drive was found, * Second drive should only exist if first drive was found,
...@@ -556,7 +634,8 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -556,7 +634,8 @@ static void probe_hwif (ide_hwif_t *hwif)
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
drive->dn = ((hwif->channel ? 2 : 0) + unit); drive->dn = ((hwif->channel ? 2 : 0) + unit);
(void) probe_for_drive (drive); hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit);
(void) probe_for_drive(drive);
if (drive->present && !hwif->present) { if (drive->present && !hwif->present) {
hwif->present = 1; hwif->present = 1;
if (hwif->chipset != ide_4drives || if (hwif->chipset != ide_4drives ||
...@@ -567,40 +646,76 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -567,40 +646,76 @@ static void probe_hwif (ide_hwif_t *hwif)
} }
if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
unsigned long timeout = jiffies + WAIT_WORSTCASE; unsigned long timeout = jiffies + WAIT_WORSTCASE;
byte stat; u8 stat;
printk("%s: reset\n", hwif->name); printk("%s: reset\n", hwif->name);
OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
udelay(10); udelay(10);
OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do { do {
ide_delay_50ms(); ide_delay_50ms();
stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
} while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); } while ((stat & BUSY_STAT) && time_after(timeout, jiffies));
} }
local_irq_restore(flags); local_irq_restore(flags);
if (hwif->hw.ack_intr && hwif->irq)
enable_irq(hwif->irq);
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) { if (drive->present) {
if (hwif->tuneproc != NULL && drive->autotune == 1) if (hwif->tuneproc != NULL && drive->autotune == 1)
/* auto-tune PIO mode */ /* auto-tune PIO mode */
hwif->tuneproc(drive, 255); hwif->tuneproc(drive, 255);
/*
if ((drive->autotune != 2) && hwif->dmaproc != NULL) { * MAJOR HACK BARF :-/
*
* FIXME: chipsets own this cruft!
*/
/*
* Move here to prevent module loading clashing.
*/
// drive->autodma = hwif->autodma;
if ((drive->autotune != 2) && (hwif->ide_dma_check)) {
/* /*
* Force DMAing for the beginning of the check. * Force DMAing for the beginning of the check.
* Some chipsets appear to do interesting * Some chipsets appear to do interesting
* things, if not checked and cleared. * things, if not checked and cleared.
* PARANOIA!!! * PARANOIA!!!
*/ */
hwif->dmaproc(ide_dma_off_quietly, drive); hwif->ide_dma_off_quietly(drive);
hwif->dmaproc(ide_dma_check, drive); hwif->ide_dma_check(drive);
} }
} }
} }
} }
EXPORT_SYMBOL(probe_hwif);
int hwif_init (ide_hwif_t *hwif);
int probe_hwif_init (ide_hwif_t *hwif)
{
hwif->initializing = 1;
probe_hwif(hwif);
hwif_init(hwif);
#if 1
if (hwif->present) {
u16 unit = 0;
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
if (drive->present)
ata_attach(drive);
}
}
#endif
hwif->initializing = 0;
return 0;
}
EXPORT_SYMBOL(probe_hwif_init);
#if MAX_HWIFS > 1 #if MAX_HWIFS > 1
/* /*
* save_match() is used to simplify logic in init_irq() below. * save_match() is used to simplify logic in init_irq() below.
...@@ -613,7 +728,7 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -613,7 +728,7 @@ static void probe_hwif (ide_hwif_t *hwif)
* *
* This routine detects and reports such situations, but does not fix them. * This routine detects and reports such situations, but does not fix them.
*/ */
static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
{ {
ide_hwif_t *m = *match; ide_hwif_t *m = *match;
...@@ -626,6 +741,7 @@ static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) ...@@ -626,6 +741,7 @@ static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */ if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
*match = new; *match = new;
} }
EXPORT_SYMBOL(save_match);
#endif /* MAX_HWIFS > 1 */ #endif /* MAX_HWIFS > 1 */
/* /*
...@@ -667,17 +783,20 @@ static void ide_init_queue(ide_drive_t *drive) ...@@ -667,17 +783,20 @@ static void ide_init_queue(ide_drive_t *drive)
* but anything else has led to problems on some machines. We re-enable * but anything else has led to problems on some machines. We re-enable
* interrupts as much as we can safely do in most places. * interrupts as much as we can safely do in most places.
*/ */
static int init_irq (ide_hwif_t *hwif) int init_irq (ide_hwif_t *hwif)
{ {
unsigned long flags; unsigned long flags;
unsigned int index; unsigned int index;
ide_hwgroup_t *hwgroup, *new_hwgroup; ide_hwgroup_t *hwgroup, *new_hwgroup;
ide_hwif_t *match = NULL; ide_hwif_t *match = NULL;
#if 0
/* Allocate the buffer and no sleep allowed */
new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_ATOMIC);
#else
/* Allocate the buffer and potentially sleep first */ /* Allocate the buffer and potentially sleep first */
new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL); new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
#endif
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
...@@ -691,7 +810,8 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -691,7 +810,8 @@ static int init_irq (ide_hwif_t *hwif)
if (h->hwgroup) { /* scan only initialized hwif's */ if (h->hwgroup) { /* scan only initialized hwif's */
if (hwif->irq == h->irq) { if (hwif->irq == h->irq) {
hwif->sharing_irq = h->sharing_irq = 1; hwif->sharing_irq = h->sharing_irq = 1;
if (hwif->chipset != ide_pci || h->chipset != ide_pci) { if (hwif->chipset != ide_pci ||
h->chipset != ide_pci) {
save_match(hwif, h, &match); save_match(hwif, h, &match);
} }
} }
...@@ -734,16 +854,23 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -734,16 +854,23 @@ static int init_irq (ide_hwif_t *hwif)
* Allocate the irq, if not already obtained for another hwif * Allocate the irq, if not already obtained for another hwif
*/ */
if (!match || match->irq != hwif->irq) { if (!match || match->irq != hwif->irq) {
#ifdef CONFIG_IDEPCI_SHARE_IRQ int sa = SA_INTERRUPT;
int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_SHIRQ : SA_INTERRUPT; #if defined(__mc68000__) || defined(CONFIG_APUS)
#else /* !CONFIG_IDEPCI_SHARE_IRQ */ sa = SA_SHIRQ;
int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; #endif /* __mc68000__ || CONFIG_APUS */
if (IDE_CHIPSET_IS_PCI(hwif->chipset)) {
sa = SA_SHIRQ;
#ifndef CONFIG_IDEPCI_SHARE_IRQ
sa |= SA_INTERRUPT;
#endif /* CONFIG_IDEPCI_SHARE_IRQ */ #endif /* CONFIG_IDEPCI_SHARE_IRQ */
}
if (hwif->io_ports[IDE_CONTROL_OFFSET]) if (hwif->io_ports[IDE_CONTROL_OFFSET])
OUT_BYTE(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */ /* clear nIEN */
hwif->OUTB(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]);
if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) { if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) {
if (!match) if (!match)
kfree(hwgroup); kfree(hwgroup);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
...@@ -774,11 +901,12 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -774,11 +901,12 @@ static int init_irq (ide_hwif_t *hwif)
printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name); printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);
#endif #endif
} }
/* all CPUs; safe now that hwif->hwgroup is set up */
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
/* all CPUs; safe now that hwif->hwgroup is set up */
#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name, printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
hwif->io_ports[IDE_DATA_OFFSET], hwif->io_ports[IDE_DATA_OFFSET],
hwif->io_ports[IDE_DATA_OFFSET]+7, hwif->io_ports[IDE_DATA_OFFSET]+7,
hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq); hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
...@@ -788,7 +916,7 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -788,7 +916,7 @@ static int init_irq (ide_hwif_t *hwif)
hwif->io_ports[IDE_DATA_OFFSET]+7, hwif->io_ports[IDE_DATA_OFFSET]+7,
hwif->io_ports[IDE_CONTROL_OFFSET], __irq_itoa(hwif->irq)); hwif->io_ports[IDE_CONTROL_OFFSET], __irq_itoa(hwif->irq));
#else #else
printk("%s at %p on irq 0x%08x", hwif->name, printk("%s at %x on irq 0x%08x", hwif->name,
hwif->io_ports[IDE_DATA_OFFSET], hwif->irq); hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
#endif /* __mc68000__ && CONFIG_APUS */ #endif /* __mc68000__ && CONFIG_APUS */
if (match) if (match)
...@@ -798,6 +926,8 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -798,6 +926,8 @@ static int init_irq (ide_hwif_t *hwif)
return 0; return 0;
} }
EXPORT_SYMBOL(init_irq);
/* /*
* init_gendisk() (as opposed to ide_geninit) is called for each major device, * init_gendisk() (as opposed to ide_geninit) is called for each major device,
* after probing for drives, to allocate partition tables and other data * after probing for drives, to allocate partition tables and other data
...@@ -811,15 +941,7 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -811,15 +941,7 @@ static void init_gendisk (ide_hwif_t *hwif)
extern devfs_handle_t ide_devfs_handle; extern devfs_handle_t ide_devfs_handle;
char *names; char *names;
#if 1
units = MAX_DRIVES; units = MAX_DRIVES;
#else
/* figure out maximum drive number on the interface */
for (units = MAX_DRIVES; units > 0; --units) {
if (hwif->drives[units-1].present)
break;
}
#endif
minors = units * (1<<PARTN_BITS); minors = units * (1<<PARTN_BITS);
gd = kmalloc(MAX_DRIVES * sizeof(struct gendisk), GFP_KERNEL); gd = kmalloc(MAX_DRIVES * sizeof(struct gendisk), GFP_KERNEL);
...@@ -827,7 +949,7 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -827,7 +949,7 @@ static void init_gendisk (ide_hwif_t *hwif)
goto err_kmalloc_gd; goto err_kmalloc_gd;
memset(gd, 0, MAX_DRIVES * sizeof(struct gendisk)); memset(gd, 0, MAX_DRIVES * sizeof(struct gendisk));
names = kmalloc (4 * MAX_DRIVES, GFP_KERNEL); names = kmalloc(4 * MAX_DRIVES, GFP_KERNEL);
if (!names) if (!names)
goto err_kmalloc_gd_names; goto err_kmalloc_gd_names;
memset(names, 0, 4 * MAX_DRIVES); memset(names, 0, 4 * MAX_DRIVES);
...@@ -843,7 +965,6 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -843,7 +965,6 @@ static void init_gendisk (ide_hwif_t *hwif)
} }
for (unit = 0; unit < units; ++unit) { for (unit = 0; unit < units; ++unit) {
#if 1
char name[64]; char name[64];
ide_add_generic_settings(hwif->drives + unit); ide_add_generic_settings(hwif->drives + unit);
sprintf (name, "host%d/bus%d/target%d/lun%d", sprintf (name, "host%d/bus%d/target%d/lun%d",
...@@ -852,18 +973,6 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -852,18 +973,6 @@ static void init_gendisk (ide_hwif_t *hwif)
hwif->channel, unit, hwif->drives[unit].lun); hwif->channel, unit, hwif->drives[unit].lun);
if (hwif->drives[unit].present) if (hwif->drives[unit].present)
hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL); hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL);
#else
if (hwif->drives[unit].present) {
char name[64];
ide_add_generic_settings(hwif->drives + unit);
sprintf (name, "host%d/bus%d/target%d/lun%d",
(hwif->channel && hwif->mate) ? hwif->mate->index : hwif->index,
hwif->channel, unit, hwif->drives[unit].lun);
hwif->drives[unit].de =
devfs_mk_dir (ide_devfs_handle, name, NULL);
}
#endif
} }
return; return;
...@@ -873,7 +982,9 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -873,7 +982,9 @@ static void init_gendisk (ide_hwif_t *hwif)
printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n"); printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n");
} }
static int hwif_init (ide_hwif_t *hwif) EXPORT_SYMBOL(init_gendisk);
int hwif_init (ide_hwif_t *hwif)
{ {
if (!hwif->present) if (!hwif->present)
return 0; return 0;
...@@ -891,8 +1002,9 @@ static int hwif_init (ide_hwif_t *hwif) ...@@ -891,8 +1002,9 @@ static int hwif_init (ide_hwif_t *hwif)
return (hwif->present = 0); return (hwif->present = 0);
} }
#endif /* CONFIG_BLK_DEV_HD */ #endif /* CONFIG_BLK_DEV_HD */
hwif->present = 0; /* we set it back to 1 if all is ok below */ /* we set it back to 1 if all is ok below */
hwif->present = 0;
if (register_blkdev (hwif->major, hwif->name, ide_fops)) { if (register_blkdev (hwif->major, hwif->name, ide_fops)) {
printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", printk("%s: UNABLE TO GET MAJOR NUMBER %d\n",
...@@ -909,13 +1021,13 @@ static int hwif_init (ide_hwif_t *hwif) ...@@ -909,13 +1021,13 @@ static int hwif_init (ide_hwif_t *hwif)
if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) { if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
printk("%s: Disabled unable to get IRQ %d.\n", printk("%s: Disabled unable to get IRQ %d.\n",
hwif->name, i); hwif->name, i);
(void) unregister_blkdev (hwif->major, hwif->name); (void) unregister_blkdev(hwif->major, hwif->name);
return (hwif->present = 0); return (hwif->present = 0);
} }
if (init_irq(hwif)) { if (init_irq(hwif)) {
printk("%s: probed IRQ %d and default IRQ %d failed.\n", printk("%s: probed IRQ %d and default IRQ %d failed.\n",
hwif->name, i, hwif->irq); hwif->name, i, hwif->irq);
(void) unregister_blkdev (hwif->major, hwif->name); (void) unregister_blkdev(hwif->major, hwif->name);
return (hwif->present = 0); return (hwif->present = 0);
} }
printk("%s: probed IRQ %d failed, using default.\n", printk("%s: probed IRQ %d failed, using default.\n",
...@@ -926,28 +1038,23 @@ static int hwif_init (ide_hwif_t *hwif) ...@@ -926,28 +1038,23 @@ static int hwif_init (ide_hwif_t *hwif)
blk_dev[hwif->major].data = hwif; blk_dev[hwif->major].data = hwif;
blk_dev[hwif->major].queue = ide_get_queue; blk_dev[hwif->major].queue = ide_get_queue;
hwif->present = 1; /* success */ hwif->present = 1; /* success */
return 1;
#if (DEBUG_SPINLOCK > 0)
{
static int done = 0;
if (!done++)
printk("ide_lock is %p\n", &ide_lock); /* FIXME */
}
#endif
return hwif->present;
} }
EXPORT_SYMBOL(hwif_init);
void export_ide_init_queue (ide_drive_t *drive) void export_ide_init_queue (ide_drive_t *drive)
{ {
ide_init_queue(drive); ide_init_queue(drive);
} }
byte export_probe_for_drive (ide_drive_t *drive) EXPORT_SYMBOL(export_ide_init_queue);
u8 export_probe_for_drive (ide_drive_t *drive)
{ {
return probe_for_drive(drive); return probe_for_drive(drive);
} }
EXPORT_SYMBOL(export_ide_init_queue);
EXPORT_SYMBOL(export_probe_for_drive); EXPORT_SYMBOL(export_probe_for_drive);
int ideprobe_init (void); int ideprobe_init (void);
...@@ -961,7 +1068,7 @@ int ideprobe_init (void) ...@@ -961,7 +1068,7 @@ int ideprobe_init (void)
{ {
unsigned int index; unsigned int index;
int probe[MAX_HWIFS]; int probe[MAX_HWIFS];
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
memset(probe, 0, MAX_HWIFS * sizeof(int)); memset(probe, 0, MAX_HWIFS * sizeof(int));
for (index = 0; index < MAX_HWIFS; ++index) for (index = 0; index < MAX_HWIFS; ++index)
...@@ -976,7 +1083,7 @@ int ideprobe_init (void) ...@@ -976,7 +1083,7 @@ int ideprobe_init (void)
for (index = 0; index < MAX_HWIFS; ++index) for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index]) if (probe[index])
hwif_init(&ide_hwifs[index]); hwif_init(&ide_hwifs[index]);
for (index = 0; index < MAX_HWIFS; ++index) for (index = 0; index < MAX_HWIFS; ++index) {
if (probe[index]) { if (probe[index]) {
ide_hwif_t *hwif = &ide_hwifs[index]; ide_hwif_t *hwif = &ide_hwifs[index];
int unit; int unit;
...@@ -985,6 +1092,7 @@ int ideprobe_init (void) ...@@ -985,6 +1092,7 @@ int ideprobe_init (void)
for (unit = 0; unit < MAX_DRIVES; ++unit) for (unit = 0; unit < MAX_DRIVES; ++unit)
ata_attach(&hwif->drives[unit]); ata_attach(&hwif->drives[unit]);
} }
}
if (!ide_probe) if (!ide_probe)
ide_probe = &ideprobe_module; ide_probe = &ideprobe_module;
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment