Commit 5be8243b authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.7 IDE 28a

- Apply Pavel Macheks suspend resume double resume fix.

- Finally remove the busy field for ata_operations and replace it with
   MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT.

- Fix ali15xx chipset support by removing initialization differences,
   apparently caused by mislead interpretation of the specs or a mismatch
   between the specification and reality.

- Guard calls to ide_set_handler with checks to see whatever the previously
   installed IRQ handler already served it's purpose.

- Convert timeout checks on poll_timeout to the time_before() interface.

- Consolidate the two different IRQ handlers for multi mode PIO writes into
   one. The problems remain the same but at least now we will only have to
   tangle one single problem.
parent ff3c2cbb
...@@ -798,7 +798,7 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -798,7 +798,7 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
* not a diskdrive. * not a diskdrive.
*/ */
if (drive->media != ide_disk) if (drive->type != ATA_DISK)
return 0; return 0;
dma_begin: dma_begin:
...@@ -809,7 +809,7 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -809,7 +809,7 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
WAIT_DMA(ATA_RX_DMA_NBR); WAIT_DMA(ATA_RX_DMA_NBR);
/* set up the Etrax DMA descriptors */ /* set up the Etrax DMA descriptors */
if(e100_ide_build_dmatable (drive)) if(e100_ide_build_dmatable (drive))
return 1; return 1;
......
...@@ -334,6 +334,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -334,6 +334,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0; return 0;
......
...@@ -441,9 +441,10 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -441,9 +441,10 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
: DMA_MODE_WRITE); : DMA_MODE_WRITE);
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
if (drive->media != ide_disk) if (drive->type != ATA_DISK)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
IDE_COMMAND_REG); IDE_COMMAND_REG);
......
...@@ -740,11 +740,12 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, ...@@ -740,11 +740,12 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG); OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG);
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl, IDE_CONTROL_REG); OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
if (info->dma) if (info->dma)
(void) drive->channel->dmaproc(ide_dma_begin, drive); (void) drive->channel->dmaproc(ide_dma_begin, drive);
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry); ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
return ide_started; return ide_started;
...@@ -787,6 +788,7 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, ...@@ -787,6 +788,7 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
} }
/* Arm the interrupt handler. */ /* Arm the interrupt handler. */
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, handler, timeout, cdrom_timer_expiry); ide_set_handler (drive, handler, timeout, cdrom_timer_expiry);
/* Send the command to the device. */ /* Send the command to the device. */
...@@ -1005,7 +1007,9 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) ...@@ -1005,7 +1007,9 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
/* Done moving data! /* Done moving data!
Wait for another interrupt. */ Wait for another interrupt. */
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL); ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
...@@ -1335,6 +1339,8 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) ...@@ -1335,6 +1339,8 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
} }
/* Now we wait for another interrupt. */ /* Now we wait for another interrupt. */
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
return ide_started; return ide_started;
} }
...@@ -1559,6 +1565,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) ...@@ -1559,6 +1565,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
} }
/* re-arm handler */ /* re-arm handler */
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL); ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
...@@ -2984,15 +2991,14 @@ int ide_cdrom_init(void) ...@@ -2984,15 +2991,14 @@ int ide_cdrom_init(void)
memset (info, 0, sizeof (struct cdrom_info)); memset (info, 0, sizeof (struct cdrom_info));
drive->driver_data = info; drive->driver_data = info;
/* ATA-PATTERN */ MOD_INC_USE_COUNT;
ata_ops(drive)->busy++;
if (ide_cdrom_setup (drive)) { if (ide_cdrom_setup (drive)) {
ata_ops(drive)->busy--; MOD_DEC_USE_COUNT;
if (ide_cdrom_cleanup (drive)) if (ide_cdrom_cleanup (drive))
printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name); printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
continue; continue;
} }
ata_ops(drive)->busy--; MOD_DEC_USE_COUNT;
failed--; failed--;
} }
......
...@@ -323,7 +323,7 @@ static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq ...@@ -323,7 +323,7 @@ static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq
while (drive->blocked) { while (drive->blocked) {
yield(); yield();
// panic("ide: Request while drive blocked?"); printk("ide: Request while drive blocked?");
} }
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
...@@ -380,12 +380,14 @@ static int idedisk_flushcache(ide_drive_t *drive) ...@@ -380,12 +380,14 @@ static int idedisk_flushcache(ide_drive_t *drive)
{ {
struct hd_drive_task_hdr taskfile; struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile; struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr)); memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
if (drive->id->cfs_enable_2 & 0x2400) if (drive->id->cfs_enable_2 & 0x2400)
taskfile.command = WIN_FLUSH_CACHE_EXT; taskfile.command = WIN_FLUSH_CACHE_EXT;
else else
taskfile.command = WIN_FLUSH_CACHE; taskfile.command = WIN_FLUSH_CACHE;
return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL); return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
} }
...@@ -504,7 +506,7 @@ static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long a ...@@ -504,7 +506,7 @@ static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long a
args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40; args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
args.taskfile.command = WIN_SET_MAX; args.taskfile.command = WIN_SET_MAX;
args.handler = task_no_data_intr; args.handler = task_no_data_intr;
/* submit command request */ /* submit command request */
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args, NULL);
/* if OK, read new maximum address value */ /* if OK, read new maximum address value */
...@@ -540,7 +542,7 @@ static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsign ...@@ -540,7 +542,7 @@ static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsign
args.hobfile.device_head = 0x40; args.hobfile.device_head = 0x40;
args.hobfile.control = (drive->ctl | 0x80); args.hobfile.control = (drive->ctl | 0x80);
args.handler = task_no_data_intr; args.handler = task_no_data_intr;
/* submit command request */ /* submit command request */
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */ /* if OK, compute maximum address value */
...@@ -611,10 +613,10 @@ static void init_idedisk_capacity (ide_drive_t *drive) ...@@ -611,10 +613,10 @@ static void init_idedisk_capacity (ide_drive_t *drive)
drive->select.b.lba = 1; drive->select.b.lba = 1;
drive->id->lba_capacity_2 = capacity_2; drive->id->lba_capacity_2 = capacity_2;
} }
#else /* !CONFIG_IDEDISK_STROKE */ #else
printk("%s: setmax_ext LBA %llu, native %llu\n", printk("%s: setmax_ext LBA %llu, native %llu\n",
drive->name, set_max_ext, capacity_2); drive->name, set_max_ext, capacity_2);
#endif /* CONFIG_IDEDISK_STROKE */ #endif
} }
drive->bios_cyl = drive->cyl; drive->bios_cyl = drive->cyl;
drive->capacity48 = capacity_2; drive->capacity48 = capacity_2;
...@@ -637,10 +639,10 @@ static void init_idedisk_capacity (ide_drive_t *drive) ...@@ -637,10 +639,10 @@ static void init_idedisk_capacity (ide_drive_t *drive)
drive->select.b.lba = 1; drive->select.b.lba = 1;
drive->id->lba_capacity = capacity; drive->id->lba_capacity = capacity;
} }
#else /* !CONFIG_IDEDISK_STROKE */ #else
printk("%s: setmax LBA %lu, native %lu\n", printk("%s: setmax LBA %lu, native %lu\n",
drive->name, set_max, capacity); drive->name, set_max, capacity);
#endif /* CONFIG_IDEDISK_STROKE */ #endif
} }
drive->capacity = capacity; drive->capacity = capacity;
...@@ -954,6 +956,9 @@ static int idedisk_suspend(struct device *dev, u32 state, u32 level) ...@@ -954,6 +956,9 @@ static int idedisk_suspend(struct device *dev, u32 state, u32 level)
* already been done... * already been done...
*/ */
if (level != SUSPEND_SAVE_STATE)
return 0;
/* wait until all commands are finished */ /* wait until all commands are finished */
printk("ide_disk_suspend()\n"); printk("ide_disk_suspend()\n");
while (HWGROUP(drive)->handler) while (HWGROUP(drive)->handler)
...@@ -973,6 +978,9 @@ static int idedisk_suspend(struct device *dev, u32 state, u32 level) ...@@ -973,6 +978,9 @@ static int idedisk_suspend(struct device *dev, u32 state, u32 level)
static int idedisk_resume(struct device *dev, u32 level) static int idedisk_resume(struct device *dev, u32 level)
{ {
ide_drive_t *drive = dev->driver_data; ide_drive_t *drive = dev->driver_data;
if (level != RESUME_RESTORE_STATE)
return 0;
if (!drive->blocked) if (!drive->blocked)
panic("ide: Resume but not suspended?\n"); panic("ide: Resume but not suspended?\n");
...@@ -1113,8 +1121,11 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -1113,8 +1121,11 @@ static void idedisk_setup(ide_drive_t *drive)
(void) probe_lba_addressing(drive, 1); (void) probe_lba_addressing(drive, 1);
} }
static int idedisk_cleanup (ide_drive_t *drive) static int idedisk_cleanup(ide_drive_t *drive)
{ {
if (!drive)
return 0;
put_device(&drive->device); put_device(&drive->device);
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (idedisk_flushcache(drive)) if (idedisk_flushcache(drive))
......
...@@ -588,6 +588,8 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -588,6 +588,8 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) && if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
(drive->addressing == 1)) { (drive->addressing == 1)) {
......
...@@ -968,6 +968,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) ...@@ -968,6 +968,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
idefloppy_discard_data (drive,bcount.all); idefloppy_discard_data (drive,bcount.all);
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
...@@ -990,7 +991,9 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) ...@@ -990,7 +991,9 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
pc->actually_transferred+=bcount.all; /* Update the current position */ pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all; pc->current_position+=bcount.all;
ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */
return ide_started; return ide_started;
} }
...@@ -1014,8 +1017,11 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) ...@@ -1014,8 +1017,11 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive)
printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
return ide_stopped; return ide_stopped;
} }
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */ atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
return ide_started; return ide_started;
} }
...@@ -1055,17 +1061,19 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) ...@@ -1055,17 +1061,19 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
return ide_stopped; return ide_stopped;
} }
/* /*
* The following delay solves a problem with ATAPI Zip 100 drives where the * The following delay solves a problem with ATAPI Zip 100 drives where the
* Busy flag was apparently being deasserted before the unit was ready to * Busy flag was apparently being deasserted before the unit was ready to
* receive data. This was happening on a 1200 MHz Athlon system. 10/26/01 * receive data. This was happening on a 1200 MHz Athlon system. 10/26/01
* 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will
* not be actually used until after the packet is moved in about 50 msec. * not be actually used until after the packet is moved in about 50 msec.
*/ */
ide_set_handler (drive, BUG_ON(HWGROUP(drive)->handler);
&idefloppy_pc_intr, /* service routine for packet command */ ide_set_handler (drive,
&idefloppy_pc_intr, /* service routine for packet command */
floppy->ticks, /* wait this long before "failing" */ floppy->ticks, /* wait this long before "failing" */
&idefloppy_transfer_pc2); /* fail == transfer_pc2 */ &idefloppy_transfer_pc2); /* fail == transfer_pc2 */
return ide_started; return ide_started;
} }
...@@ -1143,8 +1151,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p ...@@ -1143,8 +1151,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
} else { } else {
pkt_xfer_routine = &idefloppy_transfer_pc; /* immediate */ pkt_xfer_routine = &idefloppy_transfer_pc; /* immediate */
} }
if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
return ide_started; return ide_started;
...@@ -1156,7 +1165,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p ...@@ -1156,7 +1165,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
static void idefloppy_rw_callback (ide_drive_t *drive) static void idefloppy_rw_callback (ide_drive_t *drive)
{ {
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n"); printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif /* IDEFLOPPY_DEBUG_LOG */
...@@ -2109,10 +2118,9 @@ int idefloppy_init (void) ...@@ -2109,10 +2118,9 @@ int idefloppy_init (void)
kfree (floppy); kfree (floppy);
continue; continue;
} }
/* ATA-PATTERN */ MOD_INC_USE_COUNT;
ata_ops(drive)->busy++;
idefloppy_setup (drive, floppy); idefloppy_setup (drive, floppy);
ata_ops(drive)->busy--; MOD_DEC_USE_COUNT;
failed--; failed--;
} }
......
...@@ -931,12 +931,12 @@ pmac_ide_check_dma(ide_drive_t *drive) ...@@ -931,12 +931,12 @@ pmac_ide_check_dma(ide_drive_t *drive)
int enable = 1; int enable = 1;
drive->using_dma = 0; drive->using_dma = 0;
idx = pmac_ide_find(drive); idx = pmac_ide_find(drive);
if (idx < 0) if (idx < 0)
return 0; return 0;
if (drive->media == ide_floppy) if (drive->type == ATA_FLOPPY)
enable = 0; enable = 0;
if (((id->capability & 1) == 0) && !check_drive_lists(drive, GOOD_DMA_DRIVE)) if (((id->capability & 1) == 0) && !check_drive_lists(drive, GOOD_DMA_DRIVE))
enable = 0; enable = 0;
...@@ -945,9 +945,9 @@ pmac_ide_check_dma(ide_drive_t *drive) ...@@ -945,9 +945,9 @@ pmac_ide_check_dma(ide_drive_t *drive)
udma = 0; udma = 0;
ata4 = (pmac_ide[idx].kind == controller_kl_ata4); ata4 = (pmac_ide[idx].kind == controller_kl_ata4);
if(enable) { if(enable) {
if (ata4 && (drive->media == ide_disk) && if (ata4 && (drive->type == ATA_DISK) &&
(id->field_valid & 0x0004) && (id->dma_ultra & 0x17)) { (id->field_valid & 0x0004) && (id->dma_ultra & 0x17)) {
/* UltraDMA modes. */ /* UltraDMA modes. */
drive->using_dma = pmac_ide_udma_enable(drive, idx); drive->using_dma = pmac_ide_udma_enable(drive, idx);
...@@ -994,8 +994,9 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -994,8 +994,9 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write)) if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write))
return 1; return 1;
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
if (drive->media != ide_disk) if (drive->type != ATA_DISK)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA, OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
IDE_COMMAND_REG); IDE_COMMAND_REG);
...@@ -1054,12 +1055,12 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -1054,12 +1055,12 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base) static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base)
{ {
int j; int j;
/* FIXME: We only handle the master IDE disk, we shoud /* FIXME: We only handle the master IDE disk, we shoud
* try to fix CD-ROMs here * try to fix CD-ROMs here
*/ */
switch (drive->media) { switch (drive->type) {
case ide_disk: case ATA_DISK:
/* Spin down the drive */ /* Spin down the drive */
outb(0xa0, base+0x60); outb(0xa0, base+0x60);
outb(0x0, base+0x30); outb(0x0, base+0x30);
...@@ -1067,7 +1068,7 @@ static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base) ...@@ -1067,7 +1068,7 @@ static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base)
outb(0x0, base+0x40); outb(0x0, base+0x40);
outb(0x0, base+0x50); outb(0x0, base+0x50);
outb(0xe0, base+0x70); outb(0xe0, base+0x70);
outb(0x2, base+0x160); outb(0x2, base+0x160);
for (j = 0; j < 10; j++) { for (j = 0; j < 10; j++) {
int status; int status;
mdelay(100); mdelay(100);
...@@ -1076,10 +1077,10 @@ static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base) ...@@ -1076,10 +1077,10 @@ static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base)
break; break;
} }
break; break;
case ide_cdrom: case ATA_ROM:
// todo // todo
break; break;
case ide_floppy: case ATA_FLOPPY:
// todo // todo
break; break;
} }
......
...@@ -2155,7 +2155,8 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) ...@@ -2155,7 +2155,8 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
idetape_discard_data (drive, bcount.all); idetape_discard_data (drive, bcount.all);
ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
...@@ -2181,7 +2182,8 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) ...@@ -2181,7 +2182,8 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
#endif #endif
ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */ BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */
return ide_started; return ide_started;
} }
...@@ -2255,6 +2257,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) ...@@ -2255,6 +2257,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
return ide_stopped; return ide_stopped;
} }
tape->cmd_start_time = jiffies; tape->cmd_start_time = jiffies;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */ ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */ atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */
return ide_started; return ide_started;
...@@ -2328,6 +2331,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape ...@@ -2328,6 +2331,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
return ide_started; return ide_started;
...@@ -6099,8 +6103,7 @@ static int idetape_cleanup (ide_drive_t *drive) ...@@ -6099,8 +6103,7 @@ static int idetape_cleanup (ide_drive_t *drive)
idetape_chrdevs[minor].drive = NULL; idetape_chrdevs[minor].drive = NULL;
restore_flags (flags); /* all CPUs (overkill?) */ restore_flags (flags); /* all CPUs (overkill?) */
/* FIXME: this appears to be totally wrong! */ MOD_DEC_USE_COUNT;
ata_ops(drive)->busy = 0;
ide_unregister_subdriver (drive); ide_unregister_subdriver (drive);
drive->driver_data = NULL; drive->driver_data = NULL;
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define DEBUG_TASKFILE 0 /* unset when fixed */ #define DEBUG_TASKFILE 0 /* unset when fixed */
#if DEBUG_TASKFILE #if DEBUG_TASKFILE
#define DTF(x...) printk(##x) #define DTF(x...) printk(x)
#else #else
#define DTF(x...) #define DTF(x...)
#endif #endif
...@@ -55,7 +55,7 @@ static inline void ide_unmap_rq(struct request *rq, char *to, ...@@ -55,7 +55,7 @@ static inline void ide_unmap_rq(struct request *rq, char *to,
unsigned long *flags) unsigned long *flags)
{ {
if (rq->bio) if (rq->bio)
bio_kunmap_irq(to, flags); bio_kunmap_irq(to, flags);
} }
static void bswap_data (void *buffer, int wcount) static void bswap_data (void *buffer, int wcount)
...@@ -288,73 +288,104 @@ void ata_poll_drive_ready(ide_drive_t *drive) ...@@ -288,73 +288,104 @@ void ata_poll_drive_ready(ide_drive_t *drive)
break; break;
} }
} }
static ide_startstop_t bio_mulout_intr(ide_drive_t *drive);
/* static ide_startstop_t pre_task_mulout_intr(ide_drive_t *drive, struct request *rq)
* Handler for command write multiple {
* Called directly from execute_drive_cmd for the first bunch of sectors, ide_task_t *args = rq->special;
* afterwards only by the ISR ide_startstop_t startstop;
*/
static ide_startstop_t task_mulout_intr(ide_drive_t *drive) /*
* assign private copy for multi-write
*/
memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ))
return startstop;
ata_poll_drive_ready(drive);
return args->handler(drive);
}
static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
{ {
unsigned int msect, nsect;
byte stat = GET_STAT(); byte stat = GET_STAT();
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq; struct request *rq = &HWGROUP(drive)->wrq;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
char *pBuf = NULL; int mcount = drive->mult_count;
unsigned long flags; ide_startstop_t startstop;
/* /*
* (ks/hs): Handle last IRQ on multi-sector transfer, * (ks/hs): Handle last IRQ on multi-sector transfer,
* occurs after all data was sent in this chunk * occurs after all data was sent in this chunk
*/ */
if (rq->current_nr_sectors == 0) { if (!rq->nr_sectors) {
if (stat & (ERR_STAT|DRQ_STAT)) if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_mulout_intr", stat); startstop = ide_error(drive, "task_mulout_intr", stat);
memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
return startstop;
}
/* __ide_end_request(drive, 1, rq->hard_nr_sectors);
* there may be more, ide_do_request will restart it if rq->bio = NULL;
* necessary
*/
ide_end_request(drive, 1);
return ide_stopped; return ide_stopped;
} }
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_mulout_intr", stat); startstop = ide_error(drive, "task_mulout_intr", stat);
memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
return startstop;
} }
/* no data yet, so wait for another interrupt */ /* no data yet, so wait for another interrupt */
if (hwgroup->handler == NULL) if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
/* (ks/hs): See task_mulin_intr */ do {
msect = drive->mult_count; char *buffer;
nsect = rq->current_nr_sectors; int nsect = rq->current_nr_sectors;
if (nsect > msect) unsigned long flags;
nsect = msect;
pBuf = ide_map_rq(rq, &flags); if (nsect > mcount)
DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", nsect = mcount;
pBuf, nsect, rq->current_nr_sectors); mcount -= nsect;
drive->io_32bit = 0; buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); rq->sector += nsect;
rq->nr_sectors -= nsect;
rq->current_nr_sectors -= nsect;
ide_unmap_rq(rq, pBuf, &flags); /* Do we move to the next bio after this? */
if (!rq->current_nr_sectors) {
/* remember to fix this up /jens */
struct bio *bio = rq->bio->bi_next;
drive->io_32bit = io_32bit; /* end early if we ran out of requests */
if (!bio) {
mcount = 0;
} else {
rq->bio = bio;
rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
}
}
rq->errors = 0; /*
/* Are we sure that this as all been already transfered? */ * Ok, we're all setup for the interrupt
rq->current_nr_sectors -= nsect; * re-entering us on the last transfer.
*/
taskfile_output_data(drive, buffer, nsect * SECTOR_WORDS);
bio_kunmap_irq(buffer, &flags);
} while (mcount);
drive->io_32bit = io_32bit;
rq->errors = 0;
if (hwgroup->handler == NULL) if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
...@@ -371,7 +402,7 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive, ...@@ -371,7 +402,7 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive,
u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF; u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
/* (ks/hs): Moved to start, do not use for multiple out commands */ /* (ks/hs): Moved to start, do not use for multiple out commands */
if (handler != task_mulout_intr && handler != bio_mulout_intr) { if (handler != task_mulout_intr) {
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(drive->channel, drive, 0); SELECT_MASK(drive->channel, drive, 0);
...@@ -583,107 +614,6 @@ static ide_startstop_t task_out_intr(ide_drive_t *drive) ...@@ -583,107 +614,6 @@ static ide_startstop_t task_out_intr(ide_drive_t *drive)
return ide_started; return ide_started;
} }
static ide_startstop_t pre_bio_out_intr(ide_drive_t *drive, struct request *rq)
{
ide_task_t *args = rq->special;
ide_startstop_t startstop;
/*
* assign private copy for multi-write
*/
memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ))
return startstop;
ata_poll_drive_ready(drive);
return args->handler(drive);
}
static ide_startstop_t bio_mulout_intr (ide_drive_t *drive)
{
byte stat = GET_STAT();
byte io_32bit = drive->io_32bit;
struct request *rq = &HWGROUP(drive)->wrq;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
int mcount = drive->mult_count;
ide_startstop_t startstop;
/*
* (ks/hs): Handle last IRQ on multi-sector transfer,
* occurs after all data was sent in this chunk
*/
if (!rq->nr_sectors) {
if (stat & (ERR_STAT|DRQ_STAT)) {
startstop = ide_error(drive, "bio_mulout_intr", stat);
memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
return startstop;
}
__ide_end_request(drive, 1, rq->hard_nr_sectors);
HWGROUP(drive)->wrq.bio = NULL;
return ide_stopped;
}
if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
if (stat & (ERR_STAT | DRQ_STAT)) {
startstop = ide_error(drive, "bio_mulout_intr", stat);
memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
return startstop;
}
/* no data yet, so wait for another interrupt */
if (hwgroup->handler == NULL)
ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
do {
char *buffer;
int nsect = rq->current_nr_sectors;
unsigned long flags;
if (nsect > mcount)
nsect = mcount;
mcount -= nsect;
buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
rq->sector += nsect;
rq->nr_sectors -= nsect;
rq->current_nr_sectors -= nsect;
/* Do we move to the next bio after this? */
if (!rq->current_nr_sectors) {
/* remember to fix this up /jens */
struct bio *bio = rq->bio->bi_next;
/* end early early we ran out of requests */
if (!bio) {
mcount = 0;
} else {
rq->bio = bio;
rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
}
}
/*
* Ok, we're all setup for the interrupt
* re-entering us on the last transfer.
*/
taskfile_output_data(drive, buffer, nsect * SECTOR_WORDS);
bio_kunmap_irq(buffer, &flags);
} while (mcount);
drive->io_32bit = io_32bit;
rq->errors = 0;
if (hwgroup->handler == NULL)
ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
/* /*
* Handler for command with Read Multiple * Handler for command with Read Multiple
*/ */
...@@ -781,8 +711,8 @@ void ide_cmd_type_parser(ide_task_t *args) ...@@ -781,8 +711,8 @@ void ide_cmd_type_parser(ide_task_t *args)
case CFA_WRITE_MULTI_WO_ERASE: case CFA_WRITE_MULTI_WO_ERASE:
case WIN_MULTWRITE: case WIN_MULTWRITE:
case WIN_MULTWRITE_EXT: case WIN_MULTWRITE_EXT:
args->prehandler = pre_bio_out_intr; args->prehandler = pre_task_mulout_intr;
args->handler = bio_mulout_intr; args->handler = task_mulout_intr;
args->command_type = IDE_DRIVE_TASK_RAW_WRITE; args->command_type = IDE_DRIVE_TASK_RAW_WRITE;
return; return;
...@@ -989,7 +919,7 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *args, byte *buf) ...@@ -989,7 +919,7 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *args, byte *buf)
* *
* The caller has to make sure buf is never NULL! * The caller has to make sure buf is never NULL!
*/ */
static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *argbuf) static int ide_wait_cmd(ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *argbuf)
{ {
struct request rq; struct request rq;
...@@ -998,10 +928,10 @@ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int ...@@ -998,10 +928,10 @@ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int
memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * sectors); memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * sectors);
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
rq.buffer = argbuf; rq.buffer = argbuf;
*argbuf++ = cmd; argbuf[0] = cmd;
*argbuf++ = nsect; argbuf[1] = nsect;
*argbuf++ = feature; argbuf[2] = feature;
*argbuf++ = sectors; argbuf[3] = sectors;
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
...@@ -1009,7 +939,8 @@ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int ...@@ -1009,7 +939,8 @@ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int
int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{ {
int err = 0; int err = 0;
byte args[4], *argbuf = args; u8 args[4];
u8 *argbuf = args;
byte xfer_rate = 0; byte xfer_rate = 0;
int argsize = 4; int argsize = 4;
ide_task_t tfargs; ide_task_t tfargs;
......
...@@ -548,7 +548,8 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) ...@@ -548,7 +548,8 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) { if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) {
printk("%s: ATAPI reset complete\n", drive->name); printk("%s: ATAPI reset complete\n", drive->name);
} else { } else {
if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { if (time_before(jiffies, hwgroup->poll_timeout)) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
return ide_started; /* continue polling */ return ide_started; /* continue polling */
} }
...@@ -573,7 +574,8 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) ...@@ -573,7 +574,8 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
byte tmp; byte tmp;
if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) { if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { if (time_before(jiffies, hwgroup->poll_timeout)) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
return ide_started; /* continue polling */ return ide_started; /* continue polling */
} }
...@@ -645,6 +647,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) ...@@ -645,6 +647,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
udelay (20); udelay (20);
OUT_BYTE (WIN_SRST, IDE_COMMAND_REG); OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
__restore_flags (flags); /* local CPU only */ __restore_flags (flags); /* local CPU only */
return ide_started; return ide_started;
...@@ -679,7 +682,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) ...@@ -679,7 +682,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
} }
udelay(10); /* more than enough time */ udelay(10); /* more than enough time */
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
/* /*
* Some weird controller like resetting themselves to a strange * Some weird controller like resetting themselves to a strange
...@@ -931,6 +935,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat) ...@@ -931,6 +935,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
*/ */
void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
{ {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, handler, WAIT_CMD, NULL); ide_set_handler (drive, handler, WAIT_CMD, NULL);
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
...@@ -1553,7 +1558,7 @@ static void unexpected_intr(int irq, ide_hwgroup_t *hwgroup) ...@@ -1553,7 +1558,7 @@ static void unexpected_intr(int irq, ide_hwgroup_t *hwgroup)
/* /*
* entry point for all interrupts, caller does __cli() for us * entry point for all interrupts, caller does __cli() for us
*/ */
void ide_intr (int irq, void *dev_id, struct pt_regs *regs) void ide_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned long flags; unsigned long flags;
ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
...@@ -1596,7 +1601,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs) ...@@ -1596,7 +1601,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
* Whack the status register, just in case we have a leftover pending IRQ. * Whack the status register, just in case we have a leftover pending IRQ.
*/ */
IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
#endif /* CONFIG_BLK_DEV_IDEPCI */ #endif
} }
goto out_lock; goto out_lock;
} }
...@@ -3175,10 +3180,19 @@ int ide_unregister_subdriver(ide_drive_t *drive) ...@@ -3175,10 +3180,19 @@ int ide_unregister_subdriver(ide_drive_t *drive)
save_flags(flags); /* all CPUs */ save_flags(flags); /* all CPUs */
cli(); /* all CPUs */ cli(); /* all CPUs */
if (drive->usage || drive->busy || !ata_ops(drive) || ata_ops(drive)->busy) {
#if 0
if (__MOD_IN_USE(ata_ops(drive)->owner)) {
restore_flags(flags);
return 1;
}
#endif
if (drive->usage || drive->busy || !ata_ops(drive)) {
restore_flags(flags); /* all CPUs */ restore_flags(flags); /* all CPUs */
return 1; return 1;
} }
#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
...@@ -3189,7 +3203,10 @@ int ide_unregister_subdriver(ide_drive_t *drive) ...@@ -3189,7 +3203,10 @@ int ide_unregister_subdriver(ide_drive_t *drive)
#endif #endif
auto_remove_settings(drive); auto_remove_settings(drive);
drive->driver = NULL; drive->driver = NULL;
drive->present = 0;
restore_flags(flags); /* all CPUs */ restore_flags(flags); /* all CPUs */
return 0; return 0;
} }
...@@ -3298,6 +3315,7 @@ static int ide_notify_reboot (struct notifier_block *this, unsigned long event, ...@@ -3298,6 +3315,7 @@ static int ide_notify_reboot (struct notifier_block *this, unsigned long event,
hwif = &ide_hwifs[i]; hwif = &ide_hwifs[i];
if (!hwif->present) if (!hwif->present)
continue; continue;
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
drive = &hwif->drives[unit]; drive = &hwif->drives[unit];
if (!drive->present) if (!drive->present)
......
...@@ -394,6 +394,7 @@ static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive) ...@@ -394,6 +394,7 @@ static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
if (GET_STAT() & BUSY_STAT) { if (GET_STAT() & BUSY_STAT) {
if (time_before(jiffies, hwgroup->poll_timeout)) { if (time_before(jiffies, hwgroup->poll_timeout)) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
return ide_started; /* continue polling... */ return ide_started; /* continue polling... */
} }
...@@ -476,6 +477,7 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) ...@@ -476,6 +477,7 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
if (IN_BYTE(IDE_NSECTOR_REG) != 0) { if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
if (time_before(jiffies, hwgroup->poll_timeout)) { if (time_before(jiffies, hwgroup->poll_timeout)) {
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
return ide_started; /* continue polling... */ return ide_started; /* continue polling... */
} }
...@@ -489,6 +491,7 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) ...@@ -489,6 +491,7 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
*/ */
promise_multwrite(drive, 4); promise_multwrite(drive, 4);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
#ifdef DEBUG_WRITE #ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n", printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
...@@ -523,6 +526,7 @@ static ide_startstop_t promise_write (ide_drive_t *drive) ...@@ -523,6 +526,7 @@ static ide_startstop_t promise_write (ide_drive_t *drive)
if (promise_multwrite(drive, rq->nr_sectors - 4)) if (promise_multwrite(drive, rq->nr_sectors - 4))
return ide_stopped; return ide_stopped;
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
return ide_started; return ide_started;
} else { } else {
...@@ -533,6 +537,7 @@ static ide_startstop_t promise_write (ide_drive_t *drive) ...@@ -533,6 +537,7 @@ static ide_startstop_t promise_write (ide_drive_t *drive)
if (promise_multwrite(drive, rq->nr_sectors)) if (promise_multwrite(drive, rq->nr_sectors))
return ide_stopped; return ide_stopped;
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
#ifdef DEBUG_WRITE #ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, " printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
...@@ -554,6 +559,13 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) ...@@ -554,6 +559,13 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
unsigned long timeout; unsigned long timeout;
byte stat; byte stat;
/* Check that it's a regular command. If not, bomb out early. */
if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "pdc4030 bad flags");
ide_end_request(drive, 0);
return ide_stopped;
}
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(drive->channel, drive, 0); SELECT_MASK(drive->channel, drive, 0);
...@@ -568,20 +580,12 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) ...@@ -568,20 +580,12 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
OUT_BYTE(taskfile->device_head, IDE_SELECT_REG); OUT_BYTE(taskfile->device_head, IDE_SELECT_REG);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG); OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
/* Check that it's a regular command. If not, bomb out early. */
if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "pdc4030 bad flags");
ide_end_request(drive, 0);
return ide_stopped;
}
switch (rq_data_dir(rq)) { switch (rq_data_dir(rq)) {
case READ: case READ:
OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
/* /*
* The card's behaviour is odd at this point. If the data is * The card's behaviour is odd at this point. If the data is
* available, DRQ will be true, and no interrupt will be * available, DRQ will be true, and no interrupt will be
* generated by the card. If this is the case, we need to call the * generated by the card. If this is the case, we need to call the
* "interrupt" handler (promise_read_intr) directly. Otherwise, if * "interrupt" handler (promise_read_intr) directly. Otherwise, if
* an interrupt is going to occur, bit0 of the SELECT register will * an interrupt is going to occur, bit0 of the SELECT register will
* be high, so we can set the handler the just return and be interrupted. * be high, so we can set the handler the just return and be interrupted.
...@@ -600,6 +604,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) ...@@ -600,6 +604,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
printk(KERN_DEBUG "%s: read: waiting for " printk(KERN_DEBUG "%s: read: waiting for "
"interrupt\n", drive->name); "interrupt\n", drive->name);
#endif #endif
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL); ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
...@@ -612,7 +617,6 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) ...@@ -612,7 +617,6 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
case WRITE: { case WRITE: {
ide_startstop_t startstop; ide_startstop_t startstop;
OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
/* /*
* Strategy on write is: * Strategy on write is:
* look for the DRQ that should have been immediately asserted * look for the DRQ that should have been immediately asserted
...@@ -624,7 +628,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) ...@@ -624,7 +628,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
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;
} }
if (!drive->unmask) if (!drive->unmask)
__cli(); /* local CPU only */ __cli(); /* local CPU only */
HWGROUP(drive)->wrq = *rq; /* scratchpad */ HWGROUP(drive)->wrq = *rq; /* scratchpad */
......
...@@ -194,6 +194,7 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -194,6 +194,7 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */ outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0; return 0;
......
...@@ -508,7 +508,7 @@ static void idescsi_add_settings(ide_drive_t *drive) ...@@ -508,7 +508,7 @@ static void idescsi_add_settings(ide_drive_t *drive)
*/ */
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id) static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
{ {
ata_ops(drive)->busy++; MOD_INC_USE_COUNT;
idescsi_drives[id] = drive; idescsi_drives[id] = drive;
drive->driver_data = scsi; drive->driver_data = scsi;
...@@ -629,8 +629,9 @@ int idescsi_release (struct Scsi_Host *host) ...@@ -629,8 +629,9 @@ int idescsi_release (struct Scsi_Host *host)
for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) { for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
drive = idescsi_drives[id]; drive = idescsi_drives[id];
if (drive) if (drive) {
ata_ops(drive)->busy--; MOD_DEC_USE_COUNT;
}
} }
return 0; return 0;
} }
......
...@@ -300,10 +300,13 @@ typedef struct ide_drive_s { ...@@ -300,10 +300,13 @@ typedef struct ide_drive_s {
byte slow; /* flag: slow data port */ byte slow; /* flag: slow data port */
byte bswap; /* flag: byte swap data */ byte bswap; /* flag: byte swap data */
byte dsc_overlap; /* flag: DSC overlap */ byte dsc_overlap; /* flag: DSC overlap */
unsigned waiting_for_dma: 1; /* dma currently in progress */ unsigned waiting_for_dma: 1; /* dma currently in progress */
unsigned busy : 1; /* currently doing revalidate_disk() */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
unsigned present : 1; /* drive is physically present */ unsigned present : 1; /* drive is physically present */
unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned noprobe : 1; /* from: hdx=noprobe */
unsigned busy : 1; /* currently doing revalidate_disk() */
unsigned removable : 1; /* 1 if need to do check_media_change */ unsigned removable : 1; /* 1 if need to do check_media_change */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
unsigned no_unmask : 1; /* disallow setting unmask bit */ unsigned no_unmask : 1; /* disallow setting unmask bit */
...@@ -315,7 +318,6 @@ typedef struct ide_drive_s { ...@@ -315,7 +318,6 @@ typedef struct ide_drive_s {
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */
unsigned ata_flash : 1; /* 1=present, 0=default */ unsigned ata_flash : 1; /* 1=present, 0=default */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
unsigned addressing; /* : 2; 0=28-bit, 1=48-bit, 2=64-bit */ unsigned addressing; /* : 2; 0=28-bit, 1=48-bit, 2=64-bit */
byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
select_t select; /* basic drive/head select reg value */ select_t select; /* basic drive/head select reg value */
...@@ -620,7 +622,6 @@ read_proc_t proc_ide_read_geometry; ...@@ -620,7 +622,6 @@ read_proc_t proc_ide_read_geometry;
struct ata_operations { struct ata_operations {
struct module *owner; struct module *owner;
unsigned busy: 1; /* FIXME: this will go soon away... */
int (*cleanup)(ide_drive_t *); int (*cleanup)(ide_drive_t *);
int (*standby)(ide_drive_t *); int (*standby)(ide_drive_t *);
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long); ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long);
...@@ -635,6 +636,7 @@ struct ata_operations { ...@@ -635,6 +636,7 @@ struct ata_operations {
void (*pre_reset)(ide_drive_t *); void (*pre_reset)(ide_drive_t *);
unsigned long (*capacity)(ide_drive_t *); unsigned long (*capacity)(ide_drive_t *);
ide_startstop_t (*special)(ide_drive_t *); ide_startstop_t (*special)(ide_drive_t *);
ide_proc_entry_t *proc; ide_proc_entry_t *proc;
}; };
......
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