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 @@
#include <asm/uaccess.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);
int bswap = 1;
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) {
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;
}
/* read 512 bytes of id info */
#if 1
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
hwif->ata_input_data(drive, id, SECTOR_WORDS);
local_irq_enable();
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)
drive->last_lun = id->last_lun & 0x7;
#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
/*
* EATA SCSI controllers do a hardware ATA emulation:
* Ignore them if there is a driver for them available.
*/
if ((id->model[0] == 'P' && id->model[1] == 'M')
|| (id->model[0] == 'S' && id->model[1] == 'K')) {
if ((id->model[0] == 'P' && id->model[1] == 'M') ||
(id->model[0] == 'S' && id->model[1] == 'K')) {
printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
goto err_misc;
}
......@@ -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 */
|| (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */
|| (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->fw_rev, sizeof(id->fw_rev), bswap);
ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap);
ide_fixstring(id->model, sizeof(id->model), bswap);
ide_fixstring(id->fw_rev, sizeof(id->fw_rev), 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"))
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);
drive->present = 1;
......@@ -122,7 +147,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
* Check for an ATAPI device
*/
if (cmd == WIN_PIDENTIFY) {
byte type = (id->config >> 8) & 0x1f;
u8 type = (id->config >> 8) & 0x1f;
printk("ATAPI ");
#ifdef CONFIG_BLK_DEV_PDC4030
if (hwif->channel == 1 && hwif->chipset == ide_pdc4030) {
......@@ -142,7 +167,8 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
break;
}
}
type = ide_cdrom; /* Early cdrom models used zero */
/* Early cdrom models used zero */
type = ide_cdrom;
case ide_cdrom:
drive->removable = 1;
#ifdef CONFIG_PPC
......@@ -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
* some variety:
*/
drive->is_flash = 0;
if (drive_is_flashcard(drive)) {
ide_drive_t *mate = &hwif->drives[1^drive->select.b.unit];
if (!mate->ata_flash) {
mate->present = 0;
mate->noprobe = 1;
}
drive->is_flash = 1;
}
drive->media = ide_disk;
printk("ATA DISK drive\n");
QUIRK_LIST(hwif, drive);
printk("%s DISK drive\n", (drive->is_flash) ? "CFA" : "ATA" );
QUIRK_LIST(drive);
return;
err_misc:
......@@ -211,68 +239,80 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
* 1 device timed-out (no response to identify request)
* 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;
ide_ioreg_t hd_status;
unsigned long timeout;
byte s, a;
u8 s = 0, a = 0;
if (IDE_CONTROL_REG) {
/* take a deep breath */
ide_delay_50ms();
a = IN_BYTE(IDE_ALTSTATUS_REG);
s = IN_BYTE(IDE_STATUS_REG);
a = hwif->INB(IDE_ALTSTATUS_REG);
s = hwif->INB(IDE_STATUS_REG);
if ((a ^ s) & ~INDEX_STAT) {
printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a);
hd_status = IDE_STATUS_REG; /* ancient Seagate drives, broken interfaces */
printk("%s: probing with STATUS(0x%02x) instead of "
"ALTSTATUS(0x%02x)\n", drive->name, s, a);
/* ancient Seagate drives, broken interfaces */
hd_status = IDE_STATUS_REG;
} else {
hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */
/* use non-intrusive polling */
hd_status = IDE_ALTSTATUS_REG;
}
} else {
ide_delay_50ms();
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))
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(drive)->chipset == ide_pdc4030) {
/* DC4030 hosted drives need their own identify... */
extern int pdc4030_identify(ide_drive_t *);
if (pdc4030_identify(drive)) {
if (hwif->identify != NULL) {
if (hwif->identify(drive))
return 1;
} else {
/* ask drive for ID */
hwif->OUTB(cmd, IDE_COMMAND_REG);
}
} else
#endif /* CONFIG_BLK_DEV_PDC4030 */
OUT_BYTE(cmd,IDE_COMMAND_REG); /* ask drive for ID */
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
timeout += jiffies;
do {
if (time_after(jiffies, timeout)) {
return 1; /* drive timed-out */
/* drive timed-out */
return 1;
}
ide_delay_50ms(); /* give drive a breather */
} while (IN_BYTE(hd_status) & BUSY_STAT);
/* give drive a breather */
ide_delay_50ms();
} while ((hwif->INB(hd_status)) & BUSY_STAT);
ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */
if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
/* wait for IRQ and DRQ_STAT */
ide_delay_50ms();
if (OK_STAT((hwif->INB(IDE_STATUS_REG)), DRQ_STAT, BAD_R_STAT)) {
unsigned long flags;
local_irq_save(flags);
/* local CPU only; some systems need this */
do_identify(drive, cmd); /* drive returned ID */
rc = 0; /* drive responded with ID */
(void) GET_STAT(); /* clear drive IRQ */
local_irq_save(flags);
/* drive returned ID */
do_identify(drive, cmd);
/* drive responded with ID */
rc = 0;
/* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG);
local_irq_restore(flags);
} else
rc = 2; /* drive refused ID */
} else {
/* drive refused ID */
rc = 2;
}
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);
int retval;
......@@ -282,26 +322,34 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
if (IDE_CONTROL_REG && !hwif->irq) {
autoprobe = 1;
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);
if (autoprobe) {
int irq;
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
(void) GET_STAT(); /* clear drive IRQ */
/* mask device irq */
hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG);
/* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG);
udelay(5);
irq = probe_irq_off(cookie);
if (!hwif->irq) {
if (irq > 0) {
hwif->irq = irq;
} else { /* Mmmm.. multiple IRQs.. don't know which was ours */
printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie);
} else {
/* 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 CMD640_DUMP_REGS
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;
}
#endif /* CMD640_DUMP_REGS */
......@@ -329,11 +377,13 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
* 3 bad status from device (possible for ATAPI drives)
* 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;
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))
return 4;
}
......@@ -342,43 +392,64 @@ static int do_probe (ide_drive_t *drive, byte cmd)
drive->name, drive->present, drive->media,
(cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI");
#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();
SELECT_DRIVE(drive);
ide_delay_50ms();
if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) {
if (hwif->INB(IDE_SELECT_REG) != drive->select.all && !drive->present) {
if (drive->select.b.unit != 0) {
SELECT_DRIVE(hwif,&hwif->drives[0]); /* exit with drive0 selected */
ide_delay_50ms(); /* allow BUSY_STAT to assert & clear */
/* exit with drive0 selected */
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) {
if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */
rc = try_to_identify(drive,cmd); /* failed: try again */
/* send cmd and wait */
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) {
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();
OUT_BYTE (drive->select.all, IDE_SELECT_REG);
hwif->OUTB(drive->select.all, IDE_SELECT_REG);
ide_delay_50ms();
OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
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();
rc = try_to_identify(drive, cmd);
}
if (rc == 1)
printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT());
(void) GET_STAT(); /* ensure drive irq is clear */
printk("%s: no response (status = 0x%02x)\n",
drive->name, hwif->INB(IDE_STATUS_REG));
/* ensure drive irq is clear */
(void) hwif->INB(IDE_STATUS_REG);
} else {
rc = 3; /* not present or maybe ATAPI */
/* not present or maybe ATAPI */
rc = 3;
}
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();
(void) GET_STAT(); /* ensure drive irq is clear */
/* ensure drive irq is clear */
(void) hwif->INB(IDE_STATUS_REG);
}
return rc;
}
......@@ -392,9 +463,9 @@ static void enable_nest (ide_drive_t *drive)
unsigned long timeout;
printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(hwif, drive);
SELECT_DRIVE(drive);
ide_delay_50ms();
OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
......@@ -402,15 +473,21 @@ static void enable_nest (ide_drive_t *drive)
return;
}
ide_delay_50ms();
} while (GET_STAT() & BUSY_STAT);
} while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT);
ide_delay_50ms();
if (!OK_STAT(GET_STAT(), 0, BAD_STAT))
printk("failed (status = 0x%02x)\n", GET_STAT());
else
if (!OK_STAT((hwif->INB(IDE_STATUS_REG)), 0, BAD_STAT)) {
printk("failed (status = 0x%02x)\n", hwif->INB(IDE_STATUS_REG));
} else {
printk("success\n");
}
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);
}
}
/*
......@@ -419,102 +496,99 @@ static void enable_nest (ide_drive_t *drive)
* Returns: 0 no device was found
* 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;
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"))
enable_nest(drive);
if (!drive->present)
return 0; /* drive not found */
if (drive->id == NULL) { /* identification failed? */
/* drive not found */
return 0;
/* identification failed? */
if (drive->id == NULL) {
if (drive->media == ide_disk) {
printk ("%s: non-IDE drive, CHS=%d/%d/%d\n",
drive->name, drive->cyl, drive->head, drive->sect);
printk("%s: non-IDE drive, CHS=%d/%d/%d\n",
drive->name, drive->cyl,
drive->head, drive->sect);
} else if (drive->media == ide_cdrom) {
printk("%s: ATAPI cdrom (?)\n", drive->name);
} else {
drive->present = 0; /* nuke it */
/* nuke it */
drive->present = 0;
}
}
return 1; /* drive was found */
/* drive was found */
return 1;
}
/*
* Calculate the region that this interface occupies,
* handling interfaces where the registers may not be
* ordered sanely. We deal with the CONTROL register
* separately.
*/
#define hwif_check_region(addr, num) \
((hwif->mmio) ? check_mem_region((addr),(num)) : check_region((addr),(num)))
static int hwif_check_regions (ide_hwif_t *hwif)
{
int region_errors = 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);
u32 i = 0;
int addr_errs = 0;
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])
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 (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) */
/*
* If any errors are return, we drop the hwif interface.
*/
return(region_errors);
/* If any errors are return, we drop the hwif interface. */
hwif->straight8 = 0;
return(addr_errs);
}
//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)
{
if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name);
hwif->straight8 = 1;
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:
u32 i = 0;
if (hwif->mmio == 2)
return;
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 (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) */
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
* 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 long flags;
......@@ -524,8 +598,7 @@ static void probe_hwif (ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDE
if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
extern void probe_cmos_for_drives(ide_hwif_t *);
probe_cmos_for_drives (hwif);
probe_cmos_for_drives(hwif);
}
#endif
......@@ -534,20 +607,25 @@ static void probe_hwif (ide_hwif_t *hwif)
(hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
#endif /* CONFIG_BLK_DEV_PDC4030 */
(hwif_check_regions(hwif))) {
int msgout = 0;
u16 msgout = 0;
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) {
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;
}
}
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;
}
if (hwif->hw.ack_intr && hwif->irq)
disable_irq(hwif->irq);
local_irq_set(flags);
/*
* Second drive should only exist if first drive was found,
......@@ -556,7 +634,8 @@ static void probe_hwif (ide_hwif_t *hwif)
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[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) {
hwif->present = 1;
if (hwif->chipset != ide_4drives ||
......@@ -567,40 +646,76 @@ static void probe_hwif (ide_hwif_t *hwif)
}
if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
unsigned long timeout = jiffies + WAIT_WORSTCASE;
byte stat;
u8 stat;
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);
OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do {
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));
}
local_irq_restore(flags);
if (hwif->hw.ack_intr && hwif->irq)
enable_irq(hwif->irq);
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) {
if (hwif->tuneproc != NULL && drive->autotune == 1)
/* auto-tune PIO mode */
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.
* Some chipsets appear to do interesting
* things, if not checked and cleared.
* PARANOIA!!!
*/
hwif->dmaproc(ide_dma_off_quietly, drive);
hwif->dmaproc(ide_dma_check, drive);
hwif->ide_dma_off_quietly(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
/*
* save_match() is used to simplify logic in init_irq() below.
......@@ -613,7 +728,7 @@ static void probe_hwif (ide_hwif_t *hwif)
*
* 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;
......@@ -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 */
*match = new;
}
EXPORT_SYMBOL(save_match);
#endif /* MAX_HWIFS > 1 */
/*
......@@ -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
* 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 int index;
ide_hwgroup_t *hwgroup, *new_hwgroup;
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 */
new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
#endif
spin_lock_irqsave(&ide_lock, flags);
......@@ -691,7 +810,8 @@ static int init_irq (ide_hwif_t *hwif)
if (h->hwgroup) { /* scan only initialized hwif's */
if (hwif->irq == h->irq) {
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);
}
}
......@@ -734,16 +854,23 @@ static int init_irq (ide_hwif_t *hwif)
* Allocate the irq, if not already obtained for another hwif
*/
if (!match || match->irq != hwif->irq) {
#ifdef CONFIG_IDEPCI_SHARE_IRQ
int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_SHIRQ : SA_INTERRUPT;
#else /* !CONFIG_IDEPCI_SHARE_IRQ */
int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
int sa = SA_INTERRUPT;
#if defined(__mc68000__) || defined(CONFIG_APUS)
sa = SA_SHIRQ;
#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 */
}
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)
kfree(hwgroup);
spin_unlock_irqrestore(&ide_lock, flags);
......@@ -774,11 +901,12 @@ static int init_irq (ide_hwif_t *hwif)
printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);
#endif
}
spin_unlock_irqrestore(&ide_lock, flags);
/* all CPUs; safe now that hwif->hwgroup is set up */
spin_unlock_irqrestore(&ide_lock, flags);
#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]+7,
hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
......@@ -788,7 +916,7 @@ static int init_irq (ide_hwif_t *hwif)
hwif->io_ports[IDE_DATA_OFFSET]+7,
hwif->io_ports[IDE_CONTROL_OFFSET], __irq_itoa(hwif->irq));
#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);
#endif /* __mc68000__ && CONFIG_APUS */
if (match)
......@@ -798,6 +926,8 @@ static int init_irq (ide_hwif_t *hwif)
return 0;
}
EXPORT_SYMBOL(init_irq);
/*
* init_gendisk() (as opposed to ide_geninit) is called for each major device,
* after probing for drives, to allocate partition tables and other data
......@@ -811,15 +941,7 @@ static void init_gendisk (ide_hwif_t *hwif)
extern devfs_handle_t ide_devfs_handle;
char *names;
#if 1
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);
gd = kmalloc(MAX_DRIVES * sizeof(struct gendisk), GFP_KERNEL);
......@@ -827,7 +949,7 @@ static void init_gendisk (ide_hwif_t *hwif)
goto err_kmalloc_gd;
memset(gd, 0, MAX_DRIVES * sizeof(struct gendisk));
names = kmalloc (4 * MAX_DRIVES, GFP_KERNEL);
names = kmalloc(4 * MAX_DRIVES, GFP_KERNEL);
if (!names)
goto err_kmalloc_gd_names;
memset(names, 0, 4 * MAX_DRIVES);
......@@ -843,7 +965,6 @@ static void init_gendisk (ide_hwif_t *hwif)
}
for (unit = 0; unit < units; ++unit) {
#if 1
char name[64];
ide_add_generic_settings(hwif->drives + unit);
sprintf (name, "host%d/bus%d/target%d/lun%d",
......@@ -852,18 +973,6 @@ static void init_gendisk (ide_hwif_t *hwif)
hwif->channel, unit, hwif->drives[unit].lun);
if (hwif->drives[unit].present)
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;
......@@ -873,7 +982,9 @@ static void init_gendisk (ide_hwif_t *hwif)
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)
return 0;
......@@ -892,7 +1003,8 @@ static int hwif_init (ide_hwif_t *hwif)
}
#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)) {
printk("%s: UNABLE TO GET MAJOR NUMBER %d\n",
......@@ -909,13 +1021,13 @@ static int hwif_init (ide_hwif_t *hwif)
if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
printk("%s: Disabled unable to get IRQ %d.\n",
hwif->name, i);
(void) unregister_blkdev (hwif->major, hwif->name);
(void) unregister_blkdev(hwif->major, hwif->name);
return (hwif->present = 0);
}
if (init_irq(hwif)) {
printk("%s: probed IRQ %d and default IRQ %d failed.\n",
hwif->name, i, hwif->irq);
(void) unregister_blkdev (hwif->major, hwif->name);
(void) unregister_blkdev(hwif->major, hwif->name);
return (hwif->present = 0);
}
printk("%s: probed IRQ %d failed, using default.\n",
......@@ -926,28 +1038,23 @@ static int hwif_init (ide_hwif_t *hwif)
blk_dev[hwif->major].data = hwif;
blk_dev[hwif->major].queue = ide_get_queue;
hwif->present = 1; /* success */
#if (DEBUG_SPINLOCK > 0)
{
static int done = 0;
if (!done++)
printk("ide_lock is %p\n", &ide_lock); /* FIXME */
}
#endif
return hwif->present;
return 1;
}
EXPORT_SYMBOL(hwif_init);
void export_ide_init_queue (ide_drive_t *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);
}
EXPORT_SYMBOL(export_ide_init_queue);
EXPORT_SYMBOL(export_probe_for_drive);
int ideprobe_init (void);
......@@ -976,7 +1083,7 @@ int ideprobe_init (void)
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
hwif_init(&ide_hwifs[index]);
for (index = 0; index < MAX_HWIFS; ++index)
for (index = 0; index < MAX_HWIFS; ++index) {
if (probe[index]) {
ide_hwif_t *hwif = &ide_hwifs[index];
int unit;
......@@ -985,6 +1092,7 @@ int ideprobe_init (void)
for (unit = 0; unit < MAX_DRIVES; ++unit)
ata_attach(&hwif->drives[unit]);
}
}
if (!ide_probe)
ide_probe = &ideprobe_module;
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