aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-atapi.c41
-rw-r--r--drivers/ide/ide-floppy.c72
-rw-r--r--drivers/ide/ide-floppy.h3
-rw-r--r--drivers/ide/ide-tape.c6
4 files changed, 44 insertions, 78 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index b558663418d8..2521677e1f48 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -468,12 +468,22 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
468 return ireason; 468 return ireason;
469} 469}
470 470
471ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout, 471static int ide_delayed_transfer_pc(ide_drive_t *drive)
472 ide_expiry_t *expiry) 472{
473 /* Send the actual packet */
474 drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);
475
476 /* Timeout for the packet command */
477 return WAIT_FLOPPY_CMD;
478}
479
480static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
473{ 481{
474 struct ide_atapi_pc *pc = drive->pc; 482 struct ide_atapi_pc *pc = drive->pc;
475 ide_hwif_t *hwif = drive->hwif; 483 ide_hwif_t *hwif = drive->hwif;
476 struct request *rq = hwif->hwgroup->rq; 484 struct request *rq = hwif->hwgroup->rq;
485 ide_expiry_t *expiry;
486 unsigned int timeout;
477 ide_startstop_t startstop; 487 ide_startstop_t startstop;
478 u8 ireason; 488 u8 ireason;
479 489
@@ -493,6 +503,25 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout,
493 return ide_do_reset(drive); 503 return ide_do_reset(drive);
494 } 504 }
495 505
506 /*
507 * If necessary schedule the packet transfer to occur 'timeout'
508 * miliseconds later in ide_delayed_transfer_pc() after the device
509 * says it's ready for a packet.
510 */
511 if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
512 timeout = drive->pc_delay;
513 expiry = &ide_delayed_transfer_pc;
514 } else {
515 if (drive->scsi) {
516 timeout = ide_scsi_get_timeout(pc);
517 expiry = ide_scsi_expiry;
518 } else {
519 timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
520 : WAIT_TAPE_CMD;
521 expiry = NULL;
522 }
523 }
524
496 /* Set the interrupt routine */ 525 /* Set the interrupt routine */
497 ide_set_handler(drive, ide_pc_intr, timeout, expiry); 526 ide_set_handler(drive, ide_pc_intr, timeout, expiry);
498 527
@@ -508,10 +537,8 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout,
508 537
509 return ide_started; 538 return ide_started;
510} 539}
511EXPORT_SYMBOL_GPL(ide_transfer_pc);
512 540
513ide_startstop_t ide_issue_pc(ide_drive_t *drive, 541ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
514 ide_handler_t *handler, unsigned int timeout,
515 ide_expiry_t *expiry) 542 ide_expiry_t *expiry)
516{ 543{
517 struct ide_atapi_pc *pc = drive->pc; 544 struct ide_atapi_pc *pc = drive->pc;
@@ -550,12 +577,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive,
550 577
551 /* Issue the packet command */ 578 /* Issue the packet command */
552 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { 579 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
553 ide_execute_command(drive, ATA_CMD_PACKET, handler, 580 ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
554 timeout, NULL); 581 timeout, NULL);
555 return ide_started; 582 return ide_started;
556 } else { 583 } else {
557 ide_execute_pkt_cmd(drive); 584 ide_execute_pkt_cmd(drive);
558 return (*handler)(drive); 585 return ide_transfer_pc(drive);
559 } 586 }
560} 587}
561EXPORT_SYMBOL_GPL(ide_issue_pc); 588EXPORT_SYMBOL_GPL(ide_issue_pc);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 7be3cd5daa9d..2a34f1ad2284 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -73,7 +73,11 @@
73#define CAPACITY_CURRENT 0x02 73#define CAPACITY_CURRENT 0x02
74#define CAPACITY_NO_CARTRIDGE 0x03 74#define CAPACITY_NO_CARTRIDGE 0x03
75 75
76#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ 76/*
77 * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit
78 * was apparently being deasserted before the unit was ready to receive data.
79 */
80#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
77 81
78/* Error code returned in rq->errors to the higher part of the driver. */ 82/* Error code returned in rq->errors to the higher part of the driver. */
79#define IDEFLOPPY_ERROR_GENERAL 101 83#define IDEFLOPPY_ERROR_GENERAL 101
@@ -193,51 +197,6 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
193 idefloppy_end_request(drive, uptodate, 0); 197 idefloppy_end_request(drive, uptodate, 0);
194} 198}
195 199
196/*
197 * What we have here is a classic case of a top half / bottom half interrupt
198 * service routine. In interrupt mode, the device sends an interrupt to signal
199 * that it is ready to receive a packet. However, we need to delay about 2-3
200 * ticks before issuing the packet or we gets in trouble.
201 */
202static int idefloppy_transfer_pc(ide_drive_t *drive)
203{
204 /* Send the actual packet */
205 drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);
206
207 /* Timeout for the packet command */
208 return WAIT_FLOPPY_CMD;
209}
210
211/*
212 * Called as an interrupt (or directly). When the device says it's ready for a
213 * packet, we schedule the packet transfer to occur about 2-3 ticks later in
214 * transfer_pc.
215 */
216static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive)
217{
218 idefloppy_floppy_t *floppy = drive->driver_data;
219 ide_expiry_t *expiry;
220 unsigned int timeout;
221
222 /*
223 * The following delay solves a problem with ATAPI Zip 100 drives
224 * where the Busy flag was apparently being deasserted before the
225 * unit was ready to receive data. This was happening on a
226 * 1200 MHz Athlon system. 10/26/01 25msec is too short,
227 * 40 and 50msec work well. ide_pc_intr will not be actually
228 * used until after the packet is moved in about 50 msec.
229 */
230 if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
231 timeout = floppy->ticks;
232 expiry = &idefloppy_transfer_pc;
233 } else {
234 timeout = WAIT_FLOPPY_CMD;
235 expiry = NULL;
236 }
237
238 return ide_transfer_pc(drive, timeout, expiry);
239}
240
241static void ide_floppy_report_error(idefloppy_floppy_t *floppy, 200static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
242 struct ide_atapi_pc *pc) 201 struct ide_atapi_pc *pc)
243{ 202{
@@ -281,8 +240,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
281 240
282 pc->retries++; 241 pc->retries++;
283 242
284 return ide_issue_pc(drive, idefloppy_start_pc_transfer, 243 return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);
285 WAIT_FLOPPY_CMD, NULL);
286} 244}
287 245
288void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) 246void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -597,21 +555,7 @@ static sector_t idefloppy_capacity(ide_drive_t *drive)
597ide_devset_rw_field(bios_cyl, bios_cyl); 555ide_devset_rw_field(bios_cyl, bios_cyl);
598ide_devset_rw_field(bios_head, bios_head); 556ide_devset_rw_field(bios_head, bios_head);
599ide_devset_rw_field(bios_sect, bios_sect); 557ide_devset_rw_field(bios_sect, bios_sect);
600 558ide_devset_rw_field(ticks, pc_delay);
601static int get_ticks(ide_drive_t *drive)
602{
603 idefloppy_floppy_t *floppy = drive->driver_data;
604 return floppy->ticks;
605}
606
607static int set_ticks(ide_drive_t *drive, int arg)
608{
609 idefloppy_floppy_t *floppy = drive->driver_data;
610 floppy->ticks = arg;
611 return 0;
612}
613
614IDE_DEVSET(ticks, DS_SYNC, get_ticks, set_ticks);
615 559
616static const struct ide_proc_devset idefloppy_settings[] = { 560static const struct ide_proc_devset idefloppy_settings[] = {
617 IDE_PROC_DEVSET(bios_cyl, 0, 1023), 561 IDE_PROC_DEVSET(bios_cyl, 0, 1023),
@@ -647,7 +591,7 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
647 if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { 591 if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) {
648 drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; 592 drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE;
649 /* This value will be visible in the /proc/ide/hdx/settings */ 593 /* This value will be visible in the /proc/ide/hdx/settings */
650 floppy->ticks = IDEFLOPPY_TICKS_DELAY; 594 drive->pc_delay = IDEFLOPPY_PC_DELAY;
651 blk_queue_max_sectors(drive->queue, 64); 595 blk_queue_max_sectors(drive->queue, 64);
652 } 596 }
653 597
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h
index ced5ceb474de..00ad5f992dc0 100644
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -20,8 +20,7 @@ typedef struct ide_floppy_obj {
20 20
21 /* Last error information */ 21 /* Last error information */
22 u8 sense_key, asc, ascq; 22 u8 sense_key, asc, ascq;
23 /* delay this long before sending packet command */ 23
24 u8 ticks;
25 int progress_indication; 24 int progress_indication;
26 25
27 /* Device information */ 26 /* Device information */
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index a148de623af0..622d5fed2dc5 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -654,10 +654,6 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
654 * again, the callback function will be called and then we will handle the next 654 * again, the callback function will be called and then we will handle the next
655 * request. 655 * request.
656 */ 656 */
657static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
658{
659 return ide_transfer_pc(drive, WAIT_TAPE_CMD, NULL);
660}
661 657
662static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, 658static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
663 struct ide_atapi_pc *pc) 659 struct ide_atapi_pc *pc)
@@ -705,7 +701,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
705 701
706 pc->retries++; 702 pc->retries++;
707 703
708 return ide_issue_pc(drive, idetape_transfer_pc, WAIT_TAPE_CMD, NULL); 704 return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL);
709} 705}
710 706
711/* A mode sense command is used to "sense" tape parameters. */ 707/* A mode sense command is used to "sense" tape parameters. */