Commit bdff23c1 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.15 IDE 60

 - Rewrite ioctl handling.

 - Apply fix for hpt366 "hang on boot" by Andre.

 - Remove stale XXX_tune_req. It was no longer used.

 - Propagate rq through ide_error(), ide_end_drive_cmd(), ide_dump_status(),
   ide_wait_stat().

 - Push the current drive down to ata_channel from hwgroup.

 - Push the timer down to the ata_channel structure. Most probably it will end
   at the drive.
parent 362a4a0c
...@@ -670,8 +670,8 @@ static void hpt366_tune_chipset(struct ata_device *drive, byte speed) ...@@ -670,8 +670,8 @@ static void hpt366_tune_chipset(struct ata_device *drive, byte speed)
* Disable the "fast interrupt" prediction. * Disable the "fast interrupt" prediction.
*/ */
pci_read_config_byte(dev, regfast, &drive_fast); pci_read_config_byte(dev, regfast, &drive_fast);
if (drive_fast & 0x02) if (drive_fast & 0x80)
pci_write_config_byte(dev, regfast, drive_fast & ~0x20); pci_write_config_byte(dev, regfast, drive_fast & ~0x80);
pci_read_config_dword(dev, regtime, &reg1); pci_read_config_dword(dev, regtime, &reg1);
reg2 = pci_bus_clock_list(speed, reg2 = pci_bus_clock_list(speed,
......
...@@ -594,7 +594,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr ...@@ -594,7 +594,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
pc = (struct packet_command *) rq->special; pc = (struct packet_command *) rq->special;
pc->stat = 1; pc->stat = 1;
cdrom_end_request(drive, rq, 1); cdrom_end_request(drive, rq, 1);
*startstop = ide_error (drive, "request sense failure", stat); *startstop = ide_error (drive, rq, "request sense failure", stat);
return 1; return 1;
} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) { } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
...@@ -614,7 +614,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr ...@@ -614,7 +614,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
return 0; return 0;
} else if (!pc->quiet) { } else if (!pc->quiet) {
/* Otherwise, print an error. */ /* Otherwise, print an error. */
ide_dump_status(drive, "packet command error", stat); ide_dump_status(drive, rq, "packet command error", stat);
} }
/* Set the error flag and complete the request. /* Set the error flag and complete the request.
...@@ -662,18 +662,18 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr ...@@ -662,18 +662,18 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
sense_key == DATA_PROTECT) { sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal /* No point in retrying after an illegal
request or data protect error.*/ request or data protect error.*/
ide_dump_status (drive, "command error", stat); ide_dump_status(drive, rq, "command error", stat);
cdrom_end_request(drive, rq, 0); cdrom_end_request(drive, rq, 0);
} else if (sense_key == MEDIUM_ERROR) { } else if (sense_key == MEDIUM_ERROR) {
/* No point in re-trying a zillion times on a bad /* No point in re-trying a zillion times on a bad
* sector. The error is not correctable at all. * sector. The error is not correctable at all.
*/ */
ide_dump_status (drive, "media error (bad sector)", stat); ide_dump_status(drive, rq, "media error (bad sector)", stat);
cdrom_end_request(drive, rq, 0); cdrom_end_request(drive, rq, 0);
} else if ((err & ~ABRT_ERR) != 0) { } else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler /* Go to the default handler
for other errors. */ for other errors. */
*startstop = ide_error (drive, __FUNCTION__, stat); *startstop = ide_error(drive, rq, __FUNCTION__, stat);
return 1; return 1;
} else if ((++rq->errors > ERROR_MAX)) { } else if ((++rq->errors > ERROR_MAX)) {
/* We've racked up too many retries. Abort. */ /* We've racked up too many retries. Abort. */
...@@ -732,7 +732,7 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive, ...@@ -732,7 +732,7 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
/* Wait for the controller to be idle. */ /* Wait for the controller to be idle. */
if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY)) if (ide_wait_stat(&startstop, drive, rq, 0, BUSY_STAT, WAIT_READY))
return startstop; return startstop;
if (info->dma) { if (info->dma) {
...@@ -789,7 +789,7 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive, ...@@ -789,7 +789,7 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive,
return startstop; return startstop;
} else { } else {
/* Otherwise, we must wait for DRQ to get set. */ /* Otherwise, we must wait for DRQ to get set. */
if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY))
return startstop; return startstop;
} }
...@@ -917,7 +917,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request ...@@ -917,7 +917,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
__ide_end_request(drive, rq, 1, rq->nr_sectors); __ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
} else } else
return ide_error (drive, "dma error", stat); return ide_error (drive, rq, "dma error", stat);
} }
/* Read the interrupt reason and the transfer length. */ /* Read the interrupt reason and the transfer length. */
...@@ -1496,7 +1496,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request ...@@ -1496,7 +1496,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
*/ */
if (dma) { if (dma) {
if (dma_error) if (dma_error)
return ide_error(drive, "dma error", stat); return ide_error(drive, rq, "dma error", stat);
__ide_end_request(drive, rq, 1, rq->nr_sectors); __ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
...@@ -2659,12 +2659,6 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) ...@@ -2659,12 +2659,6 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
return nslots; return nslots;
} }
static void ide_cdrom_add_settings(ide_drive_t *drive)
{
ide_add_setting(drive, "dsc_overlap",
SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
}
static static
int ide_cdrom_setup(ide_drive_t *drive) int ide_cdrom_setup(ide_drive_t *drive)
{ {
...@@ -2798,7 +2792,7 @@ int ide_cdrom_setup(ide_drive_t *drive) ...@@ -2798,7 +2792,7 @@ int ide_cdrom_setup(ide_drive_t *drive)
info->devinfo.handle = NULL; info->devinfo.handle = NULL;
return 1; return 1;
} }
ide_cdrom_add_settings(drive);
return 0; return 0;
} }
......
...@@ -472,12 +472,6 @@ static int set_nowerr(struct ata_device *drive, int arg) ...@@ -472,12 +472,6 @@ static int set_nowerr(struct ata_device *drive, int arg)
drive->nowerr = arg; drive->nowerr = arg;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
/* FIXME: I'm less then sure that we are under the global request lock here!
*/
#if 0
spin_unlock_irq(&ide_lock);
#endif
return 0; return 0;
} }
...@@ -531,8 +525,10 @@ static int set_using_tcq(struct ata_device *drive, int arg) ...@@ -531,8 +525,10 @@ static int set_using_tcq(struct ata_device *drive, int arg)
{ {
if (!drive->driver) if (!drive->driver)
return -EPERM; return -EPERM;
if (!drive->channel->XXX_udma) if (!drive->channel->XXX_udma)
return -EPERM; return -EPERM;
if (arg == drive->queue_depth && drive->using_tcq) if (arg == drive->queue_depth && drive->using_tcq)
return 0; return 0;
...@@ -568,20 +564,6 @@ static int set_lba_addressing(struct ata_device *drive, int arg) ...@@ -568,20 +564,6 @@ static int set_lba_addressing(struct ata_device *drive, int arg)
return (probe_lba_addressing(drive, arg)); return (probe_lba_addressing(drive, arg));
} }
static void idedisk_add_settings(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
ide_add_setting(drive, "address", SETTING_RW, HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, TYPE_INTA, 0, 2, 1, 1, &drive->addressing, set_lba_addressing);
ide_add_setting(drive, "multcount", id ? SETTING_RW : SETTING_READ, HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, TYPE_BYTE, 0, id ? id->max_multsect : 0, 1, 1, &drive->mult_count, set_multcount);
ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr);
ide_add_setting(drive, "wcache", SETTING_RW, HDIO_GET_WCACHE, HDIO_SET_WCACHE, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache);
ide_add_setting(drive, "acoustic", SETTING_RW, HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
ide_add_setting(drive, "using_tcq", SETTING_RW, HDIO_GET_QDMA, HDIO_SET_QDMA, TYPE_BYTE, 0, IDE_MAX_TAG, 1, 1, &drive->using_tcq, set_using_tcq);
#endif
}
static int idedisk_suspend(struct device *dev, u32 state, u32 level) static int idedisk_suspend(struct device *dev, u32 state, u32 level)
{ {
struct ata_device *drive = dev->driver_data; struct ata_device *drive = dev->driver_data;
...@@ -624,9 +606,6 @@ static int idedisk_resume(struct device *dev, u32 level) ...@@ -624,9 +606,6 @@ static int idedisk_resume(struct device *dev, u32 level)
/* This is just a hook for the overall driver tree. /* This is just a hook for the overall driver tree.
*
* FIXME: This is soon goig to replace the custom linked list games played up
* to great extend between the different components of the IDE drivers.
*/ */
static struct device_driver idedisk_devdrv = { static struct device_driver idedisk_devdrv = {
...@@ -783,8 +762,6 @@ static void idedisk_setup(struct ata_device *drive) ...@@ -783,8 +762,6 @@ static void idedisk_setup(struct ata_device *drive)
sector_t set_max; sector_t set_max;
int drvid = -1; int drvid = -1;
idedisk_add_settings(drive);
if (id == NULL) if (id == NULL)
return; return;
...@@ -1022,6 +999,159 @@ static int idedisk_cleanup(struct ata_device *drive) ...@@ -1022,6 +999,159 @@ static int idedisk_cleanup(struct ata_device *drive)
return ide_unregister_subdriver(drive); return ide_unregister_subdriver(drive);
} }
static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct hd_driveid *id = drive->id;
switch (cmd) {
case HDIO_GET_ADDRESS: {
unsigned long val = drive->addressing;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_ADDRESS: {
int val;
if (arg < 0 || arg > 2)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_lba_addressing(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
case HDIO_GET_MULTCOUNT: {
unsigned long val = drive->mult_count & 0xFF;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_MULTCOUNT: {
int val;
if (!id)
return -EBUSY;
if (arg < 0 || arg > (id ? id->max_multsect : 0))
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_multcount(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
case HDIO_GET_NOWERR: {
unsigned long val = drive->nowerr;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_NOWERR: {
int val;
if (arg < 0 || arg > 1)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_nowerr(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
case HDIO_GET_WCACHE: {
unsigned long val = drive->wcache;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_WCACHE: {
int val;
if (arg < 0 || arg > 1)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = write_cache(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
case HDIO_GET_ACOUSTIC: {
u8 val = drive->acoustic;
if (put_user(val, (u8 *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_ACOUSTIC: {
int val;
if (arg < 0 || arg > 254)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_acoustic(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
#ifdef CONFIG_BLK_DEV_IDE_TCQ
case HDIO_GET_QDMA: {
u8 val = drive->using_tcq;
if (put_user(val, (u8 *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_QDMA: {
int val;
if (arg < 0 || arg > IDE_MAX_TAG)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_using_tcq(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
#endif
default:
return -EINVAL;
}
}
/* /*
* IDE subdriver functions, registered with ide.c * IDE subdriver functions, registered with ide.c
*/ */
...@@ -1031,7 +1161,7 @@ static struct ata_operations idedisk_driver = { ...@@ -1031,7 +1161,7 @@ static struct ata_operations idedisk_driver = {
standby: idedisk_standby, standby: idedisk_standby,
do_request: idedisk_do_request, do_request: idedisk_do_request,
end_request: NULL, end_request: NULL,
ioctl: NULL, ioctl: idedisk_ioctl,
open: idedisk_open, open: idedisk_open,
release: idedisk_release, release: idedisk_release,
check_media_change: idedisk_check_media_change, check_media_change: idedisk_check_media_change,
......
...@@ -208,7 +208,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq) ...@@ -208,7 +208,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat); drive->name, dma_stat);
} }
return ide_error(drive, "dma_intr", stat); return ide_error(drive, rq, "dma_intr", stat);
} }
/* /*
...@@ -375,7 +375,7 @@ static int config_drive_for_dma(struct ata_device *drive) ...@@ -375,7 +375,7 @@ static int config_drive_for_dma(struct ata_device *drive)
/* /*
* 1 dma-ing, 2 error, 4 intr * 1 dma-ing, 2 error, 4 intr
*/ */
static int dma_timer_expiry(struct ata_device *drive, struct request *__rq) static int dma_timer_expiry(struct ata_device *drive, struct request *rq)
{ {
/* FIXME: What's that? */ /* FIXME: What's that? */
u8 dma_stat = inb(drive->channel->dma_base+2); u8 dma_stat = inb(drive->channel->dma_base+2);
...@@ -390,7 +390,7 @@ static int dma_timer_expiry(struct ata_device *drive, struct request *__rq) ...@@ -390,7 +390,7 @@ static int dma_timer_expiry(struct ata_device *drive, struct request *__rq)
if (dma_stat & 2) { /* ERROR */ if (dma_stat & 2) { /* ERROR */
u8 stat = GET_STAT(); u8 stat = GET_STAT();
return ide_error(drive, "dma_timer_expiry", stat); return ide_error(drive, rq, "dma_timer_expiry", stat);
} }
if (dma_stat & 1) /* DMAing */ if (dma_stat & 1) /* DMAing */
return WAIT_CMD; return WAIT_CMD;
......
...@@ -393,7 +393,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) ...@@ -393,7 +393,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
enable_irq(hwif->irq); enable_irq(hwif->irq);
if (error) { if (error) {
ide_dump_status(drive, "set_drive_speed_status", stat); ide_dump_status(drive, NULL, "set_drive_speed_status", stat);
return error; return error;
} }
......
...@@ -692,7 +692,7 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i ...@@ -692,7 +692,7 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i
return 0; return 0;
} }
rq->errors = error; rq->errors = error;
ide_end_drive_cmd (drive, 0, 0); ide_end_drive_cmd (drive, rq, 0, 0);
return 0; return 0;
} }
...@@ -1006,7 +1006,7 @@ static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct re ...@@ -1006,7 +1006,7 @@ static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct re
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_ireason_reg_t ireason; idefloppy_ireason_reg_t ireason;
if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { if (ide_wait_stat (&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
...@@ -1043,13 +1043,13 @@ static int idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq ...@@ -1043,13 +1043,13 @@ static int idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq
return IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */ return IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */
} }
static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *__rq) static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_startstop_t startstop; ide_startstop_t startstop;
idefloppy_ireason_reg_t ireason; idefloppy_ireason_reg_t ireason;
if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
...@@ -1960,14 +1960,6 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id) ...@@ -1960,14 +1960,6 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
return 0; return 0;
} }
static void idefloppy_add_settings(ide_drive_t *drive)
{
ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL);
ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL);
ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
}
/* /*
* Driver initialization. * Driver initialization.
*/ */
...@@ -2009,7 +2001,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) ...@@ -2009,7 +2001,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
} }
(void) idefloppy_get_capacity (drive); (void) idefloppy_get_capacity (drive);
idefloppy_add_settings(drive);
for (i = 0; i < MAX_DRIVES; ++i) { for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_channel *hwif = drive->channel; struct ata_channel *hwif = drive->channel;
......
...@@ -628,9 +628,6 @@ static int init_irq(struct ata_channel *ch) ...@@ -628,9 +628,6 @@ static int init_irq(struct ata_channel *ch)
return 1; return 1;
} }
memset(hwgroup, 0, sizeof(*hwgroup)); memset(hwgroup, 0, sizeof(*hwgroup));
init_timer(&hwgroup->timer);
hwgroup->timer.function = &ide_timer_expiry;
hwgroup->timer.data = (unsigned long) hwgroup;
} }
/* /*
...@@ -659,6 +656,11 @@ static int init_irq(struct ata_channel *ch) ...@@ -659,6 +656,11 @@ static int init_irq(struct ata_channel *ch)
* Everything is okay. Tag us as member of this hardware group. * Everything is okay. Tag us as member of this hardware group.
*/ */
ch->hwgroup = hwgroup; ch->hwgroup = hwgroup;
init_timer(&ch->timer);
ch->timer.function = &ide_timer_expiry;
ch->timer.data = (unsigned long) ch;
for (i = 0; i < MAX_DRIVES; ++i) { for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_device *drive = &ch->drives[i]; struct ata_device *drive = &ch->drives[i];
request_queue_t *q; request_queue_t *q;
...@@ -667,8 +669,8 @@ static int init_irq(struct ata_channel *ch) ...@@ -667,8 +669,8 @@ static int init_irq(struct ata_channel *ch)
if (!drive->present) if (!drive->present)
continue; continue;
if (!hwgroup->XXX_drive) if (!ch->drive)
hwgroup->XXX_drive = drive; ch->drive = drive;
/* /*
* Init the per device request queue * Init the per device request queue
...@@ -842,7 +844,6 @@ static void channel_init(struct ata_channel *ch) ...@@ -842,7 +844,6 @@ static void channel_init(struct ata_channel *ch)
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
char name[80]; char name[80];
ide_add_generic_settings(ch->drives + unit);
ch->drives[unit].dn = ((ch->unit ? 2 : 0) + unit); ch->drives[unit].dn = ((ch->unit ? 2 : 0) + unit);
sprintf(name, "host%d/bus%d/target%d/lun%d", sprintf(name, "host%d/bus%d/target%d/lun%d",
ch->index, ch->unit, unit, ch->drives[unit].lun); ch->index, ch->unit, unit, ch->drives[unit].lun);
......
...@@ -1925,7 +1925,7 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int ...@@ -1925,7 +1925,7 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int
idetape_increase_max_pipeline_stages (drive); idetape_increase_max_pipeline_stages (drive);
} }
} }
ide_end_drive_cmd (drive, 0, 0); ide_end_drive_cmd(drive, rq, 0, 0);
if (remove_stage) if (remove_stage)
idetape_remove_stage_head (drive); idetape_remove_stage_head (drive);
if (tape->active_data_request == NULL) if (tape->active_data_request == NULL)
...@@ -2228,7 +2228,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2228,7 +2228,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
* we will handle the next request. * we will handle the next request.
* *
*/ */
static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *__rq) static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc = tape->pc; idetape_pc_t *pc = tape->pc;
...@@ -2236,7 +2236,7 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ ...@@ -2236,7 +2236,7 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ
int retries = 100; int retries = 100;
ide_startstop_t startstop; ide_startstop_t startstop;
if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
...@@ -5926,41 +5926,7 @@ static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive) ...@@ -5926,41 +5926,7 @@ static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive)
tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2]; tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2];
#if IDETAPE_DEBUG_INFO #if IDETAPE_DEBUG_INFO
printk (KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size); printk (KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size);
#endif /* IDETAPE_DEBUG_INFO */ #endif
}
static void idetape_add_settings (ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
/*
* drive setting name read/write ioctl ioctl data type min max mul_factor div_factor data pointer set function
*/
ide_add_setting(drive, "buffer", SETTING_READ, -1, -1, TYPE_SHORT, 0, 0xffff, 1, 2, &tape->capabilities.buffer_size, NULL);
ide_add_setting(drive, "pipeline_min", SETTING_RW, -1, -1, TYPE_INT, 2, 0xffff, tape->stage_size / 1024, 1, &tape->min_pipeline, NULL);
ide_add_setting(drive, "pipeline", SETTING_RW, -1, -1, TYPE_INT, 2, 0xffff, tape->stage_size / 1024, 1, &tape->max_stages, NULL);
ide_add_setting(drive, "pipeline_max", SETTING_RW, -1, -1, TYPE_INT, 2, 0xffff, tape->stage_size / 1024, 1, &tape->max_pipeline, NULL);
ide_add_setting(drive, "pipeline_used",SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, tape->stage_size / 1024, 1, &tape->nr_stages, NULL);
ide_add_setting(drive, "pipeline_pending",SETTING_READ,-1, -1, TYPE_INT, 0, 0xffff, tape->stage_size / 1024, 1, &tape->nr_pending_stages, NULL);
ide_add_setting(drive, "speed", SETTING_READ, -1, -1, TYPE_SHORT, 0, 0xffff, 1, 1, &tape->capabilities.speed, NULL);
ide_add_setting(drive, "stage", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1024, &tape->stage_size, NULL);
ide_add_setting(drive, "tdsc", SETTING_RW, -1, -1, TYPE_INT, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_frequency, NULL);
ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
ide_add_setting(drive, "pipeline_head_speed_c",SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->controlled_pipeline_head_speed, NULL);
ide_add_setting(drive, "pipeline_head_speed_u",SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->uncontrolled_pipeline_head_speed, NULL);
ide_add_setting(drive, "avg_speed", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->avg_speed, NULL);
ide_add_setting(drive, "debug_level",SETTING_RW, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->debug_level, NULL);
if (tape->onstream) {
ide_add_setting(drive, "cur_frames", SETTING_READ, -1, -1, TYPE_SHORT, 0, 0xffff, 1, 1, &tape->cur_frames, NULL);
ide_add_setting(drive, "max_frames", SETTING_READ, -1, -1, TYPE_SHORT, 0, 0xffff, 1, 1, &tape->max_frames, NULL);
ide_add_setting(drive, "insert_speed", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->insert_speed, NULL);
ide_add_setting(drive, "speed_control",SETTING_RW, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->speed_control, NULL);
ide_add_setting(drive, "tape_still_time",SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->tape_still_time, NULL);
ide_add_setting(drive, "max_insert_speed",SETTING_RW, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->max_insert_speed, NULL);
ide_add_setting(drive, "insert_size", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->insert_size, NULL);
ide_add_setting(drive, "capacity", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->capacity, NULL);
ide_add_setting(drive, "first_frame", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->first_frame_position, NULL);
ide_add_setting(drive, "logical_blk", SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, 1, 1, &tape->logical_blk_num, NULL);
}
} }
/* /*
...@@ -6074,8 +6040,6 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -6074,8 +6040,6 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
drive->name, tape->name, tape->capabilities.speed, (tape->capabilities.buffer_size * 512) / tape->stage_size, drive->name, tape->name, tape->capabilities.speed, (tape->capabilities.buffer_size * 512) / tape->stage_size,
tape->stage_size / 1024, tape->max_stages * tape->stage_size / 1024, tape->stage_size / 1024, tape->max_stages * tape->stage_size / 1024,
tape->best_dsc_rw_frequency * 1000 / HZ, drive->using_dma ? ", DMA":""); tape->best_dsc_rw_frequency * 1000 / HZ, drive->using_dma ? ", DMA":"");
idetape_add_settings(drive);
} }
static int idetape_cleanup (ide_drive_t *drive) static int idetape_cleanup (ide_drive_t *drive)
......
...@@ -308,7 +308,7 @@ static ide_startstop_t pre_task_mulout_intr(struct ata_device *drive, struct req ...@@ -308,7 +308,7 @@ static ide_startstop_t pre_task_mulout_intr(struct ata_device *drive, struct req
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
ide_startstop_t startstop; ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ))
return startstop; return startstop;
ata_poll_drive_ready(drive); ata_poll_drive_ready(drive);
...@@ -329,7 +329,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request ...@@ -329,7 +329,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
*/ */
if (!rq->nr_sectors) { if (!rq->nr_sectors) {
if (stat & (ERR_STAT|DRQ_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) {
startstop = ide_error(drive, "task_mulout_intr", stat); startstop = ide_error(drive, rq, "task_mulout_intr", stat);
return startstop; return startstop;
} }
...@@ -342,7 +342,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request ...@@ -342,7 +342,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
if (stat & (ERR_STAT | DRQ_STAT)) { if (stat & (ERR_STAT | DRQ_STAT)) {
startstop = ide_error(drive, "task_mulout_intr", stat); startstop = ide_error(drive, rq, "task_mulout_intr", stat);
return startstop; return startstop;
} }
...@@ -489,12 +489,12 @@ ide_startstop_t ata_taskfile(struct ata_device *drive, ...@@ -489,12 +489,12 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
/* /*
* This is invoked on completion of a WIN_RESTORE (recalibrate) cmd. * This is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
*/ */
ide_startstop_t recal_intr(struct ata_device *drive, struct request *__rq) ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq)
{ {
u8 stat; u8 stat;
if (!OK_STAT(stat = GET_STAT(),READY_STAT,BAD_STAT)) if (!OK_STAT(stat = GET_STAT(),READY_STAT,BAD_STAT))
return ide_error(drive, "recal_intr", stat); return ide_error(drive, rq, "recal_intr", stat);
return ide_stopped; return ide_stopped;
} }
...@@ -511,11 +511,11 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq) ...@@ -511,11 +511,11 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
if (!OK_STAT(stat = GET_STAT(), READY_STAT, BAD_STAT)) { if (!OK_STAT(stat = GET_STAT(), READY_STAT, BAD_STAT)) {
/* Keep quiet for NOP because it is expected to fail. */ /* Keep quiet for NOP because it is expected to fail. */
if (args && args->taskfile.command != WIN_NOP) if (args && args->taskfile.command != WIN_NOP)
return ide_error(drive, "task_no_data_intr", stat); return ide_error(drive, rq, "task_no_data_intr", stat);
} }
if (args) if (args)
ide_end_drive_cmd (drive, stat, GET_ERR()); ide_end_drive_cmd(drive, rq, stat, GET_ERR());
return ide_stopped; return ide_stopped;
} }
...@@ -523,7 +523,7 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq) ...@@ -523,7 +523,7 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
/* /*
* Handler for command with PIO data-in phase * Handler for command with PIO data-in phase
*/ */
static ide_startstop_t task_in_intr (struct ata_device *drive, struct request *rq) static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
{ {
u8 stat = GET_STAT(); u8 stat = GET_STAT();
char *pBuf = NULL; char *pBuf = NULL;
...@@ -531,7 +531,7 @@ static ide_startstop_t task_in_intr (struct ata_device *drive, struct request *r ...@@ -531,7 +531,7 @@ static ide_startstop_t task_in_intr (struct ata_device *drive, struct request *r
if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_in_intr", stat); return ide_error(drive, rq, "task_in_intr", stat);
} }
if (!(stat & BUSY_STAT)) { if (!(stat & BUSY_STAT)) {
DTF("task_in_intr to Soon wait for next interrupt\n"); DTF("task_in_intr to Soon wait for next interrupt\n");
...@@ -569,7 +569,7 @@ static ide_startstop_t pre_task_out_intr(struct ata_device *drive, struct reques ...@@ -569,7 +569,7 @@ static ide_startstop_t pre_task_out_intr(struct ata_device *drive, struct reques
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
ide_startstop_t startstop; ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE"); printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
return startstop; return startstop;
} }
...@@ -600,7 +600,7 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -600,7 +600,7 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
unsigned long flags; unsigned long flags;
if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat))
return ide_error(drive, "task_out_intr", stat); return ide_error(drive, rq, "task_out_intr", stat);
if (!rq->current_nr_sectors) if (!rq->current_nr_sectors)
if (!ide_end_request(drive, rq, 1)) if (!ide_end_request(drive, rq, 1))
...@@ -632,7 +632,7 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request ...@@ -632,7 +632,7 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request
if (!OK_STAT(stat = GET_STAT(),DATA_READY,BAD_R_STAT)) { if (!OK_STAT(stat = GET_STAT(),DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_mulin_intr", stat); return ide_error(drive, rq, "task_mulin_intr", stat);
} }
/* no data yet, so wait for another interrupt */ /* no data yet, so wait for another interrupt */
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
......
...@@ -337,17 +337,18 @@ void ide_set_handler(struct ata_device *drive, ata_handler_t handler, ...@@ -337,17 +337,18 @@ void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry) unsigned long timeout, ata_expiry_t expiry)
{ {
unsigned long flags; unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive); struct ata_channel *ch = drive->channel;
ide_hwgroup_t *hwgroup = ch->hwgroup;
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (hwgroup->handler != NULL) { if (hwgroup->handler != NULL) {
printk("%s: ide_set_handler: handler not null; old=%p, new=%p, from %p\n", printk("%s: ide_set_handler: handler not null; old=%p, new=%p, from %p\n",
drive->name, hwgroup->handler, handler, __builtin_return_address(0)); drive->name, hwgroup->handler, handler, __builtin_return_address(0));
} }
hwgroup->handler = handler; hwgroup->handler = handler;
hwgroup->expiry = expiry; ch->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout; ch->timer.expires = jiffies + timeout;
add_timer(&hwgroup->timer); add_timer(&ch->timer);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
...@@ -592,15 +593,11 @@ static inline u32 read_24(struct ata_device *drive) ...@@ -592,15 +593,11 @@ static inline u32 read_24(struct ata_device *drive)
/* /*
* Clean up after success/failure of an explicit drive cmd * Clean up after success/failure of an explicit drive cmd
*
* Should be called under lock held.
*/ */
void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err) void ide_end_drive_cmd(struct ata_device *drive, struct request *rq, u8 stat, u8 err)
{ {
unsigned long flags;
struct request *rq;
spin_lock_irqsave(&ide_lock, flags);
rq = HWGROUP(drive)->rq;
if (rq->flags & REQ_DRIVE_CMD) { if (rq->flags & REQ_DRIVE_CMD) {
u8 *args = rq->buffer; u8 *args = rq->buffer;
rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT); rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
...@@ -640,14 +637,12 @@ void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err) ...@@ -640,14 +637,12 @@ void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err)
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL; HWGROUP(drive)->rq = NULL;
end_that_request_last(rq); end_that_request_last(rq);
spin_unlock_irqrestore(&ide_lock, flags);
} }
/* /*
* Error reporting, in human readable form (luxurious, but a memory hog). * Error reporting, in human readable form (luxurious, but a memory hog).
*/ */
byte ide_dump_status(struct ata_device *drive, const char *msg, byte stat) u8 ide_dump_status(struct ata_device *drive, struct request * rq, const char *msg, u8 stat)
{ {
unsigned long flags; unsigned long flags;
byte err = 0; byte err = 0;
...@@ -722,8 +717,8 @@ byte ide_dump_status(struct ata_device *drive, const char *msg, byte stat) ...@@ -722,8 +717,8 @@ byte ide_dump_status(struct ata_device *drive, const char *msg, byte stat)
IN_BYTE(IDE_SECTOR_REG)); IN_BYTE(IDE_SECTOR_REG));
} }
} }
if (HWGROUP(drive) && HWGROUP(drive)->rq) if (rq)
printk(", sector=%ld", HWGROUP(drive)->rq->sector); printk(", sector=%ld", rq->sector);
} }
} }
#endif #endif
...@@ -786,18 +781,17 @@ static int do_recalibrate(struct ata_device *drive) ...@@ -786,18 +781,17 @@ static int do_recalibrate(struct ata_device *drive)
/* /*
* Take action based on the error returned by the drive. * Take action based on the error returned by the drive.
*/ */
ide_startstop_t ide_error(struct ata_device *drive, const char *msg, byte stat) ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const char *msg, byte stat)
{ {
struct request *rq;
byte err; byte err;
err = ide_dump_status(drive, msg, stat); err = ide_dump_status(drive, rq, msg, stat);
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) if (!drive || !rq)
return ide_stopped; return ide_stopped;
/* retry only "normal" I/O: */ /* retry only "normal" I/O: */
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
rq->errors = 1; rq->errors = 1;
ide_end_drive_cmd(drive, stat, err); ide_end_drive_cmd(drive, rq, stat, err);
return ide_stopped; return ide_stopped;
} }
...@@ -869,8 +863,8 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request * ...@@ -869,8 +863,8 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *
} }
if (!OK_STAT(stat, READY_STAT, BAD_STAT)) if (!OK_STAT(stat, READY_STAT, BAD_STAT))
return ide_error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ return ide_error(drive, rq, "drive_cmd", stat); /* calls ide_end_drive_cmd */
ide_end_drive_cmd (drive, stat, GET_ERR()); ide_end_drive_cmd(drive, rq, stat, GET_ERR());
return ide_stopped; return ide_stopped;
} }
...@@ -886,8 +880,11 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request * ...@@ -886,8 +880,11 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *
* setting a timer to wake up at half second intervals thereafter, until * setting a timer to wake up at half second intervals thereafter, until
* timeout is achieved, before timing out. * timeout is achieved, before timing out.
*/ */
int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte good, byte bad, unsigned long timeout) { int ide_wait_stat(ide_startstop_t *startstop,
byte stat; struct ata_device *drive, struct request *rq,
byte good, byte bad, unsigned long timeout)
{
u8 stat;
int i; int i;
unsigned long flags; unsigned long flags;
...@@ -903,9 +900,9 @@ int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte goo ...@@ -903,9 +900,9 @@ int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte goo
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
timeout += jiffies; timeout += jiffies;
while ((stat = GET_STAT()) & BUSY_STAT) { while ((stat = GET_STAT()) & BUSY_STAT) {
if (0 < (signed long)(jiffies - timeout)) { if (time_after(timeout, jiffies)) {
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
*startstop = ide_error(drive, "status timeout", stat); *startstop = ide_error(drive, rq, "status timeout", stat);
return 1; return 1;
} }
} }
...@@ -923,7 +920,8 @@ int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte goo ...@@ -923,7 +920,8 @@ int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte goo
if (OK_STAT((stat = GET_STAT()), good, bad)) if (OK_STAT((stat = GET_STAT()), good, bad))
return 0; return 0;
} }
*startstop = ide_error(drive, "status error", stat); *startstop = ide_error(drive, rq, "status error", stat);
return 1; return 1;
} }
...@@ -975,7 +973,7 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r ...@@ -975,7 +973,7 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r
ide_startstop_t res; ide_startstop_t res;
SELECT_DRIVE(ch, drive); SELECT_DRIVE(ch, drive);
if (ide_wait_stat(&res, drive, drive->ready_stat, if (ide_wait_stat(&res, drive, rq, drive->ready_stat,
BUSY_STAT|DRQ_STAT, WAIT_READY)) { BUSY_STAT|DRQ_STAT, WAIT_READY)) {
printk(KERN_WARNING "%s: drive not ready for command\n", drive->name); printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
...@@ -1066,20 +1064,21 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r ...@@ -1066,20 +1064,21 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r
#ifdef DEBUG #ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name); printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif #endif
ide_end_drive_cmd(drive, GET_STAT(), GET_ERR()); ide_end_drive_cmd(drive, rq, GET_STAT(), GET_ERR());
return ide_stopped; return ide_stopped;
} }
ide_startstop_t restart_request(struct ata_device *drive) ide_startstop_t restart_request(struct ata_device *drive)
{ {
ide_hwgroup_t *hwgroup = HWGROUP(drive); struct ata_channel *ch = drive->channel;
ide_hwgroup_t *hwgroup = ch->hwgroup;
unsigned long flags; unsigned long flags;
struct request *rq; struct request *rq;
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
hwgroup->handler = NULL; hwgroup->handler = NULL;
del_timer(&hwgroup->timer); del_timer(&ch->timer);
rq = hwgroup->rq; rq = hwgroup->rq;
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
...@@ -1195,11 +1194,11 @@ static struct ata_device *choose_urgent_device(struct ata_channel *channel) ...@@ -1195,11 +1194,11 @@ static struct ata_device *choose_urgent_device(struct ata_channel *channel)
if (time_after(jiffies, sleep - WAIT_MIN_SLEEP)) if (time_after(jiffies, sleep - WAIT_MIN_SLEEP))
sleep = jiffies + WAIT_MIN_SLEEP; sleep = jiffies + WAIT_MIN_SLEEP;
#if 1 #if 1
if (timer_pending(&channel->hwgroup->timer)) if (timer_pending(&channel->timer))
printk(KERN_ERR "ide_set_handler: timer already active\n"); printk(KERN_ERR "ide_set_handler: timer already active\n");
#endif #endif
set_bit(IDE_SLEEP, &channel->hwgroup->flags); set_bit(IDE_SLEEP, &channel->hwgroup->flags);
mod_timer(&channel->hwgroup->timer, sleep); mod_timer(&channel->timer, sleep);
/* we purposely leave hwgroup busy while sleeping */ /* we purposely leave hwgroup busy while sleeping */
} else { } else {
/* Ugly, but how can we sleep for the lock otherwise? perhaps /* Ugly, but how can we sleep for the lock otherwise? perhaps
...@@ -1341,8 +1340,8 @@ static void queue_commands(struct ata_device *drive, int masked_irq) ...@@ -1341,8 +1340,8 @@ static void queue_commands(struct ata_device *drive, int masked_irq)
static void ide_do_request(struct ata_channel *channel, int masked_irq) static void ide_do_request(struct ata_channel *channel, int masked_irq)
{ {
ide_hwgroup_t *hwgroup = channel->hwgroup; ide_hwgroup_t *hwgroup = channel->hwgroup;
ide_get_lock(&irq_lock, ata_irq_request, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
ide_get_lock(&irq_lock, ata_irq_request, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
__cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */ __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */
while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) { while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) {
...@@ -1357,7 +1356,7 @@ static void ide_do_request(struct ata_channel *channel, int masked_irq) ...@@ -1357,7 +1356,7 @@ static void ide_do_request(struct ata_channel *channel, int masked_irq)
ch = drive->channel; ch = drive->channel;
if (hwgroup->XXX_drive->channel->sharing_irq && ch != hwgroup->XXX_drive->channel && ch->io_ports[IDE_CONTROL_OFFSET]) { if (channel->sharing_irq && ch != channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
/* set nIEN for previous channel */ /* set nIEN for previous channel */
/* FIXME: check this! It appears to act on the current channel! */ /* FIXME: check this! It appears to act on the current channel! */
...@@ -1369,7 +1368,7 @@ static void ide_do_request(struct ata_channel *channel, int masked_irq) ...@@ -1369,7 +1368,7 @@ static void ide_do_request(struct ata_channel *channel, int masked_irq)
/* Remember the last drive we where acting on. /* Remember the last drive we where acting on.
*/ */
hwgroup->XXX_drive = drive; ch->drive = drive;
queue_commands(drive, masked_irq); queue_commands(drive, masked_irq);
} }
...@@ -1423,7 +1422,8 @@ static void dma_timeout_retry(struct ata_device *drive, struct request *rq) ...@@ -1423,7 +1422,8 @@ static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
*/ */
void ide_timer_expiry(unsigned long data) void ide_timer_expiry(unsigned long data)
{ {
ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; struct ata_channel *ch = (struct ata_channel *) data;
ide_hwgroup_t *hwgroup = ch->hwgroup;
ata_handler_t *handler; ata_handler_t *handler;
ata_expiry_t *expiry; ata_expiry_t *expiry;
unsigned long flags; unsigned long flags;
...@@ -1435,7 +1435,7 @@ void ide_timer_expiry(unsigned long data) ...@@ -1435,7 +1435,7 @@ void ide_timer_expiry(unsigned long data)
*/ */
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
del_timer(&hwgroup->timer); del_timer(&ch->timer);
if ((handler = hwgroup->handler) == NULL) { if ((handler = hwgroup->handler) == NULL) {
...@@ -1449,23 +1449,22 @@ void ide_timer_expiry(unsigned long data) ...@@ -1449,23 +1449,22 @@ void ide_timer_expiry(unsigned long data)
if (test_and_clear_bit(IDE_SLEEP, &hwgroup->flags)) if (test_and_clear_bit(IDE_SLEEP, &hwgroup->flags))
clear_bit(IDE_BUSY, &hwgroup->flags); clear_bit(IDE_BUSY, &hwgroup->flags);
} else { } else {
struct ata_device *drive = hwgroup->XXX_drive; struct ata_device *drive = ch->drive;
if (!drive) { if (!drive) {
printk("ide_timer_expiry: hwgroup->drive was NULL\n"); printk("ide_timer_expiry: hwgroup->drive was NULL\n");
hwgroup->handler = NULL; hwgroup->handler = NULL;
} else { } else {
struct ata_channel *ch;
ide_startstop_t startstop; ide_startstop_t startstop;
/* paranoia */ /* paranoia */
if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags))
printk("%s: ide_timer_expiry: hwgroup was not busy??\n", drive->name); printk("%s: ide_timer_expiry: hwgroup was not busy??\n", drive->name);
if ((expiry = hwgroup->expiry) != NULL) { if ((expiry = ch->expiry) != NULL) {
/* continue */ /* continue */
if ((wait = expiry(drive, HWGROUP(drive)->rq)) != 0) { if ((wait = expiry(drive, HWGROUP(drive)->rq)) != 0) {
/* reengage timer */ /* reengage timer */
hwgroup->timer.expires = jiffies + wait; ch->timer.expires = jiffies + wait;
add_timer(&hwgroup->timer); add_timer(&ch->timer);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
return; return;
} }
...@@ -1497,7 +1496,7 @@ void ide_timer_expiry(unsigned long data) ...@@ -1497,7 +1496,7 @@ void ide_timer_expiry(unsigned long data)
startstop = ide_stopped; startstop = ide_stopped;
dma_timeout_retry(drive, ch->hwgroup->rq); dma_timeout_retry(drive, ch->hwgroup->rq);
} else } else
startstop = ide_error(drive, "irq timeout", GET_STAT()); startstop = ide_error(drive, ch->hwgroup->rq, "irq timeout", GET_STAT());
} }
set_recovery_timer(ch); set_recovery_timer(ch);
enable_irq(ch->irq); enable_irq(ch->irq);
...@@ -1507,7 +1506,7 @@ void ide_timer_expiry(unsigned long data) ...@@ -1507,7 +1506,7 @@ void ide_timer_expiry(unsigned long data)
} }
} }
ide_do_request(hwgroup->XXX_drive->channel, 0); ide_do_request(ch->drive->channel, 0);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
...@@ -1617,7 +1616,7 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs) ...@@ -1617,7 +1616,7 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
} }
goto out_lock; goto out_lock;
} }
drive = hwgroup->XXX_drive; drive = ch->drive;
if (!drive_is_ready(drive)) { if (!drive_is_ready(drive)) {
/* /*
* This happens regularly when we share a PCI IRQ with another device. * This happens regularly when we share a PCI IRQ with another device.
...@@ -1631,7 +1630,7 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs) ...@@ -1631,7 +1630,7 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags))
printk(KERN_ERR "%s: %s: hwgroup was not busy!?\n", drive->name, __FUNCTION__); printk(KERN_ERR "%s: %s: hwgroup was not busy!?\n", drive->name, __FUNCTION__);
hwgroup->handler = NULL; hwgroup->handler = NULL;
del_timer(&hwgroup->timer); del_timer(&ch->timer);
spin_unlock(&ide_lock); spin_unlock(&ide_lock);
if (ch->unmask) if (ch->unmask)
...@@ -2002,7 +2001,7 @@ void ide_unregister(struct ata_channel *ch) ...@@ -2002,7 +2001,7 @@ void ide_unregister(struct ata_channel *ch)
*/ */
hwgroup = ch->hwgroup; hwgroup = ch->hwgroup;
d = hwgroup->XXX_drive; d = ch->drive;
for (i = 0; i < MAX_DRIVES; ++i) { for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_device *drive = &ch->drives[i]; struct ata_device *drive = &ch->drives[i];
...@@ -2013,8 +2012,9 @@ void ide_unregister(struct ata_channel *ch) ...@@ -2013,8 +2012,9 @@ void ide_unregister(struct ata_channel *ch)
if (!drive->present) if (!drive->present)
continue; continue;
if (hwgroup->XXX_drive == drive) /* FIXME: possibly unneccessary */
hwgroup->XXX_drive = NULL; if (ch->drive == drive)
ch->drive = NULL;
if (drive->id != NULL) { if (drive->id != NULL) {
kfree(drive->id); kfree(drive->id);
...@@ -2024,7 +2024,7 @@ void ide_unregister(struct ata_channel *ch) ...@@ -2024,7 +2024,7 @@ void ide_unregister(struct ata_channel *ch)
blk_cleanup_queue(&drive->queue); blk_cleanup_queue(&drive->queue);
} }
if (d->present) if (d->present)
hwgroup->XXX_drive = d; ch->drive = d;
/* /*
...@@ -2220,84 +2220,6 @@ int ide_register(int arg1, int arg2, int irq) ...@@ -2220,84 +2220,6 @@ int ide_register(int arg1, int arg2, int irq)
return ide_register_hw(&hw, NULL); return ide_register_hw(&hw, NULL);
} }
void ide_add_setting(struct ata_device *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
{
ide_settings_t **p = &drive->settings;
ide_settings_t *setting = NULL;
while ((*p) && strcmp((*p)->name, name) < 0)
p = &((*p)->next);
if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
goto abort;
memset(setting, 0, sizeof(*setting));
if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
goto abort;
strcpy(setting->name, name); setting->rw = rw;
setting->read_ioctl = read_ioctl; setting->write_ioctl = write_ioctl;
setting->data_type = data_type; setting->min = min;
setting->max = max; setting->mul_factor = mul_factor;
setting->div_factor = div_factor; setting->data = data;
setting->set = set; setting->next = *p;
if (drive->driver)
setting->auto_remove = 1;
*p = setting;
return;
abort:
if (setting)
kfree(setting);
}
void ide_remove_setting(struct ata_device *drive, char *name)
{
ide_settings_t **p = &drive->settings, *setting;
while ((*p) && strcmp((*p)->name, name))
p = &((*p)->next);
if ((setting = (*p)) == NULL)
return;
(*p) = setting->next;
kfree(setting->name);
kfree(setting);
}
static void auto_remove_settings(struct ata_device *drive)
{
ide_settings_t *setting;
repeat:
setting = drive->settings;
while (setting) {
if (setting->auto_remove) {
ide_remove_setting(drive, setting->name);
goto repeat;
}
setting = setting->next;
}
}
int ide_read_setting(struct ata_device *drive, ide_settings_t *setting)
{
int val = -EINVAL;
unsigned long flags;
if ((setting->rw & SETTING_READ)) {
spin_lock_irqsave(&ide_lock, flags);
switch(setting->data_type) {
case TYPE_BYTE:
val = *((u8 *) setting->data);
break;
case TYPE_SHORT:
val = *((u16 *) setting->data);
break;
case TYPE_INT:
case TYPE_INTA:
val = *((u32 *) setting->data);
break;
}
spin_unlock_irqrestore(&ide_lock, flags);
}
return val;
}
int ide_spin_wait_hwgroup(struct ata_device *drive) int ide_spin_wait_hwgroup(struct ata_device *drive)
{ {
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
...@@ -2322,46 +2244,6 @@ int ide_spin_wait_hwgroup(struct ata_device *drive) ...@@ -2322,46 +2244,6 @@ int ide_spin_wait_hwgroup(struct ata_device *drive)
return 0; return 0;
} }
/*
* FIXME: This should be changed to enqueue a special request
* to the driver to change settings, and then wait on a semaphore for completion.
* The current scheme of polling is kludgey, though safe enough.
*/
int ide_write_setting(struct ata_device *drive, ide_settings_t *setting, int val)
{
int i;
u32 *p;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (!(setting->rw & SETTING_WRITE))
return -EPERM;
if (val < setting->min || val > setting->max)
return -EINVAL;
if (setting->set)
return setting->set(drive, val);
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
switch (setting->data_type) {
case TYPE_BYTE:
*((u8 *) setting->data) = val;
break;
case TYPE_SHORT:
*((u16 *) setting->data) = val;
break;
case TYPE_INT:
*((u32 *) setting->data) = val;
break;
case TYPE_INTA:
p = (u32 *) setting->data;
for (i = 0; i < 1 << PARTN_BITS; i++, p++)
*p = val;
break;
}
spin_unlock_irq(&ide_lock);
return 0;
}
static int set_io_32bit(struct ata_device *drive, int arg) static int set_io_32bit(struct ata_device *drive, int arg)
{ {
if (drive->channel->no_io_32bit) if (drive->channel->no_io_32bit)
...@@ -2381,6 +2263,7 @@ static int set_using_dma(struct ata_device *drive, int arg) ...@@ -2381,6 +2263,7 @@ static int set_using_dma(struct ata_device *drive, int arg)
return -EPERM; return -EPERM;
udma_enable(drive, arg, 1); udma_enable(drive, arg, 1);
return 0; return 0;
} }
...@@ -2401,20 +2284,6 @@ static int set_pio_mode(struct ata_device *drive, int arg) ...@@ -2401,20 +2284,6 @@ static int set_pio_mode(struct ata_device *drive, int arg)
return 0; return 0;
} }
void ide_add_generic_settings(struct ata_device *drive)
{
/* drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function */
ide_add_setting(drive, "io_32bit", drive->channel->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->channel->io_32bit, set_io_32bit);
ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode);
ide_add_setting(drive, "slow", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->channel->slow, NULL);
ide_add_setting(drive, "unmaskirq", drive->channel->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->channel->unmask, NULL);
ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma);
ide_add_setting(drive, "ide_scsi", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->scsi, NULL);
ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->init_speed, NULL);
ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->current_speed, NULL);
ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL);
}
/* /*
* Delay for *at least* 50ms. As we don't know how much time is left * Delay for *at least* 50ms. As we don't know how much time is left
* until the next tick occurs, we wait an extra tick to be safe. * until the next tick occurs, we wait an extra tick to be safe.
...@@ -2433,44 +2302,125 @@ void ide_delay_50ms (void) ...@@ -2433,44 +2302,125 @@ void ide_delay_50ms (void)
#endif /* CONFIG_BLK_DEV_IDECS */ #endif /* CONFIG_BLK_DEV_IDECS */
} }
/*
* Handle ioctls.
*
* NOTE: Due to ridiculous coding habbits in the hdparm utility we have to
* always return unsigned long in case we are returning simple values.
*/
static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{ {
int err = 0, major, minor; unsigned int major, minor;
struct ata_device *drive; struct ata_device *drive;
struct request rq; struct request rq;
kdev_t dev; kdev_t dev;
ide_settings_t *setting;
dev = inode->i_rdev; dev = inode->i_rdev;
major = major(dev); minor = minor(dev); major = major(dev); minor = minor(dev);
if ((drive = get_info_ptr(inode->i_rdev)) == NULL) if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
return -ENODEV; return -ENODEV;
/* Find setting by ioctl */
setting = drive->settings; /* Contrary to popular beleve we disallow even the reading of the ioctl
* values for users which don't have permission too. We do this becouse
* such information could be used by an attacker to deply a simple-user
* attack, which triggers bugs present only on a particular
* configuration.
*/
while (setting) { if (!capable(CAP_SYS_ADMIN))
if (setting->read_ioctl == cmd || setting->write_ioctl == cmd) return -EACCES;
break;
setting = setting->next;
}
if (setting != NULL) { ide_init_drive_cmd(&rq);
if (cmd == setting->read_ioctl) { switch (cmd) {
err = ide_read_setting(drive, setting); case HDIO_GET_32BIT: {
return err >= 0 ? put_user(err, (long *) arg) : err; unsigned long val = drive->channel->io_32bit;
} else {
if ((minor(inode->i_rdev) & PARTN_MASK)) if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_32BIT: {
int val;
if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
return -EINVAL; return -EINVAL;
return ide_write_setting(drive, setting, arg);
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_io_32bit(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
} }
}
ide_init_drive_cmd(&rq); case HDIO_SET_PIO_MODE: {
switch (cmd) { int val;
case HDIO_GETGEO:
{ if (arg < 0 || arg > 255)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_pio_mode(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
case HDIO_GET_UNMASKINTR: {
unsigned long val = drive->channel->unmask;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_UNMASKINTR: {
if (arg < 0 || arg > 1)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
if (drive->channel->no_unmask)
return -EIO;
drive->channel->unmask = arg;
spin_unlock_irq(&ide_lock);
return 0;
}
case HDIO_GET_DMA: {
unsigned long val = drive->using_dma;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_DMA: {
int val;
if (arg < 0 || arg > 1)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_using_dma(drive, arg);
spin_unlock_irq(&ide_lock);
return val;
}
case HDIO_GETGEO: {
struct hd_geometry *loc = (struct hd_geometry *) arg; struct hd_geometry *loc = (struct hd_geometry *) arg;
unsigned short bios_cyl = drive->bios_cyl; /* truncate */ unsigned short bios_cyl = drive->bios_cyl; /* truncate */
...@@ -2484,11 +2434,12 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u ...@@ -2484,11 +2434,12 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
return 0; return 0;
} }
case HDIO_GETGEO_BIG_RAW: case HDIO_GETGEO_BIG_RAW: {
{
struct hd_big_geometry *loc = (struct hd_big_geometry *) arg; struct hd_big_geometry *loc = (struct hd_big_geometry *) arg;
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY)) if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL; return -EINVAL;
if (put_user(drive->head, (u8 *) &loc->heads)) return -EFAULT; if (put_user(drive->head, (u8 *) &loc->heads)) return -EFAULT;
if (put_user(drive->sect, (u8 *) &loc->sectors)) return -EFAULT; if (put_user(drive->sect, (u8 *) &loc->sectors)) return -EFAULT;
if (put_user(drive->cyl, (unsigned int *) &loc->cylinders)) return -EFAULT; if (put_user(drive->cyl, (unsigned int *) &loc->cylinders)) return -EFAULT;
...@@ -2532,6 +2483,7 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u ...@@ -2532,6 +2483,7 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
return -EPERM; return -EPERM;
} }
return 0; return 0;
case BLKGETSIZE: case BLKGETSIZE:
case BLKGETSIZE64: case BLKGETSIZE64:
case BLKROSET: case BLKROSET:
...@@ -2566,6 +2518,9 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u ...@@ -2566,6 +2518,9 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
drive->channel->busproc(drive, (int)arg); drive->channel->busproc(drive, (int)arg);
return 0; return 0;
/* Now check whatever this particular ioctl has a special
* implementation.
*/
default: default:
if (ata_ops(drive) && ata_ops(drive)->ioctl) if (ata_ops(drive) && ata_ops(drive)->ioctl)
return ata_ops(drive)->ioctl(drive, inode, file, cmd, arg); return ata_ops(drive)->ioctl(drive, inode, file, cmd, arg);
...@@ -2573,7 +2528,7 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u ...@@ -2573,7 +2528,7 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
} }
} }
static int ide_check_media_change (kdev_t i_rdev) static int ide_check_media_change(kdev_t i_rdev)
{ {
struct ata_device *drive; struct ata_device *drive;
int res = 0; /* not changed */ int res = 0; /* not changed */
...@@ -3201,7 +3156,6 @@ int ide_unregister_subdriver(struct ata_device *drive) ...@@ -3201,7 +3156,6 @@ int ide_unregister_subdriver(struct ata_device *drive)
#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE) #if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE)
pnpide_init(0); pnpide_init(0);
#endif #endif
auto_remove_settings(drive);
drive->driver = NULL; drive->driver = NULL;
drive->present = 0; drive->present = 0;
...@@ -3255,7 +3209,6 @@ devfs_handle_t ide_devfs_handle; ...@@ -3255,7 +3209,6 @@ devfs_handle_t ide_devfs_handle;
EXPORT_SYMBOL(ide_lock); EXPORT_SYMBOL(ide_lock);
EXPORT_SYMBOL(drive_is_flashcard); EXPORT_SYMBOL(drive_is_flashcard);
EXPORT_SYMBOL(ide_timer_expiry); EXPORT_SYMBOL(ide_timer_expiry);
EXPORT_SYMBOL(ide_add_generic_settings);
EXPORT_SYMBOL(do_ide_request); EXPORT_SYMBOL(do_ide_request);
/* /*
* Driver module * Driver module
...@@ -3278,8 +3231,6 @@ EXPORT_SYMBOL(ide_revalidate_disk); ...@@ -3278,8 +3231,6 @@ EXPORT_SYMBOL(ide_revalidate_disk);
EXPORT_SYMBOL(ide_cmd); EXPORT_SYMBOL(ide_cmd);
EXPORT_SYMBOL(ide_delay_50ms); EXPORT_SYMBOL(ide_delay_50ms);
EXPORT_SYMBOL(ide_stall_queue); EXPORT_SYMBOL(ide_stall_queue);
EXPORT_SYMBOL(ide_add_setting);
EXPORT_SYMBOL(ide_remove_setting);
EXPORT_SYMBOL(ide_register_hw); EXPORT_SYMBOL(ide_register_hw);
EXPORT_SYMBOL(ide_register); EXPORT_SYMBOL(ide_register);
......
...@@ -185,7 +185,7 @@ int __init setup_pdc4030(struct ata_channel *hwif) ...@@ -185,7 +185,7 @@ int __init setup_pdc4030(struct ata_channel *hwif)
if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) { if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) {
return 0; return 0;
} }
if (ide_wait_stat(&startstop, drive,DATA_READY,BAD_W_STAT,WAIT_DRQ)) { if (ide_wait_stat(&startstop, drive, NULL, DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
printk(KERN_INFO printk(KERN_INFO
"%s: Failed Promise read config!\n",hwif->name); "%s: Failed Promise read config!\n",hwif->name);
return 0; return 0;
...@@ -309,14 +309,14 @@ void __init ide_probe_for_pdc4030(void) ...@@ -309,14 +309,14 @@ void __init ide_probe_for_pdc4030(void)
*/ */
static ide_startstop_t promise_read_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t promise_read_intr(struct ata_device *drive, struct request *rq)
{ {
byte stat; u8 stat;
int total_remaining; int total_remaining;
unsigned int sectors_left, sectors_avail, nsect; unsigned int sectors_left, sectors_avail, nsect;
unsigned long flags; unsigned long flags;
char *to; char *to;
if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
return ide_error(drive, "promise_read_intr", stat); return ide_error(drive, rq, "promise_read_intr", stat);
} }
read_again: read_again:
...@@ -348,17 +348,18 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques ...@@ -348,17 +348,18 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques
if ((rq->current_nr_sectors -= nsect) <= 0) { if ((rq->current_nr_sectors -= nsect) <= 0) {
ide_end_request(drive, rq, 1); ide_end_request(drive, rq, 1);
} }
/*
* Now the data has been read in, do the following: /*
* * Now the data has been read in, do the following:
* if there are still sectors left in the request, *
* if we know there are still sectors available from the interface, * if there are still sectors left in the request, if we know there are
* go back and read the next bit of the request. * still sectors available from the interface, go back and read the
* else if DRQ is asserted, there are more sectors available, so * next bit of the request. else if DRQ is asserted, there are more
* go back and find out how many, then read them in. * sectors available, so go back and find out how many, then read them
* else if BUSY is asserted, we are going to get an interrupt, so * in. else if BUSY is asserted, we are going to get an interrupt, so
* set the handler for the interrupt and just return * set the handler for the interrupt and just return
*/ */
if (total_remaining > 0) { if (total_remaining > 0) {
if (sectors_avail) if (sectors_avail)
goto read_next; goto read_next;
...@@ -375,7 +376,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques ...@@ -375,7 +376,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques
} }
printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left " printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "
"!DRQ !BUSY\n", drive->name); "!DRQ !BUSY\n", drive->name);
return ide_error(drive, "promise read intr", stat); return ide_error(drive, rq, "promise read intr", stat);
} }
return ide_stopped; return ide_stopped;
} }
...@@ -400,7 +401,7 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc ...@@ -400,7 +401,7 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc
ch->poll_timeout = 0; ch->poll_timeout = 0;
printk(KERN_ERR "%s: completion timeout - still busy!\n", printk(KERN_ERR "%s: completion timeout - still busy!\n",
drive->name); drive->name);
return ide_error(drive, "busy timeout", GET_STAT()); return ide_error(drive, rq, "busy timeout", GET_STAT());
} }
ch->poll_timeout = 0; ch->poll_timeout = 0;
...@@ -478,7 +479,7 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r ...@@ -478,7 +479,7 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r
} }
ch->poll_timeout = 0; ch->poll_timeout = 0;
printk(KERN_ERR "%s: write timed out!\n",drive->name); printk(KERN_ERR "%s: write timed out!\n",drive->name);
return ide_error(drive, "write timeout", GET_STAT()); return ide_error(drive, rq, "write timeout", GET_STAT());
} }
/* /*
...@@ -613,7 +614,7 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg ...@@ -613,7 +614,7 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
* call the promise_write function to deal with writing the data out * call the promise_write function to deal with writing the data out
* NOTE: No interrupts are generated on writes. Write completion must be polled * NOTE: No interrupts are generated on writes. Write completion must be polled
*/ */
if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing " printk(KERN_ERR "%s: no DRQ after issuing "
"PROMISE_WRITE\n", drive->name); "PROMISE_WRITE\n", drive->name);
return startstop; return startstop;
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#undef IDE_TCQ_FIDDLE_SI #undef IDE_TCQ_FIDDLE_SI
static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq); static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq);
static ide_startstop_t service(struct ata_device *drive); static ide_startstop_t service(struct ata_device *drive, struct request *rq);
static inline void drive_ctl_nien(struct ata_device *drive, int set) static inline void drive_ctl_nien(struct ata_device *drive, int set)
{ {
...@@ -70,7 +70,7 @@ static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request ...@@ -70,7 +70,7 @@ static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
ide__sti(); ide__sti();
ide_end_drive_cmd(drive, GET_STAT(), GET_ERR()); ide_end_drive_cmd(drive, rq, GET_STAT(), GET_ERR());
kfree(args); kfree(args);
return ide_stopped; return ide_stopped;
} }
...@@ -82,7 +82,8 @@ static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request ...@@ -82,7 +82,8 @@ static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request
*/ */
static void tcq_invalidate_queue(struct ata_device *drive) static void tcq_invalidate_queue(struct ata_device *drive)
{ {
ide_hwgroup_t *hwgroup = HWGROUP(drive); struct ata_channel *ch = drive->channel;
ide_hwgroup_t *hwgroup = ch->hwgroup;
request_queue_t *q = &drive->queue; request_queue_t *q = &drive->queue;
struct ata_taskfile *args; struct ata_taskfile *args;
struct request *rq; struct request *rq;
...@@ -92,7 +93,7 @@ static void tcq_invalidate_queue(struct ata_device *drive) ...@@ -92,7 +93,7 @@ static void tcq_invalidate_queue(struct ata_device *drive)
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
del_timer(&hwgroup->timer); del_timer(&ch->timer);
if (test_bit(IDE_DMA, &hwgroup->flags)) if (test_bit(IDE_DMA, &hwgroup->flags))
udma_stop(drive); udma_stop(drive);
...@@ -169,7 +170,7 @@ static void ata_tcq_irq_timeout(unsigned long data) ...@@ -169,7 +170,7 @@ static void ata_tcq_irq_timeout(unsigned long data)
* if pending commands, try service before giving up * if pending commands, try service before giving up
*/ */
if (ata_pending_commands(drive) && (GET_STAT() & SERVICE_STAT)) if (ata_pending_commands(drive) && (GET_STAT() & SERVICE_STAT))
if (service(drive) == ide_started) if (service(drive, hwgroup->rq) == ide_started)
return; return;
if (drive) if (drive)
...@@ -178,6 +179,7 @@ static void ata_tcq_irq_timeout(unsigned long data) ...@@ -178,6 +179,7 @@ static void ata_tcq_irq_timeout(unsigned long data)
static void set_irq(struct ata_device *drive, ata_handler_t *handler) static void set_irq(struct ata_device *drive, ata_handler_t *handler)
{ {
struct ata_channel *ch = drive->channel;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long flags; unsigned long flags;
...@@ -186,10 +188,14 @@ static void set_irq(struct ata_device *drive, ata_handler_t *handler) ...@@ -186,10 +188,14 @@ static void set_irq(struct ata_device *drive, ata_handler_t *handler)
/* /*
* always just bump the timer for now, the timeout handling will * always just bump the timer for now, the timeout handling will
* have to be changed to be per-command * have to be changed to be per-command
*
* FIXME: Jens - this is broken it will interfere with
* the normal timer function on serialized drives!
*/ */
hwgroup->timer.function = ata_tcq_irq_timeout;
hwgroup->timer.data = (unsigned long) hwgroup->XXX_drive; ch->timer.function = ata_tcq_irq_timeout;
mod_timer(&hwgroup->timer, jiffies + 5 * HZ); ch->timer.data = (unsigned long) ch->drive;
mod_timer(&ch->timer, jiffies + 5 * HZ);
hwgroup->handler = handler; hwgroup->handler = handler;
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
...@@ -223,9 +229,8 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request * ...@@ -223,9 +229,8 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
* *
* Also, nIEN must be set as not to need protection against ide_dmaq_intr * Also, nIEN must be set as not to need protection against ide_dmaq_intr
*/ */
static ide_startstop_t service(struct ata_device *drive) static ide_startstop_t service(struct ata_device *drive, struct request *rq)
{ {
struct request *rq;
u8 feat; u8 feat;
u8 stat; u8 stat;
int tag; int tag;
...@@ -242,7 +247,7 @@ static ide_startstop_t service(struct ata_device *drive) ...@@ -242,7 +247,7 @@ static ide_startstop_t service(struct ata_device *drive)
/* /*
* need to select the right drive first... * need to select the right drive first...
*/ */
if (drive != HWGROUP(drive)->XXX_drive) { if (drive != drive->channel->drive) {
SELECT_DRIVE(drive->channel, drive); SELECT_DRIVE(drive->channel, drive);
udelay(10); udelay(10);
} }
...@@ -256,8 +261,9 @@ static ide_startstop_t service(struct ata_device *drive) ...@@ -256,8 +261,9 @@ static ide_startstop_t service(struct ata_device *drive)
if (wait_altstat(drive, &stat, BUSY_STAT)) { if (wait_altstat(drive, &stat, BUSY_STAT)) {
printk(KERN_ERR"%s: BUSY clear took too long\n", __FUNCTION__); printk(KERN_ERR"%s: BUSY clear took too long\n", __FUNCTION__);
ide_dump_status(drive, __FUNCTION__, stat); ide_dump_status(drive, rq, __FUNCTION__, stat);
tcq_invalidate_queue(drive); tcq_invalidate_queue(drive);
return ide_stopped; return ide_stopped;
} }
...@@ -267,8 +273,9 @@ static ide_startstop_t service(struct ata_device *drive) ...@@ -267,8 +273,9 @@ static ide_startstop_t service(struct ata_device *drive)
* FIXME, invalidate queue * FIXME, invalidate queue
*/ */
if (stat & ERR_STAT) { if (stat & ERR_STAT) {
ide_dump_status(drive, __FUNCTION__, stat); ide_dump_status(drive, rq, __FUNCTION__, stat);
tcq_invalidate_queue(drive); tcq_invalidate_queue(drive);
return ide_stopped; return ide_stopped;
} }
...@@ -301,7 +308,7 @@ static ide_startstop_t service(struct ata_device *drive) ...@@ -301,7 +308,7 @@ static ide_startstop_t service(struct ata_device *drive)
return udma_tcq_start(drive, rq); return udma_tcq_start(drive, rq);
} }
static ide_startstop_t check_service(struct ata_device *drive) static ide_startstop_t check_service(struct ata_device *drive, struct request *rq)
{ {
u8 stat; u8 stat;
...@@ -311,7 +318,7 @@ static ide_startstop_t check_service(struct ata_device *drive) ...@@ -311,7 +318,7 @@ static ide_startstop_t check_service(struct ata_device *drive)
return ide_stopped; return ide_stopped;
if ((stat = GET_STAT()) & SERVICE_STAT) if ((stat = GET_STAT()) & SERVICE_STAT)
return service(drive); return service(drive, rq);
/* /*
* we have pending commands, wait for interrupt * we have pending commands, wait for interrupt
...@@ -335,8 +342,9 @@ ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq, ...@@ -335,8 +342,9 @@ ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq,
*/ */
if (unlikely(!OK_STAT(stat, READY_STAT, drive->bad_wstat | DRQ_STAT))) { if (unlikely(!OK_STAT(stat, READY_STAT, drive->bad_wstat | DRQ_STAT))) {
printk(KERN_ERR "%s: %s: error status %x\n", __FUNCTION__, drive->name,stat); printk(KERN_ERR "%s: %s: error status %x\n", __FUNCTION__, drive->name,stat);
ide_dump_status(drive, __FUNCTION__, stat); ide_dump_status(drive, rq, __FUNCTION__, stat);
tcq_invalidate_queue(drive); tcq_invalidate_queue(drive);
return ide_stopped; return ide_stopped;
} }
...@@ -349,7 +357,7 @@ ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq, ...@@ -349,7 +357,7 @@ ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq,
/* /*
* we completed this command, check if we can service a new command * we completed this command, check if we can service a new command
*/ */
return check_service(drive); return check_service(drive, rq);
} }
/* /*
...@@ -380,11 +388,11 @@ static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *r ...@@ -380,11 +388,11 @@ static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *r
*/ */
if (stat & SERVICE_STAT) { if (stat & SERVICE_STAT) {
TCQ_PRINTK("%s: SERV (stat=%x)\n", __FUNCTION__, stat); TCQ_PRINTK("%s: SERV (stat=%x)\n", __FUNCTION__, stat);
return service(drive); return service(drive, rq);
} }
printk("%s: stat=%x, not expected\n", __FUNCTION__, stat); printk("%s: stat=%x, not expected\n", __FUNCTION__, stat);
return check_service(drive); return check_service(drive, rq);
} }
/* /*
...@@ -558,7 +566,7 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq) ...@@ -558,7 +566,7 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG); OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
if (wait_altstat(drive, &stat, BUSY_STAT)) { if (wait_altstat(drive, &stat, BUSY_STAT)) {
ide_dump_status(drive, "queued start", stat); ide_dump_status(drive, rq, "queued start", stat);
tcq_invalidate_queue(drive); tcq_invalidate_queue(drive);
return ide_stopped; return ide_stopped;
} }
...@@ -566,7 +574,7 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq) ...@@ -566,7 +574,7 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
drive_ctl_nien(drive, 0); drive_ctl_nien(drive, 0);
if (stat & ERR_STAT) { if (stat & ERR_STAT) {
ide_dump_status(drive, "tcq_start", stat); ide_dump_status(drive, rq, "tcq_start", stat);
return ide_stopped; return ide_stopped;
} }
...@@ -582,7 +590,7 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq) ...@@ -582,7 +590,7 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
TCQ_PRINTK("REL in queued_start\n"); TCQ_PRINTK("REL in queued_start\n");
if ((stat = GET_STAT()) & SERVICE_STAT) if ((stat = GET_STAT()) & SERVICE_STAT)
return service(drive); return service(drive, rq);
return ide_released; return ide_released;
} }
......
...@@ -271,7 +271,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int ...@@ -271,7 +271,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int
ide_end_request(drive, rq, uptodate); ide_end_request(drive, rq, uptodate);
return 0; return 0;
} }
ide_end_drive_cmd (drive, 0, 0); ide_end_drive_cmd(drive, rq, 0, 0);
if (rq->errors >= ERROR_MAX) { if (rq->errors >= ERROR_MAX) {
pc->scsi_cmd->result = DID_ERROR << 16; pc->scsi_cmd->result = DID_ERROR << 16;
if (log) if (log)
...@@ -401,7 +401,7 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ ...@@ -401,7 +401,7 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ
byte ireason; byte ireason;
ide_startstop_t startstop; ide_startstop_t startstop;
if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
...@@ -489,20 +489,6 @@ static void idescsi_ide_release(struct inode *inode, struct file *filp, struct a ...@@ -489,20 +489,6 @@ static void idescsi_ide_release(struct inode *inode, struct file *filp, struct a
static ide_drive_t *idescsi_drives[MAX_HWIFS * MAX_DRIVES]; static ide_drive_t *idescsi_drives[MAX_HWIFS * MAX_DRIVES];
static int idescsi_initialized = 0; static int idescsi_initialized = 0;
static void idescsi_add_settings(ide_drive_t *drive)
{
idescsi_scsi_t *scsi = drive->driver_data;
/*
* drive setting name read/write ioctl ioctl data type min max mul_factor div_factor data pointer set function
*/
ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL);
ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL);
ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
ide_add_setting(drive, "transform", SETTING_RW, -1, -1, TYPE_INT, 0, 3, 1, 1, &scsi->transform, NULL);
ide_add_setting(drive, "log", SETTING_RW, -1, -1, TYPE_INT, 0, 1, 1, 1, &scsi->log, NULL);
}
/* /*
* Driver initialization. * Driver initialization.
*/ */
...@@ -521,8 +507,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id) ...@@ -521,8 +507,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
set_bit(IDESCSI_LOG_CMD, &scsi->log); set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif /* IDESCSI_DEBUG_LOG */ #endif
idescsi_add_settings(drive);
} }
static int idescsi_cleanup (ide_drive_t *drive) static int idescsi_cleanup (ide_drive_t *drive)
......
...@@ -264,8 +264,6 @@ void ide_setup_ports(hw_regs_t *hw, ...@@ -264,8 +264,6 @@ void ide_setup_ports(hw_regs_t *hw,
#define ATA_SCSI 0x21 #define ATA_SCSI 0x21
#define ATA_NO_LUN 0x7f #define ATA_NO_LUN 0x7f
struct ide_settings_s;
typedef union { typedef union {
unsigned all : 8; /* all of the bits together */ unsigned all : 8; /* all of the bits together */
struct { struct {
...@@ -329,8 +327,6 @@ struct ata_device { ...@@ -329,8 +327,6 @@ struct ata_device {
unsigned long sleep; /* sleep until this time */ unsigned long sleep; /* sleep until this time */
u8 XXX_tune_req; /* requested drive tuning setting */
byte using_dma; /* disk is using dma for read/write */ byte using_dma; /* disk is using dma for read/write */
byte using_tcq; /* disk is using queueing */ byte using_tcq; /* disk is using queueing */
byte retry_pio; /* retrying dma capable host in pio */ byte retry_pio; /* retrying dma capable host in pio */
...@@ -379,7 +375,6 @@ struct ata_device { ...@@ -379,7 +375,6 @@ struct ata_device {
void *driver_data; /* extra driver data */ void *driver_data; /* extra driver data */
devfs_handle_t de; /* directory for device */ devfs_handle_t de; /* directory for device */
struct ide_settings_s *settings; /* ioctl entires */
char driver_req[10]; /* requests specific driver */ char driver_req[10]; /* requests specific driver */
int last_lun; /* last logical unit */ int last_lun; /* last logical unit */
...@@ -418,6 +413,9 @@ struct ata_channel { ...@@ -418,6 +413,9 @@ struct ata_channel {
int unit; /* channel number */ int unit; /* channel number */
struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */
struct timer_list timer; /* failsafe timer */
int (*expiry)(struct ata_device *, struct request *); /* irq handler, if active */
struct ata_device *drive; /* last serviced drive */
ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */
hw_regs_t hw; /* Hardware info */ hw_regs_t hw; /* Hardware info */
...@@ -569,50 +567,10 @@ typedef struct hwgroup_s { ...@@ -569,50 +567,10 @@ typedef struct hwgroup_s {
*/ */
ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */ ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */
unsigned long flags; /* BUSY, SLEEPING */ unsigned long flags; /* BUSY, SLEEPING */
struct ata_device *XXX_drive; /* current drive */
struct request *rq; /* current request */ struct request *rq; /* current request */
struct timer_list timer; /* failsafe timer */
int (*expiry)(struct ata_device *, struct request *); /* irq handler, if active */
} ide_hwgroup_t; } ide_hwgroup_t;
/* structure attached to the request for IDE_TASK_CMDS */ /* FIXME: kill this as soon as possible */
/*
* configurable drive settings
*/
#define TYPE_INT 0
#define TYPE_INTA 1
#define TYPE_BYTE 2
#define TYPE_SHORT 3
#define SETTING_READ (1 << 0)
#define SETTING_WRITE (1 << 1)
#define SETTING_RW (SETTING_READ | SETTING_WRITE)
typedef int (ide_procset_t)(struct ata_device *, int);
typedef struct ide_settings_s {
char *name;
int rw;
int read_ioctl;
int write_ioctl;
int data_type;
int min;
int max;
int mul_factor;
int div_factor;
void *data;
ide_procset_t *set;
int auto_remove;
struct ide_settings_s *next;
} ide_settings_t;
extern void ide_add_setting(struct ata_device *, const char *, int, int, int, int, int, int, int, int, void *, ide_procset_t *);
extern void ide_remove_setting(struct ata_device *, char *);
extern int ide_read_setting(struct ata_device *, ide_settings_t *);
extern int ide_write_setting(struct ata_device *, ide_settings_t *, int);
extern void ide_add_generic_settings(struct ata_device *);
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; #define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
/* /*
...@@ -683,13 +641,10 @@ extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler, ...@@ -683,13 +641,10 @@ extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
/* /*
* Error reporting, in human readable form (luxurious, but a memory hog). * Error reporting, in human readable form (luxurious, but a memory hog).
*/ */
extern byte ide_dump_status(struct ata_device *, const char *, byte); extern u8 ide_dump_status(struct ata_device *, struct request *rq, const char *, u8);
/* extern ide_startstop_t ide_error(struct ata_device *, struct request *rq,
* ide_error() takes action based on the error returned by the controller. const char *, byte);
* The caller should return immediately after invoking this.
*/
extern ide_startstop_t ide_error(struct ata_device *, const char *, byte);
/* /*
* Issue a simple drive command * Issue a simple drive command
...@@ -713,7 +668,9 @@ void ide_fixstring(byte *s, const int bytecount, const int byteswap); ...@@ -713,7 +668,9 @@ void ide_fixstring(byte *s, const int bytecount, const int byteswap);
* caller should return the updated value of "startstop" in this case. * caller should return the updated value of "startstop" in this case.
* "startstop" is unchanged when the function returns 0; * "startstop" is unchanged when the function returns 0;
*/ */
extern int ide_wait_stat(ide_startstop_t *, struct ata_device *, byte, byte, unsigned long); extern int ide_wait_stat(ide_startstop_t *,
struct ata_device *, struct request *rq,
byte, byte, unsigned long);
extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long); extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
...@@ -759,7 +716,7 @@ extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t) ...@@ -759,7 +716,7 @@ extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t)
/* /*
* Clean up after success/failure of an explicit drive cmd. * Clean up after success/failure of an explicit drive cmd.
*/ */
extern void ide_end_drive_cmd(struct ata_device *, byte, byte); extern void ide_end_drive_cmd(struct ata_device *, struct request *, u8, u8);
struct ata_taskfile { struct ata_taskfile {
struct hd_drive_task_hdr taskfile; struct hd_drive_task_hdr taskfile;
......
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