diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-15 15:21:58 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-15 15:21:58 -0400 |
commit | 594c16d8dd54cd7b1c5ef1ec3ac0f6bf34301dad (patch) | |
tree | 4891a8ab4e998ba00db51e4672da64fd83663002 | |
parent | f83cbc77b0d5521b4f0f591ede4870316944481a (diff) |
ide: add ide_transfer_pc() helper
* Add ide-atapi.c file for generic ATAPI support together with
CONFIG_IDE_ATAPI config option.
* Add generic ide_transfer_pc() helper to ide-atapi.c and then
convert ide-{floppy,tape,scsi} device drivers to use it.
There should be no functional changes caused by this patch.
Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/Kconfig | 6 | ||||
-rw-r--r-- | drivers/ide/Makefile | 1 | ||||
-rw-r--r-- | drivers/ide/ide-atapi.c | 70 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 28 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 56 | ||||
-rw-r--r-- | drivers/scsi/ide-scsi.c | 30 | ||||
-rw-r--r-- | include/linux/ide.h | 3 |
7 files changed, 85 insertions, 109 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1607536ff5fb..cf707c8f08d4 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -98,6 +98,9 @@ if BLK_DEV_IDE | |||
98 | 98 | ||
99 | comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" | 99 | comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" |
100 | 100 | ||
101 | config IDE_ATAPI | ||
102 | bool | ||
103 | |||
101 | config BLK_DEV_IDE_SATA | 104 | config BLK_DEV_IDE_SATA |
102 | bool "Support for SATA (deprecated; conflicts with libata SATA driver)" | 105 | bool "Support for SATA (deprecated; conflicts with libata SATA driver)" |
103 | default n | 106 | default n |
@@ -201,6 +204,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS | |||
201 | 204 | ||
202 | config BLK_DEV_IDETAPE | 205 | config BLK_DEV_IDETAPE |
203 | tristate "Include IDE/ATAPI TAPE support" | 206 | tristate "Include IDE/ATAPI TAPE support" |
207 | select IDE_ATAPI | ||
204 | help | 208 | help |
205 | If you have an IDE tape drive using the ATAPI protocol, say Y. | 209 | If you have an IDE tape drive using the ATAPI protocol, say Y. |
206 | ATAPI is a newer protocol used by IDE tape and CD-ROM drives, | 210 | ATAPI is a newer protocol used by IDE tape and CD-ROM drives, |
@@ -223,6 +227,7 @@ config BLK_DEV_IDETAPE | |||
223 | 227 | ||
224 | config BLK_DEV_IDEFLOPPY | 228 | config BLK_DEV_IDEFLOPPY |
225 | tristate "Include IDE/ATAPI FLOPPY support" | 229 | tristate "Include IDE/ATAPI FLOPPY support" |
230 | select IDE_ATAPI | ||
226 | ---help--- | 231 | ---help--- |
227 | If you have an IDE floppy drive which uses the ATAPI protocol, | 232 | If you have an IDE floppy drive which uses the ATAPI protocol, |
228 | answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy | 233 | answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy |
@@ -246,6 +251,7 @@ config BLK_DEV_IDEFLOPPY | |||
246 | config BLK_DEV_IDESCSI | 251 | config BLK_DEV_IDESCSI |
247 | tristate "SCSI emulation support" | 252 | tristate "SCSI emulation support" |
248 | depends on SCSI | 253 | depends on SCSI |
254 | select IDE_ATAPI | ||
249 | ---help--- | 255 | ---help--- |
250 | WARNING: ide-scsi is no longer needed for cd writing applications! | 256 | WARNING: ide-scsi is no longer needed for cd writing applications! |
251 | The 2.6 kernel supports direct writing to ide-cd, which eliminates | 257 | The 2.6 kernel supports direct writing to ide-cd, which eliminates |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index f94b679b611e..a2b3f84d710d 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -14,6 +14,7 @@ EXTRA_CFLAGS += -Idrivers/ide | |||
14 | ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o | 14 | ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o |
15 | 15 | ||
16 | # core IDE code | 16 | # core IDE code |
17 | ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o | ||
17 | ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o | 18 | ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o |
18 | ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o | 19 | ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o |
19 | ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o | 20 | ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c new file mode 100644 index 000000000000..25939bc60402 --- /dev/null +++ b/drivers/ide/ide-atapi.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * ATAPI support. | ||
3 | */ | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/delay.h> | ||
7 | #include <linux/ide.h> | ||
8 | |||
9 | static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) | ||
10 | { | ||
11 | ide_hwif_t *hwif = drive->hwif; | ||
12 | int retries = 100; | ||
13 | |||
14 | while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { | ||
15 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | ||
16 | "a packet command, retrying\n", drive->name); | ||
17 | udelay(100); | ||
18 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
19 | if (retries == 0) { | ||
20 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | ||
21 | "a packet command, ignoring\n", | ||
22 | drive->name); | ||
23 | ireason |= CD; | ||
24 | ireason &= ~IO; | ||
25 | } | ||
26 | } | ||
27 | |||
28 | return ireason; | ||
29 | } | ||
30 | |||
31 | ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
32 | ide_handler_t *handler, unsigned int timeout, | ||
33 | ide_expiry_t *expiry) | ||
34 | { | ||
35 | ide_hwif_t *hwif = drive->hwif; | ||
36 | ide_startstop_t startstop; | ||
37 | u8 ireason; | ||
38 | |||
39 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | ||
40 | printk(KERN_ERR "%s: Strange, packet command initiated yet " | ||
41 | "DRQ isn't asserted\n", drive->name); | ||
42 | return startstop; | ||
43 | } | ||
44 | |||
45 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
46 | if (drive->media == ide_tape && !drive->scsi) | ||
47 | ireason = ide_wait_ireason(drive, ireason); | ||
48 | |||
49 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
50 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | ||
51 | "a packet command\n", drive->name); | ||
52 | return ide_do_reset(drive); | ||
53 | } | ||
54 | |||
55 | /* Set the interrupt routine */ | ||
56 | ide_set_handler(drive, handler, timeout, expiry); | ||
57 | |||
58 | /* Begin DMA, if necessary */ | ||
59 | if (pc->flags & PC_FLAG_DMA_OK) { | ||
60 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
61 | hwif->dma_ops->dma_start(drive); | ||
62 | } | ||
63 | |||
64 | /* Send the actual packet */ | ||
65 | if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0) | ||
66 | hwif->output_data(drive, NULL, pc->c, 12); | ||
67 | |||
68 | return ide_started; | ||
69 | } | ||
70 | EXPORT_SYMBOL_GPL(ide_transfer_pc); | ||
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index a7c138dc324c..e7a1025c03c4 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -532,25 +532,11 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) | |||
532 | 532 | ||
533 | static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) | 533 | static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) |
534 | { | 534 | { |
535 | ide_hwif_t *hwif = drive->hwif; | ||
536 | idefloppy_floppy_t *floppy = drive->driver_data; | 535 | idefloppy_floppy_t *floppy = drive->driver_data; |
537 | struct ide_atapi_pc *pc = floppy->pc; | 536 | struct ide_atapi_pc *pc = floppy->pc; |
538 | ide_expiry_t *expiry; | 537 | ide_expiry_t *expiry; |
539 | unsigned int timeout; | 538 | unsigned int timeout; |
540 | ide_startstop_t startstop; | ||
541 | u8 ireason; | ||
542 | 539 | ||
543 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | ||
544 | printk(KERN_ERR "%s: Strange, packet command initiated yet " | ||
545 | "DRQ isn't asserted\n", drive->name); | ||
546 | return startstop; | ||
547 | } | ||
548 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
549 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
550 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | ||
551 | "a packet command\n", drive->name); | ||
552 | return ide_do_reset(drive); | ||
553 | } | ||
554 | /* | 540 | /* |
555 | * The following delay solves a problem with ATAPI Zip 100 drives | 541 | * The following delay solves a problem with ATAPI Zip 100 drives |
556 | * where the Busy flag was apparently being deasserted before the | 542 | * where the Busy flag was apparently being deasserted before the |
@@ -567,19 +553,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) | |||
567 | expiry = NULL; | 553 | expiry = NULL; |
568 | } | 554 | } |
569 | 555 | ||
570 | ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry); | 556 | return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); |
571 | |||
572 | /* Begin DMA, if necessary */ | ||
573 | if (pc->flags & PC_FLAG_DMA_OK) { | ||
574 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
575 | hwif->dma_ops->dma_start(drive); | ||
576 | } | ||
577 | |||
578 | if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0) | ||
579 | /* Send the actual packet */ | ||
580 | hwif->output_data(drive, NULL, floppy->pc->c, 12); | ||
581 | |||
582 | return ide_started; | ||
583 | } | 557 | } |
584 | 558 | ||
585 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | 559 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2a362138f973..5adc2c9ae418 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -947,64 +947,12 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) | |||
947 | * again, the callback function will be called and then we will handle the next | 947 | * again, the callback function will be called and then we will handle the next |
948 | * request. | 948 | * request. |
949 | */ | 949 | */ |
950 | |||
951 | static u8 ide_tape_wait_ireason(ide_drive_t *drive, u8 ireason) | ||
952 | { | ||
953 | ide_hwif_t *hwif = drive->hwif; | ||
954 | int retries = 100; | ||
955 | |||
956 | while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { | ||
957 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | ||
958 | "a packet command, retrying\n", drive->name); | ||
959 | udelay(100); | ||
960 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
961 | if (retries == 0) { | ||
962 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | ||
963 | "a packet command, ignoring\n", | ||
964 | drive->name); | ||
965 | ireason |= CD; | ||
966 | ireason &= ~IO; | ||
967 | } | ||
968 | } | ||
969 | |||
970 | return ireason; | ||
971 | } | ||
972 | |||
973 | static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) | 950 | static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) |
974 | { | 951 | { |
975 | ide_hwif_t *hwif = drive->hwif; | ||
976 | idetape_tape_t *tape = drive->driver_data; | 952 | idetape_tape_t *tape = drive->driver_data; |
977 | struct ide_atapi_pc *pc = tape->pc; | ||
978 | ide_startstop_t startstop; | ||
979 | u8 ireason; | ||
980 | |||
981 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | ||
982 | printk(KERN_ERR "%s: Strange, packet command initiated yet " | ||
983 | "DRQ isn't asserted\n", drive->name); | ||
984 | return startstop; | ||
985 | } | ||
986 | |||
987 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
988 | ireason = ide_tape_wait_ireason(drive, ireason); | ||
989 | 953 | ||
990 | if ((ireason & CD) == 0 || (ireason & IO)) { | 954 | return ide_transfer_pc(drive, tape->pc, idetape_pc_intr, |
991 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | 955 | IDETAPE_WAIT_CMD, NULL); |
992 | "a packet command\n", drive->name); | ||
993 | return ide_do_reset(drive); | ||
994 | } | ||
995 | /* Set the interrupt routine */ | ||
996 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | ||
997 | |||
998 | /* Begin DMA, if necessary */ | ||
999 | if (pc->flags & PC_FLAG_DMA_OK) { | ||
1000 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
1001 | hwif->dma_ops->dma_start(drive); | ||
1002 | } | ||
1003 | |||
1004 | /* Send the actual packet */ | ||
1005 | hwif->output_data(drive, NULL, pc->c, 12); | ||
1006 | |||
1007 | return ide_started; | ||
1008 | } | 956 | } |
1009 | 957 | ||
1010 | static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, | 958 | static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index c9fdf60c9dcf..d41348f2245e 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -453,36 +453,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | |||
453 | 453 | ||
454 | static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) | 454 | static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) |
455 | { | 455 | { |
456 | ide_hwif_t *hwif = drive->hwif; | ||
457 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 456 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
458 | struct ide_atapi_pc *pc = scsi->pc; | ||
459 | ide_startstop_t startstop; | ||
460 | u8 ireason; | ||
461 | |||
462 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | ||
463 | printk(KERN_ERR "%s: Strange, packet command initiated yet " | ||
464 | "DRQ isn't asserted\n", drive->name); | ||
465 | return startstop; | ||
466 | } | ||
467 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
468 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
469 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | ||
470 | "a packet command\n", drive->name); | ||
471 | return ide_do_reset (drive); | ||
472 | } | ||
473 | 457 | ||
474 | /* Set the interrupt routine */ | 458 | return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr, |
475 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); | 459 | get_timeout(scsi->pc), idescsi_expiry); |
476 | |||
477 | if (pc->flags & PC_FLAG_DMA_OK) { | ||
478 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
479 | hwif->dma_ops->dma_start(drive); | ||
480 | } | ||
481 | |||
482 | /* Send the actual packet */ | ||
483 | hwif->output_data(drive, NULL, scsi->pc->c, 12); | ||
484 | |||
485 | return ide_started; | ||
486 | } | 460 | } |
487 | 461 | ||
488 | static inline int idescsi_set_direction(struct ide_atapi_pc *pc) | 462 | static inline int idescsi_set_direction(struct ide_atapi_pc *pc) |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 89feaea9e20b..bed3c58798ae 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -967,6 +967,9 @@ extern int drive_is_ready(ide_drive_t *); | |||
967 | 967 | ||
968 | void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); | 968 | void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); |
969 | 969 | ||
970 | ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, | ||
971 | ide_handler_t *, unsigned int, ide_expiry_t *); | ||
972 | |||
970 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); | 973 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); |
971 | 974 | ||
972 | void task_end_request(ide_drive_t *, struct request *, u8); | 975 | void task_end_request(ide_drive_t *, struct request *, u8); |