diff options
| -rw-r--r-- | Documentation/feature-removal-schedule.txt | 9 | ||||
| -rw-r--r-- | MAINTAINERS | 5 | ||||
| -rw-r--r-- | drivers/ide/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/ide/Makefile | 2 | ||||
| -rw-r--r-- | drivers/ide/ide-atapi.c | 248 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.c | 99 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.h | 12 | ||||
| -rw-r--r-- | drivers/ide/ide-floppy.c | 28 | ||||
| -rw-r--r-- | drivers/ide/ide-floppy_ioctl.c | 58 | ||||
| -rw-r--r-- | drivers/ide/ide-io.c | 282 | ||||
| -rw-r--r-- | drivers/ide/ide-ioctls.c | 3 | ||||
| -rw-r--r-- | drivers/ide/ide-park.c | 13 | ||||
| -rw-r--r-- | drivers/ide/ide-probe.c | 223 | ||||
| -rw-r--r-- | drivers/ide/ide-sysfs.c | 125 | ||||
| -rw-r--r-- | drivers/ide/ide-tape.c | 2 | ||||
| -rw-r--r-- | drivers/ide/ide.c | 72 | ||||
| -rw-r--r-- | drivers/ide/tx4938ide.c | 11 | ||||
| -rw-r--r-- | drivers/ide/tx4939ide.c | 43 | ||||
| -rw-r--r-- | drivers/scsi/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/scsi/Makefile | 1 | ||||
| -rw-r--r-- | drivers/scsi/ide-scsi.c | 840 | ||||
| -rw-r--r-- | include/linux/ide.h | 121 |
22 files changed, 614 insertions, 1609 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index dc7c681e532c..df18d87c4837 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -310,15 +310,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl> | |||
| 310 | 310 | ||
| 311 | --------------------------- | 311 | --------------------------- |
| 312 | 312 | ||
| 313 | What: ide-scsi (BLK_DEV_IDESCSI) | ||
| 314 | When: 2.6.29 | ||
| 315 | Why: The 2.6 kernel supports direct writing to ide CD drives, which | ||
| 316 | eliminates the need for ide-scsi. The new method is more | ||
| 317 | efficient in every way. | ||
| 318 | Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | ||
| 319 | |||
| 320 | --------------------------- | ||
| 321 | |||
| 322 | What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() | 313 | What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() |
| 323 | When: 2.6.29 (ideally) or 2.6.30 (more likely) | 314 | When: 2.6.29 (ideally) or 2.6.30 (more likely) |
| 324 | Why: Deprecated by the new (standard) device driver binding model. Use | 315 | Why: Deprecated by the new (standard) device driver binding model. Use |
diff --git a/MAINTAINERS b/MAINTAINERS index 3148de29afa7..88f43e09aeb3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2152,11 +2152,6 @@ M: Gadi Oxman <gadio@netvision.net.il> | |||
| 2152 | L: linux-kernel@vger.kernel.org | 2152 | L: linux-kernel@vger.kernel.org |
| 2153 | S: Maintained | 2153 | S: Maintained |
| 2154 | 2154 | ||
| 2155 | IDE-SCSI DRIVER | ||
| 2156 | L: linux-ide@vger.kernel.org | ||
| 2157 | L: linux-scsi@vger.kernel.org | ||
| 2158 | S: Orphan | ||
| 2159 | |||
| 2160 | IDLE-I7300 | 2155 | IDLE-I7300 |
| 2161 | P: Andy Henroid | 2156 | P: Andy Henroid |
| 2162 | M: andrew.d.henroid@intel.com | 2157 | M: andrew.d.henroid@intel.com |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index c9f21e3d4ead..4ee85fcf9aaf 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
| @@ -137,6 +137,7 @@ config BLK_DEV_DELKIN | |||
| 137 | 137 | ||
| 138 | config BLK_DEV_IDECD | 138 | config BLK_DEV_IDECD |
| 139 | tristate "Include IDE/ATAPI CDROM support" | 139 | tristate "Include IDE/ATAPI CDROM support" |
| 140 | select IDE_ATAPI | ||
| 140 | ---help--- | 141 | ---help--- |
| 141 | If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is | 142 | If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is |
| 142 | a newer protocol used by IDE CD-ROM and TAPE drives, similar to the | 143 | a newer protocol used by IDE CD-ROM and TAPE drives, similar to the |
| @@ -185,23 +186,6 @@ config BLK_DEV_IDETAPE | |||
| 185 | To compile this driver as a module, choose M here: the | 186 | To compile this driver as a module, choose M here: the |
| 186 | module will be called ide-tape. | 187 | module will be called ide-tape. |
| 187 | 188 | ||
| 188 | config BLK_DEV_IDESCSI | ||
| 189 | tristate "SCSI emulation support (DEPRECATED)" | ||
| 190 | depends on SCSI | ||
| 191 | select IDE_ATAPI | ||
| 192 | ---help--- | ||
| 193 | WARNING: ide-scsi is no longer needed for cd writing applications! | ||
| 194 | The 2.6 kernel supports direct writing to ide-cd, which eliminates | ||
| 195 | the need for ide-scsi + the entire scsi stack just for writing a | ||
| 196 | cd. The new method is more efficient in every way. | ||
| 197 | |||
| 198 | This will provide SCSI host adapter emulation for IDE ATAPI devices, | ||
| 199 | and will allow you to use a SCSI device driver instead of a native | ||
| 200 | ATAPI driver. | ||
| 201 | |||
| 202 | If both this SCSI emulation and native ATAPI support are compiled | ||
| 203 | into the kernel, the native support will be used. | ||
| 204 | |||
| 205 | config BLK_DEV_IDEACPI | 189 | config BLK_DEV_IDEACPI |
| 206 | bool "IDE ACPI support" | 190 | bool "IDE ACPI support" |
| 207 | depends on ACPI | 191 | depends on ACPI |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 177e3f8523ed..410728992e6a 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | EXTRA_CFLAGS += -Idrivers/ide | 5 | EXTRA_CFLAGS += -Idrivers/ide |
| 6 | 6 | ||
| 7 | ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ | 7 | ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ |
| 8 | ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o | 8 | ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o |
| 9 | 9 | ||
| 10 | # core IDE code | 10 | # core IDE code |
| 11 | ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o | 11 | ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 4e58b9e7a58a..e8688c0f8645 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
| 6 | #include <linux/cdrom.h> | ||
| 6 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
| 7 | #include <linux/ide.h> | 8 | #include <linux/ide.h> |
| 8 | #include <scsi/scsi.h> | 9 | #include <scsi/scsi.h> |
| @@ -14,6 +15,13 @@ | |||
| 14 | #define debug_log(fmt, args...) do {} while (0) | 15 | #define debug_log(fmt, args...) do {} while (0) |
| 15 | #endif | 16 | #endif |
| 16 | 17 | ||
| 18 | #define ATAPI_MIN_CDB_BYTES 12 | ||
| 19 | |||
| 20 | static inline int dev_is_idecd(ide_drive_t *drive) | ||
| 21 | { | ||
| 22 | return drive->media == ide_cdrom || drive->media == ide_optical; | ||
| 23 | } | ||
| 24 | |||
| 17 | /* | 25 | /* |
| 18 | * Check whether we can support a device, | 26 | * Check whether we can support a device, |
| 19 | * based on the ATAPI IDENTIFY command results. | 27 | * based on the ATAPI IDENTIFY command results. |
| @@ -233,18 +241,49 @@ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) | |||
| 233 | } | 241 | } |
| 234 | EXPORT_SYMBOL_GPL(ide_retry_pc); | 242 | EXPORT_SYMBOL_GPL(ide_retry_pc); |
| 235 | 243 | ||
| 236 | int ide_scsi_expiry(ide_drive_t *drive) | 244 | int ide_cd_expiry(ide_drive_t *drive) |
| 237 | { | 245 | { |
| 238 | struct ide_atapi_pc *pc = drive->pc; | 246 | struct request *rq = HWGROUP(drive)->rq; |
| 247 | unsigned long wait = 0; | ||
| 239 | 248 | ||
| 240 | debug_log("%s called for %lu at %lu\n", __func__, | 249 | debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); |
| 241 | pc->scsi_cmd->serial_number, jiffies); | ||
| 242 | 250 | ||
| 243 | pc->flags |= PC_FLAG_TIMEDOUT; | 251 | /* |
| 252 | * Some commands are *slow* and normally take a long time to complete. | ||
| 253 | * Usually we can use the ATAPI "disconnect" to bypass this, but not all | ||
| 254 | * commands/drives support that. Let ide_timer_expiry keep polling us | ||
| 255 | * for these. | ||
| 256 | */ | ||
| 257 | switch (rq->cmd[0]) { | ||
| 258 | case GPCMD_BLANK: | ||
| 259 | case GPCMD_FORMAT_UNIT: | ||
| 260 | case GPCMD_RESERVE_RZONE_TRACK: | ||
| 261 | case GPCMD_CLOSE_TRACK: | ||
| 262 | case GPCMD_FLUSH_CACHE: | ||
| 263 | wait = ATAPI_WAIT_PC; | ||
| 264 | break; | ||
| 265 | default: | ||
| 266 | if (!(rq->cmd_flags & REQ_QUIET)) | ||
| 267 | printk(KERN_INFO "cmd 0x%x timed out\n", | ||
| 268 | rq->cmd[0]); | ||
| 269 | wait = 0; | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | return wait; | ||
| 273 | } | ||
| 274 | EXPORT_SYMBOL_GPL(ide_cd_expiry); | ||
| 244 | 275 | ||
| 245 | return 0; /* we do not want the IDE subsystem to retry */ | 276 | int ide_cd_get_xferlen(struct request *rq) |
| 277 | { | ||
| 278 | if (blk_fs_request(rq)) | ||
| 279 | return 32768; | ||
| 280 | else if (blk_sense_request(rq) || blk_pc_request(rq) || | ||
| 281 | rq->cmd_type == REQ_TYPE_ATA_PC) | ||
| 282 | return rq->data_len; | ||
| 283 | else | ||
| 284 | return 0; | ||
| 246 | } | 285 | } |
| 247 | EXPORT_SYMBOL_GPL(ide_scsi_expiry); | 286 | EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); |
| 248 | 287 | ||
| 249 | /* | 288 | /* |
| 250 | * This is the usual interrupt handler which will be called during a packet | 289 | * This is the usual interrupt handler which will be called during a packet |
| @@ -258,21 +297,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 258 | struct request *rq = hwif->hwgroup->rq; | 297 | struct request *rq = hwif->hwgroup->rq; |
| 259 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 298 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
| 260 | xfer_func_t *xferfunc; | 299 | xfer_func_t *xferfunc; |
| 261 | ide_expiry_t *expiry; | ||
| 262 | unsigned int timeout, temp; | 300 | unsigned int timeout, temp; |
| 263 | u16 bcount; | 301 | u16 bcount; |
| 264 | u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0; | 302 | u8 stat, ireason, dsc = 0; |
| 265 | 303 | ||
| 266 | debug_log("Enter %s - interrupt handler\n", __func__); | 304 | debug_log("Enter %s - interrupt handler\n", __func__); |
| 267 | 305 | ||
| 268 | if (scsi) { | 306 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD |
| 269 | timeout = ide_scsi_get_timeout(pc); | 307 | : WAIT_TAPE_CMD; |
| 270 | expiry = ide_scsi_expiry; | ||
| 271 | } else { | ||
| 272 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | ||
| 273 | : WAIT_TAPE_CMD; | ||
| 274 | expiry = NULL; | ||
| 275 | } | ||
| 276 | 308 | ||
| 277 | if (pc->flags & PC_FLAG_TIMEDOUT) { | 309 | if (pc->flags & PC_FLAG_TIMEDOUT) { |
| 278 | drive->pc_callback(drive, 0); | 310 | drive->pc_callback(drive, 0); |
| @@ -284,8 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 284 | 316 | ||
| 285 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | 317 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { |
| 286 | if (hwif->dma_ops->dma_end(drive) || | 318 | if (hwif->dma_ops->dma_end(drive) || |
| 287 | (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) { | 319 | (drive->media == ide_tape && (stat & ATA_ERR))) { |
| 288 | if (drive->media == ide_floppy && !scsi) | 320 | if (drive->media == ide_floppy) |
| 289 | printk(KERN_ERR "%s: DMA %s error\n", | 321 | printk(KERN_ERR "%s: DMA %s error\n", |
| 290 | drive->name, rq_data_dir(pc->rq) | 322 | drive->name, rq_data_dir(pc->rq) |
| 291 | ? "write" : "read"); | 323 | ? "write" : "read"); |
| @@ -307,7 +339,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 307 | 339 | ||
| 308 | local_irq_enable_in_hardirq(); | 340 | local_irq_enable_in_hardirq(); |
| 309 | 341 | ||
| 310 | if (drive->media == ide_tape && !scsi && | 342 | if (drive->media == ide_tape && |
| 311 | (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) | 343 | (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) |
| 312 | stat &= ~ATA_ERR; | 344 | stat &= ~ATA_ERR; |
| 313 | 345 | ||
| @@ -315,11 +347,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 315 | /* Error detected */ | 347 | /* Error detected */ |
| 316 | debug_log("%s: I/O error\n", drive->name); | 348 | debug_log("%s: I/O error\n", drive->name); |
| 317 | 349 | ||
| 318 | if (drive->media != ide_tape || scsi) { | 350 | if (drive->media != ide_tape) |
| 319 | pc->rq->errors++; | 351 | pc->rq->errors++; |
| 320 | if (scsi) | ||
| 321 | goto cmd_finished; | ||
| 322 | } | ||
| 323 | 352 | ||
| 324 | if (rq->cmd[0] == REQUEST_SENSE) { | 353 | if (rq->cmd[0] == REQUEST_SENSE) { |
| 325 | printk(KERN_ERR "%s: I/O error in request sense" | 354 | printk(KERN_ERR "%s: I/O error in request sense" |
| @@ -335,7 +364,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 335 | /* queued, but not started */ | 364 | /* queued, but not started */ |
| 336 | return ide_stopped; | 365 | return ide_stopped; |
| 337 | } | 366 | } |
| 338 | cmd_finished: | ||
| 339 | pc->error = 0; | 367 | pc->error = 0; |
| 340 | 368 | ||
| 341 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) | 369 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) |
| @@ -382,25 +410,8 @@ cmd_finished: | |||
| 382 | "us more data than expected - " | 410 | "us more data than expected - " |
| 383 | "discarding data\n", | 411 | "discarding data\n", |
| 384 | drive->name); | 412 | drive->name); |
| 385 | if (scsi) | 413 | |
| 386 | temp = pc->buf_size - pc->xferred; | 414 | ide_pad_transfer(drive, 0, bcount); |
| 387 | else | ||
| 388 | temp = 0; | ||
| 389 | if (temp) { | ||
| 390 | if (pc->sg) | ||
| 391 | drive->pc_io_buffers(drive, pc, | ||
| 392 | temp, 0); | ||
| 393 | else | ||
| 394 | tp_ops->input_data(drive, NULL, | ||
| 395 | pc->cur_pos, temp); | ||
| 396 | printk(KERN_ERR "%s: transferred %d of " | ||
| 397 | "%d bytes\n", | ||
| 398 | drive->name, | ||
| 399 | temp, bcount); | ||
| 400 | } | ||
| 401 | pc->xferred += temp; | ||
| 402 | pc->cur_pos += temp; | ||
| 403 | ide_pad_transfer(drive, 0, bcount - temp); | ||
| 404 | goto next_irq; | 415 | goto next_irq; |
| 405 | } | 416 | } |
| 406 | debug_log("The device wants to send us more data than " | 417 | debug_log("The device wants to send us more data than " |
| @@ -410,14 +421,13 @@ cmd_finished: | |||
| 410 | } else | 421 | } else |
| 411 | xferfunc = tp_ops->output_data; | 422 | xferfunc = tp_ops->output_data; |
| 412 | 423 | ||
| 413 | if ((drive->media == ide_floppy && !scsi && !pc->buf) || | 424 | if ((drive->media == ide_floppy && !pc->buf) || |
| 414 | (drive->media == ide_tape && !scsi && pc->bh) || | 425 | (drive->media == ide_tape && pc->bh)) { |
| 415 | (scsi && pc->sg)) { | ||
| 416 | int done = drive->pc_io_buffers(drive, pc, bcount, | 426 | int done = drive->pc_io_buffers(drive, pc, bcount, |
| 417 | !!(pc->flags & PC_FLAG_WRITING)); | 427 | !!(pc->flags & PC_FLAG_WRITING)); |
| 418 | 428 | ||
| 419 | /* FIXME: don't do partial completions */ | 429 | /* FIXME: don't do partial completions */ |
| 420 | if (drive->media == ide_floppy && !scsi) | 430 | if (drive->media == ide_floppy) |
| 421 | ide_end_request(drive, 1, done >> 9); | 431 | ide_end_request(drive, 1, done >> 9); |
| 422 | } else | 432 | } else |
| 423 | xferfunc(drive, NULL, pc->cur_pos, bcount); | 433 | xferfunc(drive, NULL, pc->cur_pos, bcount); |
| @@ -430,7 +440,7 @@ cmd_finished: | |||
| 430 | rq->cmd[0], bcount); | 440 | rq->cmd[0], bcount); |
| 431 | next_irq: | 441 | next_irq: |
| 432 | /* And set the interrupt handler again */ | 442 | /* And set the interrupt handler again */ |
| 433 | ide_set_handler(drive, ide_pc_intr, timeout, expiry); | 443 | ide_set_handler(drive, ide_pc_intr, timeout, NULL); |
| 434 | return ide_started; | 444 | return ide_started; |
| 435 | } | 445 | } |
| 436 | 446 | ||
| @@ -479,11 +489,12 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive) | |||
| 479 | 489 | ||
| 480 | static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | 490 | static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) |
| 481 | { | 491 | { |
| 482 | struct ide_atapi_pc *pc = drive->pc; | 492 | struct ide_atapi_pc *uninitialized_var(pc); |
| 483 | ide_hwif_t *hwif = drive->hwif; | 493 | ide_hwif_t *hwif = drive->hwif; |
| 484 | struct request *rq = hwif->hwgroup->rq; | 494 | struct request *rq = hwif->hwgroup->rq; |
| 485 | ide_expiry_t *expiry; | 495 | ide_expiry_t *expiry; |
| 486 | unsigned int timeout; | 496 | unsigned int timeout; |
| 497 | int cmd_len; | ||
| 487 | ide_startstop_t startstop; | 498 | ide_startstop_t startstop; |
| 488 | u8 ireason; | 499 | u8 ireason; |
| 489 | 500 | ||
| @@ -493,101 +504,124 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | |||
| 493 | return startstop; | 504 | return startstop; |
| 494 | } | 505 | } |
| 495 | 506 | ||
| 496 | ireason = ide_read_ireason(drive); | 507 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { |
| 497 | if (drive->media == ide_tape && | 508 | if (drive->dma) |
| 498 | (drive->dev_flags & IDE_DFLAG_SCSI) == 0) | 509 | drive->waiting_for_dma = 1; |
| 499 | ireason = ide_wait_ireason(drive, ireason); | ||
| 500 | |||
| 501 | if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { | ||
| 502 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | ||
| 503 | "a packet command\n", drive->name); | ||
| 504 | return ide_do_reset(drive); | ||
| 505 | } | 510 | } |
| 506 | 511 | ||
| 507 | /* | 512 | if (dev_is_idecd(drive)) { |
| 508 | * If necessary schedule the packet transfer to occur 'timeout' | 513 | /* ATAPI commands get padded out to 12 bytes minimum */ |
| 509 | * miliseconds later in ide_delayed_transfer_pc() after the device | 514 | cmd_len = COMMAND_SIZE(rq->cmd[0]); |
| 510 | * says it's ready for a packet. | 515 | if (cmd_len < ATAPI_MIN_CDB_BYTES) |
| 511 | */ | 516 | cmd_len = ATAPI_MIN_CDB_BYTES; |
| 512 | if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { | 517 | |
| 513 | timeout = drive->pc_delay; | 518 | timeout = rq->timeout; |
| 514 | expiry = &ide_delayed_transfer_pc; | 519 | expiry = ide_cd_expiry; |
| 515 | } else { | 520 | } else { |
| 516 | if (drive->dev_flags & IDE_DFLAG_SCSI) { | 521 | pc = drive->pc; |
| 517 | timeout = ide_scsi_get_timeout(pc); | 522 | |
| 518 | expiry = ide_scsi_expiry; | 523 | cmd_len = ATAPI_MIN_CDB_BYTES; |
| 524 | |||
| 525 | /* | ||
| 526 | * If necessary schedule the packet transfer to occur 'timeout' | ||
| 527 | * miliseconds later in ide_delayed_transfer_pc() after the | ||
| 528 | * device says it's ready for a packet. | ||
| 529 | */ | ||
| 530 | if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { | ||
| 531 | timeout = drive->pc_delay; | ||
| 532 | expiry = &ide_delayed_transfer_pc; | ||
| 519 | } else { | 533 | } else { |
| 520 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | 534 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD |
| 521 | : WAIT_TAPE_CMD; | 535 | : WAIT_TAPE_CMD; |
| 522 | expiry = NULL; | 536 | expiry = NULL; |
| 523 | } | 537 | } |
| 538 | |||
| 539 | ireason = ide_read_ireason(drive); | ||
| 540 | if (drive->media == ide_tape) | ||
| 541 | ireason = ide_wait_ireason(drive, ireason); | ||
| 542 | |||
| 543 | if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { | ||
| 544 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | ||
| 545 | "a packet command\n", drive->name); | ||
| 546 | |||
| 547 | return ide_do_reset(drive); | ||
| 548 | } | ||
| 524 | } | 549 | } |
| 525 | 550 | ||
| 526 | /* Set the interrupt routine */ | 551 | /* Set the interrupt routine */ |
| 527 | ide_set_handler(drive, ide_pc_intr, timeout, expiry); | 552 | ide_set_handler(drive, ide_pc_intr, timeout, expiry); |
| 528 | 553 | ||
| 529 | /* Begin DMA, if necessary */ | 554 | /* Begin DMA, if necessary */ |
| 530 | if (pc->flags & PC_FLAG_DMA_OK) { | 555 | if (dev_is_idecd(drive)) { |
| 531 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | 556 | if (drive->dma) |
| 532 | hwif->dma_ops->dma_start(drive); | 557 | hwif->dma_ops->dma_start(drive); |
| 558 | } else { | ||
| 559 | if (pc->flags & PC_FLAG_DMA_OK) { | ||
| 560 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
| 561 | hwif->dma_ops->dma_start(drive); | ||
| 562 | } | ||
| 533 | } | 563 | } |
| 534 | 564 | ||
| 535 | /* Send the actual packet */ | 565 | /* Send the actual packet */ |
| 536 | if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) | 566 | if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) |
| 537 | hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12); | 567 | hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); |
| 538 | 568 | ||
| 539 | return ide_started; | 569 | return ide_started; |
| 540 | } | 570 | } |
| 541 | 571 | ||
| 542 | ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, | 572 | ide_startstop_t ide_issue_pc(ide_drive_t *drive) |
| 543 | ide_expiry_t *expiry) | ||
| 544 | { | 573 | { |
| 545 | struct ide_atapi_pc *pc = drive->pc; | 574 | struct ide_atapi_pc *pc; |
| 546 | ide_hwif_t *hwif = drive->hwif; | 575 | ide_hwif_t *hwif = drive->hwif; |
| 576 | ide_expiry_t *expiry = NULL; | ||
| 577 | unsigned int timeout; | ||
| 547 | u32 tf_flags; | 578 | u32 tf_flags; |
| 548 | u16 bcount; | 579 | u16 bcount; |
| 549 | u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); | ||
| 550 | 580 | ||
| 551 | /* We haven't transferred any data yet */ | 581 | if (dev_is_idecd(drive)) { |
| 552 | pc->xferred = 0; | 582 | tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; |
| 553 | pc->cur_pos = pc->buf; | 583 | bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); |
| 584 | expiry = ide_cd_expiry; | ||
| 585 | timeout = ATAPI_WAIT_PC; | ||
| 554 | 586 | ||
| 555 | /* Request to transfer the entire buffer at once */ | 587 | if (drive->dma) |
| 556 | if (drive->media == ide_tape && scsi == 0) | 588 | drive->dma = !hwif->dma_ops->dma_setup(drive); |
| 557 | bcount = pc->req_xfer; | 589 | } else { |
| 558 | else | 590 | pc = drive->pc; |
| 559 | bcount = min(pc->req_xfer, 63 * 1024); | ||
| 560 | 591 | ||
| 561 | if (pc->flags & PC_FLAG_DMA_ERROR) { | 592 | /* We haven't transferred any data yet */ |
| 562 | pc->flags &= ~PC_FLAG_DMA_ERROR; | 593 | pc->xferred = 0; |
| 563 | ide_dma_off(drive); | 594 | pc->cur_pos = pc->buf; |
| 564 | } | ||
| 565 | 595 | ||
| 566 | if ((pc->flags & PC_FLAG_DMA_OK) && | 596 | tf_flags = IDE_TFLAG_OUT_DEVICE; |
| 567 | (drive->dev_flags & IDE_DFLAG_USING_DMA)) { | 597 | bcount = ((drive->media == ide_tape) ? |
| 568 | if (scsi) | 598 | pc->req_xfer : |
| 569 | hwif->sg_mapped = 1; | 599 | min(pc->req_xfer, 63 * 1024)); |
| 570 | drive->dma = !hwif->dma_ops->dma_setup(drive); | ||
| 571 | if (scsi) | ||
| 572 | hwif->sg_mapped = 0; | ||
| 573 | } | ||
| 574 | 600 | ||
| 575 | if (!drive->dma) | 601 | if (pc->flags & PC_FLAG_DMA_ERROR) { |
| 576 | pc->flags &= ~PC_FLAG_DMA_OK; | 602 | pc->flags &= ~PC_FLAG_DMA_ERROR; |
| 603 | ide_dma_off(drive); | ||
| 604 | } | ||
| 577 | 605 | ||
| 578 | if (scsi) | 606 | if ((pc->flags & PC_FLAG_DMA_OK) && |
| 579 | tf_flags = 0; | 607 | (drive->dev_flags & IDE_DFLAG_USING_DMA)) |
| 580 | else if (drive->media == ide_cdrom || drive->media == ide_optical) | 608 | drive->dma = !hwif->dma_ops->dma_setup(drive); |
| 581 | tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; | 609 | |
| 582 | else | 610 | if (!drive->dma) |
| 583 | tf_flags = IDE_TFLAG_OUT_DEVICE; | 611 | pc->flags &= ~PC_FLAG_DMA_OK; |
| 612 | |||
| 613 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | ||
| 614 | : WAIT_TAPE_CMD; | ||
| 615 | } | ||
| 584 | 616 | ||
| 585 | ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); | 617 | ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); |
| 586 | 618 | ||
| 587 | /* Issue the packet command */ | 619 | /* Issue the packet command */ |
| 588 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { | 620 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { |
| 621 | if (drive->dma) | ||
| 622 | drive->waiting_for_dma = 0; | ||
| 589 | ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, | 623 | ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, |
| 590 | timeout, NULL); | 624 | timeout, expiry); |
| 591 | return ide_started; | 625 | return ide_started; |
| 592 | } else { | 626 | } else { |
| 593 | ide_execute_pkt_cmd(drive); | 627 | ide_execute_pkt_cmd(drive); |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 5daa4dd1b018..1a7410f88249 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -53,14 +53,6 @@ | |||
| 53 | 53 | ||
| 54 | #include "ide-cd.h" | 54 | #include "ide-cd.h" |
| 55 | 55 | ||
| 56 | #define IDECD_DEBUG_LOG 1 | ||
| 57 | |||
| 58 | #if IDECD_DEBUG_LOG | ||
| 59 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | ||
| 60 | #else | ||
| 61 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
| 62 | #endif | ||
| 63 | |||
| 64 | static DEFINE_MUTEX(idecd_ref_mutex); | 56 | static DEFINE_MUTEX(idecd_ref_mutex); |
| 65 | 57 | ||
| 66 | static void ide_cd_release(struct kref *); | 58 | static void ide_cd_release(struct kref *); |
| @@ -519,37 +511,8 @@ end_request: | |||
| 519 | return 1; | 511 | return 1; |
| 520 | } | 512 | } |
| 521 | 513 | ||
| 522 | static int cdrom_timer_expiry(ide_drive_t *drive) | 514 | static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *); |
| 523 | { | 515 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); |
| 524 | struct request *rq = HWGROUP(drive)->rq; | ||
| 525 | unsigned long wait = 0; | ||
| 526 | |||
| 527 | ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__, | ||
| 528 | rq->cmd[0]); | ||
| 529 | |||
| 530 | /* | ||
| 531 | * Some commands are *slow* and normally take a long time to complete. | ||
| 532 | * Usually we can use the ATAPI "disconnect" to bypass this, but not all | ||
| 533 | * commands/drives support that. Let ide_timer_expiry keep polling us | ||
| 534 | * for these. | ||
| 535 | */ | ||
| 536 | switch (rq->cmd[0]) { | ||
| 537 | case GPCMD_BLANK: | ||
| 538 | case GPCMD_FORMAT_UNIT: | ||
| 539 | case GPCMD_RESERVE_RZONE_TRACK: | ||
| 540 | case GPCMD_CLOSE_TRACK: | ||
| 541 | case GPCMD_FLUSH_CACHE: | ||
| 542 | wait = ATAPI_WAIT_PC; | ||
| 543 | break; | ||
| 544 | default: | ||
| 545 | if (!(rq->cmd_flags & REQ_QUIET)) | ||
| 546 | printk(KERN_INFO PFX "cmd 0x%x timed out\n", | ||
| 547 | rq->cmd[0]); | ||
| 548 | wait = 0; | ||
| 549 | break; | ||
| 550 | } | ||
| 551 | return wait; | ||
| 552 | } | ||
| 553 | 516 | ||
| 554 | /* | 517 | /* |
| 555 | * Set up the device registers for transferring a packet command on DEV, | 518 | * Set up the device registers for transferring a packet command on DEV, |
| @@ -559,11 +522,13 @@ static int cdrom_timer_expiry(ide_drive_t *drive) | |||
| 559 | * called when the interrupt from the drive arrives. Otherwise, HANDLER | 522 | * called when the interrupt from the drive arrives. Otherwise, HANDLER |
| 560 | * will be called immediately after the drive is prepared for the transfer. | 523 | * will be called immediately after the drive is prepared for the transfer. |
| 561 | */ | 524 | */ |
| 562 | static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | 525 | static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive) |
| 563 | int xferlen, | ||
| 564 | ide_handler_t *handler) | ||
| 565 | { | 526 | { |
| 566 | ide_hwif_t *hwif = drive->hwif; | 527 | ide_hwif_t *hwif = drive->hwif; |
| 528 | struct request *rq = hwif->hwgroup->rq; | ||
| 529 | int xferlen; | ||
| 530 | |||
| 531 | xferlen = ide_cd_get_xferlen(rq); | ||
| 567 | 532 | ||
| 568 | ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); | 533 | ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); |
| 569 | 534 | ||
| @@ -581,13 +546,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | |||
| 581 | drive->waiting_for_dma = 0; | 546 | drive->waiting_for_dma = 0; |
| 582 | 547 | ||
| 583 | /* packet command */ | 548 | /* packet command */ |
| 584 | ide_execute_command(drive, ATA_CMD_PACKET, handler, | 549 | ide_execute_command(drive, ATA_CMD_PACKET, |
| 585 | ATAPI_WAIT_PC, cdrom_timer_expiry); | 550 | cdrom_transfer_packet_command, |
| 551 | ATAPI_WAIT_PC, ide_cd_expiry); | ||
| 586 | return ide_started; | 552 | return ide_started; |
| 587 | } else { | 553 | } else { |
| 588 | ide_execute_pkt_cmd(drive); | 554 | ide_execute_pkt_cmd(drive); |
| 589 | 555 | ||
| 590 | return (*handler) (drive); | 556 | return cdrom_transfer_packet_command(drive); |
| 591 | } | 557 | } |
| 592 | } | 558 | } |
| 593 | 559 | ||
| @@ -598,11 +564,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | |||
| 598 | * there's data ready. | 564 | * there's data ready. |
| 599 | */ | 565 | */ |
| 600 | #define ATAPI_MIN_CDB_BYTES 12 | 566 | #define ATAPI_MIN_CDB_BYTES 12 |
| 601 | static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, | 567 | static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive) |
| 602 | struct request *rq, | ||
| 603 | ide_handler_t *handler) | ||
| 604 | { | 568 | { |
| 605 | ide_hwif_t *hwif = drive->hwif; | 569 | ide_hwif_t *hwif = drive->hwif; |
| 570 | struct request *rq = hwif->hwgroup->rq; | ||
| 606 | int cmd_len; | 571 | int cmd_len; |
| 607 | ide_startstop_t startstop; | 572 | ide_startstop_t startstop; |
| 608 | 573 | ||
| @@ -629,7 +594,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, | |||
| 629 | } | 594 | } |
| 630 | 595 | ||
| 631 | /* arm the interrupt handler */ | 596 | /* arm the interrupt handler */ |
| 632 | ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry); | 597 | ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry); |
| 633 | 598 | ||
| 634 | /* ATAPI commands get padded out to 12 bytes minimum */ | 599 | /* ATAPI commands get padded out to 12 bytes minimum */ |
| 635 | cmd_len = COMMAND_SIZE(rq->cmd[0]); | 600 | cmd_len = COMMAND_SIZE(rq->cmd[0]); |
| @@ -717,8 +682,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) | |||
| 717 | return 1; | 682 | return 1; |
| 718 | } | 683 | } |
| 719 | 684 | ||
| 720 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); | ||
| 721 | |||
| 722 | static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, | 685 | static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, |
| 723 | struct request *rq) | 686 | struct request *rq) |
| 724 | { | 687 | { |
| @@ -761,20 +724,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, | |||
| 761 | } | 724 | } |
| 762 | 725 | ||
| 763 | /* | 726 | /* |
| 764 | * Routine to send a read/write packet command to the drive. This is usually | ||
| 765 | * called directly from cdrom_start_{read,write}(). However, for drq_interrupt | ||
| 766 | * devices, it is called from an interrupt when the drive is ready to accept | ||
| 767 | * the command. | ||
| 768 | */ | ||
| 769 | static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) | ||
| 770 | { | ||
| 771 | struct request *rq = drive->hwif->hwgroup->rq; | ||
| 772 | |||
| 773 | /* send the command to the drive and return */ | ||
| 774 | return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); | ||
| 775 | } | ||
| 776 | |||
| 777 | /* | ||
| 778 | * Fix up a possibly partially-processed request so that we can start it over | 727 | * Fix up a possibly partially-processed request so that we can start it over |
| 779 | * entirely, or even put it back on the request queue. | 728 | * entirely, or even put it back on the request queue. |
| 780 | */ | 729 | */ |
| @@ -1096,7 +1045,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 1096 | } else { | 1045 | } else { |
| 1097 | timeout = ATAPI_WAIT_PC; | 1046 | timeout = ATAPI_WAIT_PC; |
| 1098 | if (!blk_fs_request(rq)) | 1047 | if (!blk_fs_request(rq)) |
| 1099 | expiry = cdrom_timer_expiry; | 1048 | expiry = ide_cd_expiry; |
| 1100 | } | 1049 | } |
| 1101 | 1050 | ||
| 1102 | ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry); | 1051 | ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry); |
| @@ -1163,13 +1112,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | |||
| 1163 | return ide_started; | 1112 | return ide_started; |
| 1164 | } | 1113 | } |
| 1165 | 1114 | ||
| 1166 | static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) | ||
| 1167 | { | ||
| 1168 | struct request *rq = HWGROUP(drive)->rq; | ||
| 1169 | |||
| 1170 | return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | 1115 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) |
| 1174 | { | 1116 | { |
| 1175 | 1117 | ||
| @@ -1214,18 +1156,12 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
| 1214 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | 1156 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, |
| 1215 | sector_t block) | 1157 | sector_t block) |
| 1216 | { | 1158 | { |
| 1217 | ide_handler_t *fn; | ||
| 1218 | int xferlen; | ||
| 1219 | |||
| 1220 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " | 1159 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " |
| 1221 | "rq->cmd_type: 0x%x, block: %llu\n", | 1160 | "rq->cmd_type: 0x%x, block: %llu\n", |
| 1222 | __func__, rq->cmd[0], rq->cmd_type, | 1161 | __func__, rq->cmd[0], rq->cmd_type, |
| 1223 | (unsigned long long)block); | 1162 | (unsigned long long)block); |
| 1224 | 1163 | ||
| 1225 | if (blk_fs_request(rq)) { | 1164 | if (blk_fs_request(rq)) { |
| 1226 | xferlen = 32768; | ||
| 1227 | fn = cdrom_start_rw_cont; | ||
| 1228 | |||
| 1229 | if (cdrom_start_rw(drive, rq) == ide_stopped) | 1165 | if (cdrom_start_rw(drive, rq) == ide_stopped) |
| 1230 | return ide_stopped; | 1166 | return ide_stopped; |
| 1231 | 1167 | ||
| @@ -1233,9 +1169,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
| 1233 | return ide_stopped; | 1169 | return ide_stopped; |
| 1234 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || | 1170 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || |
| 1235 | rq->cmd_type == REQ_TYPE_ATA_PC) { | 1171 | rq->cmd_type == REQ_TYPE_ATA_PC) { |
| 1236 | xferlen = rq->data_len; | ||
| 1237 | fn = cdrom_do_newpc_cont; | ||
| 1238 | |||
| 1239 | if (!rq->timeout) | 1172 | if (!rq->timeout) |
| 1240 | rq->timeout = ATAPI_WAIT_PC; | 1173 | rq->timeout = ATAPI_WAIT_PC; |
| 1241 | 1174 | ||
| @@ -1250,7 +1183,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
| 1250 | return ide_stopped; | 1183 | return ide_stopped; |
| 1251 | } | 1184 | } |
| 1252 | 1185 | ||
| 1253 | return cdrom_start_packet_command(drive, xferlen, fn); | 1186 | return cdrom_start_packet_command(drive); |
| 1254 | } | 1187 | } |
| 1255 | 1188 | ||
| 1256 | /* | 1189 | /* |
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index d5ce3362dbd1..bf676b262181 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h | |||
| @@ -8,10 +8,14 @@ | |||
| 8 | #include <linux/cdrom.h> | 8 | #include <linux/cdrom.h> |
| 9 | #include <asm/byteorder.h> | 9 | #include <asm/byteorder.h> |
| 10 | 10 | ||
| 11 | /* | 11 | #define IDECD_DEBUG_LOG 0 |
| 12 | * typical timeout for packet command | 12 | |
| 13 | */ | 13 | #if IDECD_DEBUG_LOG |
| 14 | #define ATAPI_WAIT_PC (60 * HZ) | 14 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) |
| 15 | #else | ||
| 16 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
| 17 | #endif | ||
| 18 | |||
| 15 | #define ATAPI_WAIT_WRITE_BUSY (10 * HZ) | 19 | #define ATAPI_WAIT_WRITE_BUSY (10 * HZ) |
| 16 | 20 | ||
| 17 | /************************************************************************/ | 21 | /************************************************************************/ |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index aeb1ad782f54..0a48e2dc53a2 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
| @@ -197,7 +197,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | |||
| 197 | 197 | ||
| 198 | pc->retries++; | 198 | pc->retries++; |
| 199 | 199 | ||
| 200 | return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL); | 200 | return ide_issue_pc(drive); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) | 203 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) |
| @@ -342,38 +342,38 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, | |||
| 342 | * Look at the flexible disk page parameters. We ignore the CHS capacity | 342 | * Look at the flexible disk page parameters. We ignore the CHS capacity |
| 343 | * parameters and use the LBA parameters instead. | 343 | * parameters and use the LBA parameters instead. |
| 344 | */ | 344 | */ |
| 345 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | 345 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive, |
| 346 | struct ide_atapi_pc *pc) | ||
| 346 | { | 347 | { |
| 347 | struct ide_disk_obj *floppy = drive->driver_data; | 348 | struct ide_disk_obj *floppy = drive->driver_data; |
| 348 | struct gendisk *disk = floppy->disk; | 349 | struct gendisk *disk = floppy->disk; |
| 349 | struct ide_atapi_pc pc; | ||
| 350 | u8 *page; | 350 | u8 *page; |
| 351 | int capacity, lba_capacity; | 351 | int capacity, lba_capacity; |
| 352 | u16 transfer_rate, sector_size, cyls, rpm; | 352 | u16 transfer_rate, sector_size, cyls, rpm; |
| 353 | u8 heads, sectors; | 353 | u8 heads, sectors; |
| 354 | 354 | ||
| 355 | ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); | 355 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); |
| 356 | 356 | ||
| 357 | if (ide_queue_pc_tail(drive, disk, &pc)) { | 357 | if (ide_queue_pc_tail(drive, disk, pc)) { |
| 358 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); | 358 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); |
| 359 | return 1; | 359 | return 1; |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | if (pc.buf[3] & 0x80) | 362 | if (pc->buf[3] & 0x80) |
| 363 | drive->dev_flags |= IDE_DFLAG_WP; | 363 | drive->dev_flags |= IDE_DFLAG_WP; |
| 364 | else | 364 | else |
| 365 | drive->dev_flags &= ~IDE_DFLAG_WP; | 365 | drive->dev_flags &= ~IDE_DFLAG_WP; |
| 366 | 366 | ||
| 367 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); | 367 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
| 368 | 368 | ||
| 369 | page = &pc.buf[8]; | 369 | page = &pc->buf[8]; |
| 370 | 370 | ||
| 371 | transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]); | 371 | transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]); |
| 372 | sector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]); | 372 | sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]); |
| 373 | cyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]); | 373 | cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]); |
| 374 | rpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]); | 374 | rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]); |
| 375 | heads = pc.buf[8 + 4]; | 375 | heads = pc->buf[8 + 4]; |
| 376 | sectors = pc.buf[8 + 5]; | 376 | sectors = pc->buf[8 + 5]; |
| 377 | 377 | ||
| 378 | capacity = cyls * heads * sectors * sector_size; | 378 | capacity = cyls * heads * sectors * sector_size; |
| 379 | 379 | ||
| @@ -499,7 +499,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
| 499 | 499 | ||
| 500 | /* Clik! disk does not support get_flexible_disk_page */ | 500 | /* Clik! disk does not support get_flexible_disk_page */ |
| 501 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 501 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
| 502 | (void) ide_floppy_get_flexible_disk_page(drive); | 502 | (void) ide_floppy_get_flexible_disk_page(drive, &pc); |
| 503 | 503 | ||
| 504 | return rc; | 504 | return rc; |
| 505 | } | 505 | } |
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index 2bc51ff73fee..8f8be8546038 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c | |||
| @@ -31,10 +31,11 @@ | |||
| 31 | * On exit we set nformats to the number of records we've actually initialized. | 31 | * On exit we set nformats to the number of records we've actually initialized. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) | 34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, |
| 35 | struct ide_atapi_pc *pc, | ||
| 36 | int __user *arg) | ||
| 35 | { | 37 | { |
| 36 | struct ide_disk_obj *floppy = drive->driver_data; | 38 | struct ide_disk_obj *floppy = drive->driver_data; |
| 37 | struct ide_atapi_pc pc; | ||
| 38 | u8 header_len, desc_cnt; | 39 | u8 header_len, desc_cnt; |
| 39 | int i, blocks, length, u_array_size, u_index; | 40 | int i, blocks, length, u_array_size, u_index; |
| 40 | int __user *argp; | 41 | int __user *argp; |
| @@ -45,13 +46,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) | |||
| 45 | if (u_array_size <= 0) | 46 | if (u_array_size <= 0) |
| 46 | return -EINVAL; | 47 | return -EINVAL; |
| 47 | 48 | ||
| 48 | ide_floppy_create_read_capacity_cmd(&pc); | 49 | ide_floppy_create_read_capacity_cmd(pc); |
| 49 | if (ide_queue_pc_tail(drive, floppy->disk, &pc)) { | 50 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) { |
| 50 | printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); | 51 | printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); |
| 51 | return -EIO; | 52 | return -EIO; |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | header_len = pc.buf[3]; | 55 | header_len = pc->buf[3]; |
| 55 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ | 56 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ |
| 56 | 57 | ||
| 57 | u_index = 0; | 58 | u_index = 0; |
| @@ -68,8 +69,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) | |||
| 68 | if (u_index >= u_array_size) | 69 | if (u_index >= u_array_size) |
| 69 | break; /* User-supplied buffer too small */ | 70 | break; /* User-supplied buffer too small */ |
| 70 | 71 | ||
| 71 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); | 72 | blocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]); |
| 72 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); | 73 | length = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]); |
| 73 | 74 | ||
| 74 | if (put_user(blocks, argp)) | 75 | if (put_user(blocks, argp)) |
| 75 | return -EFAULT; | 76 | return -EFAULT; |
| @@ -111,29 +112,28 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, | |||
| 111 | pc->flags |= PC_FLAG_WRITING; | 112 | pc->flags |= PC_FLAG_WRITING; |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) | 115 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc) |
| 115 | { | 116 | { |
| 116 | struct ide_disk_obj *floppy = drive->driver_data; | 117 | struct ide_disk_obj *floppy = drive->driver_data; |
| 117 | struct ide_atapi_pc pc; | ||
| 118 | 118 | ||
| 119 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; | 119 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; |
| 120 | 120 | ||
| 121 | ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE); | 121 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE); |
| 122 | pc.flags |= PC_FLAG_SUPPRESS_ERROR; | 122 | pc->flags |= PC_FLAG_SUPPRESS_ERROR; |
| 123 | 123 | ||
| 124 | if (ide_queue_pc_tail(drive, floppy->disk, &pc)) | 124 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) |
| 125 | return 1; | 125 | return 1; |
| 126 | 126 | ||
| 127 | if (pc.buf[8 + 2] & 0x40) | 127 | if (pc->buf[8 + 2] & 0x40) |
| 128 | drive->atapi_flags |= IDE_AFLAG_SRFP; | 128 | drive->atapi_flags |= IDE_AFLAG_SRFP; |
| 129 | 129 | ||
| 130 | return 0; | 130 | return 0; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) | 133 | static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc, |
| 134 | int __user *arg) | ||
| 134 | { | 135 | { |
| 135 | struct ide_disk_obj *floppy = drive->driver_data; | 136 | struct ide_disk_obj *floppy = drive->driver_data; |
| 136 | struct ide_atapi_pc pc; | ||
| 137 | int blocks, length, flags, err = 0; | 137 | int blocks, length, flags, err = 0; |
| 138 | 138 | ||
| 139 | if (floppy->openers > 1) { | 139 | if (floppy->openers > 1) { |
| @@ -166,10 +166,10 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) | |||
| 166 | goto out; | 166 | goto out; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | (void)ide_floppy_get_sfrp_bit(drive); | 169 | ide_floppy_get_sfrp_bit(drive, pc); |
| 170 | ide_floppy_create_format_unit_cmd(&pc, blocks, length, flags); | 170 | ide_floppy_create_format_unit_cmd(pc, blocks, length, flags); |
| 171 | 171 | ||
| 172 | if (ide_queue_pc_tail(drive, floppy->disk, &pc)) | 172 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) |
| 173 | err = -EIO; | 173 | err = -EIO; |
| 174 | 174 | ||
| 175 | out: | 175 | out: |
| @@ -188,15 +188,16 @@ out: | |||
| 188 | * the dsc bit, and return either 0 or 65536. | 188 | * the dsc bit, and return either 0 or 65536. |
| 189 | */ | 189 | */ |
| 190 | 190 | ||
| 191 | static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) | 191 | static int ide_floppy_get_format_progress(ide_drive_t *drive, |
| 192 | struct ide_atapi_pc *pc, | ||
| 193 | int __user *arg) | ||
| 192 | { | 194 | { |
| 193 | struct ide_disk_obj *floppy = drive->driver_data; | 195 | struct ide_disk_obj *floppy = drive->driver_data; |
| 194 | struct ide_atapi_pc pc; | ||
| 195 | int progress_indication = 0x10000; | 196 | int progress_indication = 0x10000; |
| 196 | 197 | ||
| 197 | if (drive->atapi_flags & IDE_AFLAG_SRFP) { | 198 | if (drive->atapi_flags & IDE_AFLAG_SRFP) { |
| 198 | ide_create_request_sense_cmd(drive, &pc); | 199 | ide_create_request_sense_cmd(drive, pc); |
| 199 | if (ide_queue_pc_tail(drive, floppy->disk, &pc)) | 200 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) |
| 200 | return -EIO; | 201 | return -EIO; |
| 201 | 202 | ||
| 202 | if (floppy->sense_key == 2 && | 203 | if (floppy->sense_key == 2 && |
| @@ -241,20 +242,21 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
| 241 | return 0; | 242 | return 0; |
| 242 | } | 243 | } |
| 243 | 244 | ||
| 244 | static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode, | 245 | static int ide_floppy_format_ioctl(ide_drive_t *drive, struct ide_atapi_pc *pc, |
| 245 | unsigned int cmd, void __user *argp) | 246 | fmode_t mode, unsigned int cmd, |
| 247 | void __user *argp) | ||
| 246 | { | 248 | { |
| 247 | switch (cmd) { | 249 | switch (cmd) { |
| 248 | case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: | 250 | case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: |
| 249 | return 0; | 251 | return 0; |
| 250 | case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: | 252 | case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: |
| 251 | return ide_floppy_get_format_capacities(drive, argp); | 253 | return ide_floppy_get_format_capacities(drive, pc, argp); |
| 252 | case IDEFLOPPY_IOCTL_FORMAT_START: | 254 | case IDEFLOPPY_IOCTL_FORMAT_START: |
| 253 | if (!(mode & FMODE_WRITE)) | 255 | if (!(mode & FMODE_WRITE)) |
| 254 | return -EPERM; | 256 | return -EPERM; |
| 255 | return ide_floppy_format_unit(drive, (int __user *)argp); | 257 | return ide_floppy_format_unit(drive, pc, (int __user *)argp); |
| 256 | case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: | 258 | case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: |
| 257 | return ide_floppy_get_format_progress(drive, argp); | 259 | return ide_floppy_get_format_progress(drive, pc, argp); |
| 258 | default: | 260 | default: |
| 259 | return -ENOTTY; | 261 | return -ENOTTY; |
| 260 | } | 262 | } |
| @@ -270,7 +272,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, | |||
| 270 | if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) | 272 | if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) |
| 271 | return ide_floppy_lockdoor(drive, &pc, arg, cmd); | 273 | return ide_floppy_lockdoor(drive, &pc, arg, cmd); |
| 272 | 274 | ||
| 273 | err = ide_floppy_format_ioctl(drive, mode, cmd, argp); | 275 | err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp); |
| 274 | if (err != -ENOTTY) | 276 | if (err != -ENOTTY) |
| 275 | return err; | 277 | return err; |
| 276 | 278 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ecacc008fdaf..1c36a8e83d36 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -426,9 +426,6 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq) | |||
| 426 | ide_hwif_t *hwif = drive->hwif; | 426 | ide_hwif_t *hwif = drive->hwif; |
| 427 | struct scatterlist *sg = hwif->sg_table; | 427 | struct scatterlist *sg = hwif->sg_table; |
| 428 | 428 | ||
| 429 | if (hwif->sg_mapped) /* needed by ide-scsi */ | ||
| 430 | return; | ||
| 431 | |||
| 432 | if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { | 429 | if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { |
| 433 | hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); | 430 | hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); |
| 434 | } else { | 431 | } else { |
| @@ -667,85 +664,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) | |||
| 667 | drive->sleep = timeout + jiffies; | 664 | drive->sleep = timeout + jiffies; |
| 668 | drive->dev_flags |= IDE_DFLAG_SLEEPING; | 665 | drive->dev_flags |= IDE_DFLAG_SLEEPING; |
| 669 | } | 666 | } |
| 670 | |||
| 671 | EXPORT_SYMBOL(ide_stall_queue); | 667 | EXPORT_SYMBOL(ide_stall_queue); |
| 672 | 668 | ||
| 673 | #define WAKEUP(drive) ((drive)->service_start + 2 * (drive)->service_time) | ||
| 674 | |||
| 675 | /** | ||
| 676 | * choose_drive - select a drive to service | ||
| 677 | * @hwgroup: hardware group to select on | ||
| 678 | * | ||
| 679 | * choose_drive() selects the next drive which will be serviced. | ||
| 680 | * This is necessary because the IDE layer can't issue commands | ||
| 681 | * to both drives on the same cable, unlike SCSI. | ||
| 682 | */ | ||
| 683 | |||
| 684 | static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) | ||
| 685 | { | ||
| 686 | ide_drive_t *drive, *best; | ||
| 687 | |||
| 688 | repeat: | ||
| 689 | best = NULL; | ||
| 690 | drive = hwgroup->drive; | ||
| 691 | |||
| 692 | /* | ||
| 693 | * drive is doing pre-flush, ordered write, post-flush sequence. even | ||
| 694 | * though that is 3 requests, it must be seen as a single transaction. | ||
| 695 | * we must not preempt this drive until that is complete | ||
| 696 | */ | ||
| 697 | if (blk_queue_flushing(drive->queue)) { | ||
| 698 | /* | ||
| 699 | * small race where queue could get replugged during | ||
| 700 | * the 3-request flush cycle, just yank the plug since | ||
| 701 | * we want it to finish asap | ||
| 702 | */ | ||
| 703 | blk_remove_plug(drive->queue); | ||
| 704 | return drive; | ||
| 705 | } | ||
| 706 | |||
| 707 | do { | ||
| 708 | u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING); | ||
| 709 | u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING)); | ||
| 710 | |||
| 711 | if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) && | ||
| 712 | !elv_queue_empty(drive->queue)) { | ||
| 713 | if (best == NULL || | ||
| 714 | (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) || | ||
| 715 | (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) { | ||
| 716 | if (!blk_queue_plugged(drive->queue)) | ||
| 717 | best = drive; | ||
| 718 | } | ||
| 719 | } | ||
| 720 | } while ((drive = drive->next) != hwgroup->drive); | ||
| 721 | |||
| 722 | if (best && (best->dev_flags & IDE_DFLAG_NICE1) && | ||
| 723 | (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 && | ||
| 724 | best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { | ||
| 725 | long t = (signed long)(WAKEUP(best) - jiffies); | ||
| 726 | if (t >= WAIT_MIN_SLEEP) { | ||
| 727 | /* | ||
| 728 | * We *may* have some time to spare, but first let's see if | ||
| 729 | * someone can potentially benefit from our nice mood today.. | ||
| 730 | */ | ||
| 731 | drive = best->next; | ||
| 732 | do { | ||
| 733 | if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0 | ||
| 734 | && time_before(jiffies - best->service_time, WAKEUP(drive)) | ||
| 735 | && time_before(WAKEUP(drive), jiffies + t)) | ||
| 736 | { | ||
| 737 | ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP)); | ||
| 738 | goto repeat; | ||
| 739 | } | ||
| 740 | } while ((drive = drive->next) != best); | ||
| 741 | } | ||
| 742 | } | ||
| 743 | return best; | ||
| 744 | } | ||
| 745 | |||
| 746 | /* | 669 | /* |
| 747 | * Issue a new request to a drive from hwgroup | 670 | * Issue a new request to a drive from hwgroup |
| 748 | * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..); | ||
| 749 | * | 671 | * |
| 750 | * A hwgroup is a serialized group of IDE interfaces. Usually there is | 672 | * A hwgroup is a serialized group of IDE interfaces. Usually there is |
| 751 | * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) | 673 | * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) |
| @@ -757,8 +679,7 @@ repeat: | |||
| 757 | * possibly along with many other devices. This is especially common in | 679 | * possibly along with many other devices. This is especially common in |
| 758 | * PCI-based systems with off-board IDE controller cards. | 680 | * PCI-based systems with off-board IDE controller cards. |
| 759 | * | 681 | * |
| 760 | * The IDE driver uses a per-hwgroup spinlock to protect | 682 | * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag. |
| 761 | * access to the request queues, and to protect the hwgroup->busy flag. | ||
| 762 | * | 683 | * |
| 763 | * The first thread into the driver for a particular hwgroup sets the | 684 | * The first thread into the driver for a particular hwgroup sets the |
| 764 | * hwgroup->busy flag to indicate that this hwgroup is now active, | 685 | * hwgroup->busy flag to indicate that this hwgroup is now active, |
| @@ -778,69 +699,41 @@ repeat: | |||
| 778 | * the driver. This makes the driver much more friendlier to shared IRQs | 699 | * the driver. This makes the driver much more friendlier to shared IRQs |
| 779 | * than previous designs, while remaining 100% (?) SMP safe and capable. | 700 | * than previous designs, while remaining 100% (?) SMP safe and capable. |
| 780 | */ | 701 | */ |
| 781 | static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | 702 | void do_ide_request(struct request_queue *q) |
| 782 | { | 703 | { |
| 783 | ide_drive_t *drive; | 704 | ide_drive_t *drive = q->queuedata; |
| 784 | ide_hwif_t *hwif; | 705 | ide_hwif_t *hwif = drive->hwif; |
| 706 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
| 785 | struct request *rq; | 707 | struct request *rq; |
| 786 | ide_startstop_t startstop; | 708 | ide_startstop_t startstop; |
| 787 | int loops = 0; | 709 | |
| 788 | 710 | /* | |
| 789 | /* caller must own hwgroup->lock */ | 711 | * drive is doing pre-flush, ordered write, post-flush sequence. even |
| 790 | BUG_ON(!irqs_disabled()); | 712 | * though that is 3 requests, it must be seen as a single transaction. |
| 791 | 713 | * we must not preempt this drive until that is complete | |
| 792 | while (!hwgroup->busy) { | 714 | */ |
| 793 | hwgroup->busy = 1; | 715 | if (blk_queue_flushing(q)) |
| 794 | /* for atari only */ | ||
| 795 | ide_get_lock(ide_intr, hwgroup); | ||
| 796 | drive = choose_drive(hwgroup); | ||
| 797 | if (drive == NULL) { | ||
| 798 | int sleeping = 0; | ||
| 799 | unsigned long sleep = 0; /* shut up, gcc */ | ||
| 800 | hwgroup->rq = NULL; | ||
| 801 | drive = hwgroup->drive; | ||
| 802 | do { | ||
| 803 | if ((drive->dev_flags & IDE_DFLAG_SLEEPING) && | ||
| 804 | (sleeping == 0 || | ||
| 805 | time_before(drive->sleep, sleep))) { | ||
| 806 | sleeping = 1; | ||
| 807 | sleep = drive->sleep; | ||
| 808 | } | ||
| 809 | } while ((drive = drive->next) != hwgroup->drive); | ||
| 810 | if (sleeping) { | ||
| 811 | /* | 716 | /* |
| 812 | * Take a short snooze, and then wake up this hwgroup again. | 717 | * small race where queue could get replugged during |
| 813 | * This gives other hwgroups on the same a chance to | 718 | * the 3-request flush cycle, just yank the plug since |
| 814 | * play fairly with us, just in case there are big differences | 719 | * we want it to finish asap |
| 815 | * in relative throughputs.. don't want to hog the cpu too much. | ||
| 816 | */ | 720 | */ |
| 817 | if (time_before(sleep, jiffies + WAIT_MIN_SLEEP)) | 721 | blk_remove_plug(q); |
| 818 | sleep = jiffies + WAIT_MIN_SLEEP; | ||
| 819 | #if 1 | ||
| 820 | if (timer_pending(&hwgroup->timer)) | ||
| 821 | printk(KERN_CRIT "ide_set_handler: timer already active\n"); | ||
| 822 | #endif | ||
| 823 | /* so that ide_timer_expiry knows what to do */ | ||
| 824 | hwgroup->sleeping = 1; | ||
| 825 | hwgroup->req_gen_timer = hwgroup->req_gen; | ||
| 826 | mod_timer(&hwgroup->timer, sleep); | ||
| 827 | /* we purposely leave hwgroup->busy==1 | ||
| 828 | * while sleeping */ | ||
| 829 | } else { | ||
| 830 | /* Ugly, but how can we sleep for the lock | ||
| 831 | * otherwise? perhaps from tq_disk? | ||
| 832 | */ | ||
| 833 | 722 | ||
| 834 | /* for atari only */ | 723 | spin_unlock_irq(q->queue_lock); |
| 835 | ide_release_lock(); | 724 | spin_lock_irq(&hwgroup->lock); |
| 836 | hwgroup->busy = 0; | 725 | |
| 837 | } | 726 | if (!ide_lock_hwgroup(hwgroup)) { |
| 727 | repeat: | ||
| 728 | hwgroup->rq = NULL; | ||
| 838 | 729 | ||
| 839 | /* no more work for this hwgroup (for now) */ | 730 | if (drive->dev_flags & IDE_DFLAG_SLEEPING) { |
| 840 | return; | 731 | if (time_before(drive->sleep, jiffies)) { |
| 732 | ide_unlock_hwgroup(hwgroup); | ||
| 733 | goto plug_device; | ||
| 734 | } | ||
| 841 | } | 735 | } |
| 842 | again: | 736 | |
| 843 | hwif = HWIF(drive); | ||
| 844 | if (hwif != hwgroup->hwif) { | 737 | if (hwif != hwgroup->hwif) { |
| 845 | /* | 738 | /* |
| 846 | * set nIEN for previous hwif, drives in the | 739 | * set nIEN for previous hwif, drives in the |
| @@ -852,16 +745,20 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
| 852 | hwgroup->hwif = hwif; | 745 | hwgroup->hwif = hwif; |
| 853 | hwgroup->drive = drive; | 746 | hwgroup->drive = drive; |
| 854 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); | 747 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); |
| 855 | drive->service_start = jiffies; | ||
| 856 | 748 | ||
| 749 | spin_unlock_irq(&hwgroup->lock); | ||
| 750 | spin_lock_irq(q->queue_lock); | ||
| 857 | /* | 751 | /* |
| 858 | * we know that the queue isn't empty, but this can happen | 752 | * we know that the queue isn't empty, but this can happen |
| 859 | * if the q->prep_rq_fn() decides to kill a request | 753 | * if the q->prep_rq_fn() decides to kill a request |
| 860 | */ | 754 | */ |
| 861 | rq = elv_next_request(drive->queue); | 755 | rq = elv_next_request(drive->queue); |
| 756 | spin_unlock_irq(q->queue_lock); | ||
| 757 | spin_lock_irq(&hwgroup->lock); | ||
| 758 | |||
| 862 | if (!rq) { | 759 | if (!rq) { |
| 863 | hwgroup->busy = 0; | 760 | ide_unlock_hwgroup(hwgroup); |
| 864 | break; | 761 | goto out; |
| 865 | } | 762 | } |
| 866 | 763 | ||
| 867 | /* | 764 | /* |
| @@ -876,53 +773,36 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
| 876 | * though. I hope that doesn't happen too much, hopefully not | 773 | * though. I hope that doesn't happen too much, hopefully not |
| 877 | * unless the subdriver triggers such a thing in its own PM | 774 | * unless the subdriver triggers such a thing in its own PM |
| 878 | * state machine. | 775 | * state machine. |
| 879 | * | ||
| 880 | * We count how many times we loop here to make sure we service | ||
| 881 | * all drives in the hwgroup without looping for ever | ||
| 882 | */ | 776 | */ |
| 883 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && | 777 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
| 884 | blk_pm_request(rq) == 0 && | 778 | blk_pm_request(rq) == 0 && |
| 885 | (rq->cmd_flags & REQ_PREEMPT) == 0) { | 779 | (rq->cmd_flags & REQ_PREEMPT) == 0) { |
| 886 | drive = drive->next ? drive->next : hwgroup->drive; | 780 | /* there should be no pending command at this point */ |
| 887 | if (loops++ < 4 && !blk_queue_plugged(drive->queue)) | 781 | ide_unlock_hwgroup(hwgroup); |
| 888 | goto again; | 782 | goto plug_device; |
| 889 | /* We clear busy, there should be no pending ATA command at this point. */ | ||
| 890 | hwgroup->busy = 0; | ||
| 891 | break; | ||
| 892 | } | 783 | } |
| 893 | 784 | ||
| 894 | hwgroup->rq = rq; | 785 | hwgroup->rq = rq; |
| 895 | 786 | ||
| 896 | /* | 787 | spin_unlock_irq(&hwgroup->lock); |
| 897 | * Some systems have trouble with IDE IRQs arriving while | ||
| 898 | * the driver is still setting things up. So, here we disable | ||
| 899 | * the IRQ used by this interface while the request is being started. | ||
| 900 | * This may look bad at first, but pretty much the same thing | ||
| 901 | * happens anyway when any interrupt comes in, IDE or otherwise | ||
| 902 | * -- the kernel masks the IRQ while it is being handled. | ||
| 903 | */ | ||
| 904 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | ||
| 905 | disable_irq_nosync(hwif->irq); | ||
| 906 | spin_unlock(&hwgroup->lock); | ||
| 907 | local_irq_enable_in_hardirq(); | ||
| 908 | /* allow other IRQs while we start this request */ | ||
| 909 | startstop = start_request(drive, rq); | 788 | startstop = start_request(drive, rq); |
| 910 | spin_lock_irq(&hwgroup->lock); | 789 | spin_lock_irq(&hwgroup->lock); |
| 911 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | 790 | |
| 912 | enable_irq(hwif->irq); | ||
| 913 | if (startstop == ide_stopped) | 791 | if (startstop == ide_stopped) |
| 914 | hwgroup->busy = 0; | 792 | goto repeat; |
| 915 | } | 793 | } else |
| 916 | } | 794 | goto plug_device; |
| 795 | out: | ||
| 796 | spin_unlock_irq(&hwgroup->lock); | ||
| 797 | spin_lock_irq(q->queue_lock); | ||
| 798 | return; | ||
| 917 | 799 | ||
| 918 | /* | 800 | plug_device: |
| 919 | * Passes the stuff to ide_do_request | 801 | spin_unlock_irq(&hwgroup->lock); |
| 920 | */ | 802 | spin_lock_irq(q->queue_lock); |
| 921 | void do_ide_request(struct request_queue *q) | ||
| 922 | { | ||
| 923 | ide_drive_t *drive = q->queuedata; | ||
| 924 | 803 | ||
| 925 | ide_do_request(HWGROUP(drive), IDE_NO_IRQ); | 804 | if (!elv_queue_empty(q)) |
| 805 | blk_plug_device(q); | ||
| 926 | } | 806 | } |
| 927 | 807 | ||
| 928 | /* | 808 | /* |
| @@ -983,6 +863,17 @@ out: | |||
| 983 | return ret; | 863 | return ret; |
| 984 | } | 864 | } |
| 985 | 865 | ||
| 866 | static void ide_plug_device(ide_drive_t *drive) | ||
| 867 | { | ||
| 868 | struct request_queue *q = drive->queue; | ||
| 869 | unsigned long flags; | ||
| 870 | |||
| 871 | spin_lock_irqsave(q->queue_lock, flags); | ||
| 872 | if (!elv_queue_empty(q)) | ||
| 873 | blk_plug_device(q); | ||
| 874 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
| 875 | } | ||
| 876 | |||
| 986 | /** | 877 | /** |
| 987 | * ide_timer_expiry - handle lack of an IDE interrupt | 878 | * ide_timer_expiry - handle lack of an IDE interrupt |
| 988 | * @data: timer callback magic (hwgroup) | 879 | * @data: timer callback magic (hwgroup) |
| @@ -1000,10 +891,12 @@ out: | |||
| 1000 | void ide_timer_expiry (unsigned long data) | 891 | void ide_timer_expiry (unsigned long data) |
| 1001 | { | 892 | { |
| 1002 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; | 893 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; |
| 894 | ide_drive_t *uninitialized_var(drive); | ||
| 1003 | ide_handler_t *handler; | 895 | ide_handler_t *handler; |
| 1004 | ide_expiry_t *expiry; | 896 | ide_expiry_t *expiry; |
| 1005 | unsigned long flags; | 897 | unsigned long flags; |
| 1006 | unsigned long wait = -1; | 898 | unsigned long wait = -1; |
| 899 | int plug_device = 0; | ||
| 1007 | 900 | ||
| 1008 | spin_lock_irqsave(&hwgroup->lock, flags); | 901 | spin_lock_irqsave(&hwgroup->lock, flags); |
| 1009 | 902 | ||
| @@ -1015,22 +908,15 @@ void ide_timer_expiry (unsigned long data) | |||
| 1015 | * or we were "sleeping" to give other devices a chance. | 908 | * or we were "sleeping" to give other devices a chance. |
| 1016 | * Either way, we don't really want to complain about anything. | 909 | * Either way, we don't really want to complain about anything. |
| 1017 | */ | 910 | */ |
| 1018 | if (hwgroup->sleeping) { | ||
| 1019 | hwgroup->sleeping = 0; | ||
| 1020 | hwgroup->busy = 0; | ||
| 1021 | } | ||
| 1022 | } else { | 911 | } else { |
| 1023 | ide_drive_t *drive = hwgroup->drive; | 912 | drive = hwgroup->drive; |
| 1024 | if (!drive) { | 913 | if (!drive) { |
| 1025 | printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); | 914 | printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); |
| 1026 | hwgroup->handler = NULL; | 915 | hwgroup->handler = NULL; |
| 1027 | } else { | 916 | } else { |
| 1028 | ide_hwif_t *hwif; | 917 | ide_hwif_t *hwif; |
| 1029 | ide_startstop_t startstop = ide_stopped; | 918 | ide_startstop_t startstop = ide_stopped; |
| 1030 | if (!hwgroup->busy) { | 919 | |
| 1031 | hwgroup->busy = 1; /* paranoia */ | ||
| 1032 | printk(KERN_ERR "%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name); | ||
| 1033 | } | ||
| 1034 | if ((expiry = hwgroup->expiry) != NULL) { | 920 | if ((expiry = hwgroup->expiry) != NULL) { |
| 1035 | /* continue */ | 921 | /* continue */ |
| 1036 | if ((wait = expiry(drive)) > 0) { | 922 | if ((wait = expiry(drive)) > 0) { |
| @@ -1071,15 +957,18 @@ void ide_timer_expiry (unsigned long data) | |||
| 1071 | ide_error(drive, "irq timeout", | 957 | ide_error(drive, "irq timeout", |
| 1072 | hwif->tp_ops->read_status(hwif)); | 958 | hwif->tp_ops->read_status(hwif)); |
| 1073 | } | 959 | } |
| 1074 | drive->service_time = jiffies - drive->service_start; | ||
| 1075 | spin_lock_irq(&hwgroup->lock); | 960 | spin_lock_irq(&hwgroup->lock); |
| 1076 | enable_irq(hwif->irq); | 961 | enable_irq(hwif->irq); |
| 1077 | if (startstop == ide_stopped) | 962 | if (startstop == ide_stopped) { |
| 1078 | hwgroup->busy = 0; | 963 | ide_unlock_hwgroup(hwgroup); |
| 964 | plug_device = 1; | ||
| 965 | } | ||
| 1079 | } | 966 | } |
| 1080 | } | 967 | } |
| 1081 | ide_do_request(hwgroup, IDE_NO_IRQ); | ||
| 1082 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 968 | spin_unlock_irqrestore(&hwgroup->lock, flags); |
| 969 | |||
| 970 | if (plug_device) | ||
| 971 | ide_plug_device(drive); | ||
| 1083 | } | 972 | } |
| 1084 | 973 | ||
| 1085 | /** | 974 | /** |
| @@ -1173,10 +1062,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
| 1173 | unsigned long flags; | 1062 | unsigned long flags; |
| 1174 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; | 1063 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; |
| 1175 | ide_hwif_t *hwif = hwgroup->hwif; | 1064 | ide_hwif_t *hwif = hwgroup->hwif; |
| 1176 | ide_drive_t *drive; | 1065 | ide_drive_t *uninitialized_var(drive); |
| 1177 | ide_handler_t *handler; | 1066 | ide_handler_t *handler; |
| 1178 | ide_startstop_t startstop; | 1067 | ide_startstop_t startstop; |
| 1179 | irqreturn_t irq_ret = IRQ_NONE; | 1068 | irqreturn_t irq_ret = IRQ_NONE; |
| 1069 | int plug_device = 0; | ||
| 1180 | 1070 | ||
| 1181 | spin_lock_irqsave(&hwgroup->lock, flags); | 1071 | spin_lock_irqsave(&hwgroup->lock, flags); |
| 1182 | 1072 | ||
| @@ -1241,10 +1131,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
| 1241 | */ | 1131 | */ |
| 1242 | goto out; | 1132 | goto out; |
| 1243 | 1133 | ||
| 1244 | if (!hwgroup->busy) { | ||
| 1245 | hwgroup->busy = 1; /* paranoia */ | ||
| 1246 | printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); | ||
| 1247 | } | ||
| 1248 | hwgroup->handler = NULL; | 1134 | hwgroup->handler = NULL; |
| 1249 | hwgroup->req_gen++; | 1135 | hwgroup->req_gen++; |
| 1250 | del_timer(&hwgroup->timer); | 1136 | del_timer(&hwgroup->timer); |
| @@ -1267,20 +1153,22 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
| 1267 | * same irq as is currently being serviced here, and Linux | 1153 | * same irq as is currently being serviced here, and Linux |
| 1268 | * won't allow another of the same (on any CPU) until we return. | 1154 | * won't allow another of the same (on any CPU) until we return. |
| 1269 | */ | 1155 | */ |
| 1270 | drive->service_time = jiffies - drive->service_start; | ||
| 1271 | if (startstop == ide_stopped) { | 1156 | if (startstop == ide_stopped) { |
| 1272 | if (hwgroup->handler == NULL) { /* paranoia */ | 1157 | if (hwgroup->handler == NULL) { /* paranoia */ |
| 1273 | hwgroup->busy = 0; | 1158 | ide_unlock_hwgroup(hwgroup); |
| 1274 | ide_do_request(hwgroup, hwif->irq); | 1159 | plug_device = 1; |
| 1275 | } else { | 1160 | } else |
| 1276 | printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler " | 1161 | printk(KERN_ERR "%s: %s: huh? expected NULL handler " |
| 1277 | "on exit\n", drive->name); | 1162 | "on exit\n", __func__, drive->name); |
| 1278 | } | ||
| 1279 | } | 1163 | } |
| 1280 | out_handled: | 1164 | out_handled: |
| 1281 | irq_ret = IRQ_HANDLED; | 1165 | irq_ret = IRQ_HANDLED; |
| 1282 | out: | 1166 | out: |
| 1283 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1167 | spin_unlock_irqrestore(&hwgroup->lock, flags); |
| 1168 | |||
| 1169 | if (plug_device) | ||
| 1170 | ide_plug_device(drive); | ||
| 1171 | |||
| 1284 | return irq_ret; | 1172 | return irq_ret; |
| 1285 | } | 1173 | } |
| 1286 | 1174 | ||
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 28232c64c346..1be263eb9c07 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c | |||
| @@ -95,8 +95,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 95 | return -EPERM; | 95 | return -EPERM; |
| 96 | 96 | ||
| 97 | if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && | 97 | if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && |
| 98 | (drive->media != ide_tape || | 98 | (drive->media != ide_tape)) |
| 99 | (drive->dev_flags & IDE_DFLAG_SCSI))) | ||
| 100 | return -EPERM; | 99 | return -EPERM; |
| 101 | 100 | ||
| 102 | if ((arg >> IDE_NICE_DSC_OVERLAP) & 1) | 101 | if ((arg >> IDE_NICE_DSC_OVERLAP) & 1) |
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 63d01c55f865..678454ac2483 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c | |||
| @@ -16,16 +16,19 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) | |||
| 16 | spin_lock_irq(&hwgroup->lock); | 16 | spin_lock_irq(&hwgroup->lock); |
| 17 | if (drive->dev_flags & IDE_DFLAG_PARKED) { | 17 | if (drive->dev_flags & IDE_DFLAG_PARKED) { |
| 18 | int reset_timer = time_before(timeout, drive->sleep); | 18 | int reset_timer = time_before(timeout, drive->sleep); |
| 19 | int start_queue = 0; | ||
| 19 | 20 | ||
| 20 | drive->sleep = timeout; | 21 | drive->sleep = timeout; |
| 21 | wake_up_all(&ide_park_wq); | 22 | wake_up_all(&ide_park_wq); |
| 22 | if (reset_timer && hwgroup->sleeping && | 23 | if (reset_timer && del_timer(&hwgroup->timer)) |
| 23 | del_timer(&hwgroup->timer)) { | 24 | start_queue = 1; |
| 24 | hwgroup->sleeping = 0; | 25 | spin_unlock_irq(&hwgroup->lock); |
| 25 | hwgroup->busy = 0; | 26 | |
| 27 | if (start_queue) { | ||
| 28 | spin_lock_irq(q->queue_lock); | ||
| 26 | blk_start_queueing(q); | 29 | blk_start_queueing(q); |
| 30 | spin_unlock_irq(q->queue_lock); | ||
| 27 | } | 31 | } |
| 28 | spin_unlock_irq(&hwgroup->lock); | ||
| 29 | return; | 32 | return; |
| 30 | } | 33 | } |
| 31 | spin_unlock_irq(&hwgroup->lock); | 34 | spin_unlock_irq(&hwgroup->lock); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index a64ec259f3d1..c5adb7b9c5b5 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -101,6 +101,82 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) | |||
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | static void ide_classify_ata_dev(ide_drive_t *drive) | ||
| 105 | { | ||
| 106 | u16 *id = drive->id; | ||
| 107 | char *m = (char *)&id[ATA_ID_PROD]; | ||
| 108 | int is_cfa = ata_id_is_cfa(id); | ||
| 109 | |||
| 110 | /* CF devices are *not* removable in Linux definition of the term */ | ||
| 111 | if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) | ||
| 112 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 113 | |||
| 114 | drive->media = ide_disk; | ||
| 115 | |||
| 116 | if (!ata_id_has_unload(drive->id)) | ||
| 117 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; | ||
| 118 | |||
| 119 | printk(KERN_INFO "%s: %s, %s DISK drive\n", drive->name, m, | ||
| 120 | is_cfa ? "CFA" : "ATA"); | ||
| 121 | } | ||
| 122 | |||
| 123 | static void ide_classify_atapi_dev(ide_drive_t *drive) | ||
| 124 | { | ||
| 125 | u16 *id = drive->id; | ||
| 126 | char *m = (char *)&id[ATA_ID_PROD]; | ||
| 127 | u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f; | ||
| 128 | |||
| 129 | printk(KERN_INFO "%s: %s, ATAPI ", drive->name, m); | ||
| 130 | switch (type) { | ||
| 131 | case ide_floppy: | ||
| 132 | if (!strstr(m, "CD-ROM")) { | ||
| 133 | if (!strstr(m, "oppy") && | ||
| 134 | !strstr(m, "poyp") && | ||
| 135 | !strstr(m, "ZIP")) | ||
| 136 | printk(KERN_CONT "cdrom or floppy?, assuming "); | ||
| 137 | if (drive->media != ide_cdrom) { | ||
| 138 | printk(KERN_CONT "FLOPPY"); | ||
| 139 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | /* Early cdrom models used zero */ | ||
| 144 | type = ide_cdrom; | ||
| 145 | case ide_cdrom: | ||
| 146 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 147 | #ifdef CONFIG_PPC | ||
| 148 | /* kludge for Apple PowerBook internal zip */ | ||
| 149 | if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { | ||
| 150 | printk(KERN_CONT "FLOPPY"); | ||
| 151 | type = ide_floppy; | ||
| 152 | break; | ||
| 153 | } | ||
| 154 | #endif | ||
| 155 | printk(KERN_CONT "CD/DVD-ROM"); | ||
| 156 | break; | ||
| 157 | case ide_tape: | ||
| 158 | printk(KERN_CONT "TAPE"); | ||
| 159 | break; | ||
| 160 | case ide_optical: | ||
| 161 | printk(KERN_CONT "OPTICAL"); | ||
| 162 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 163 | break; | ||
| 164 | default: | ||
| 165 | printk(KERN_CONT "UNKNOWN (type %d)", type); | ||
| 166 | break; | ||
| 167 | } | ||
| 168 | |||
| 169 | printk(KERN_CONT " drive\n"); | ||
| 170 | drive->media = type; | ||
| 171 | /* an ATAPI device ignores DRDY */ | ||
| 172 | drive->ready_stat = 0; | ||
| 173 | if (ata_id_cdb_intr(id)) | ||
| 174 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; | ||
| 175 | drive->dev_flags |= IDE_DFLAG_DOORLOCKING; | ||
| 176 | /* we don't do head unloading on ATAPI devices */ | ||
| 177 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; | ||
| 178 | } | ||
| 179 | |||
| 104 | /** | 180 | /** |
| 105 | * do_identify - identify a drive | 181 | * do_identify - identify a drive |
| 106 | * @drive: drive to identify | 182 | * @drive: drive to identify |
| @@ -117,7 +193,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd) | |||
| 117 | u16 *id = drive->id; | 193 | u16 *id = drive->id; |
| 118 | char *m = (char *)&id[ATA_ID_PROD]; | 194 | char *m = (char *)&id[ATA_ID_PROD]; |
| 119 | unsigned long flags; | 195 | unsigned long flags; |
| 120 | int bswap = 1, is_cfa; | 196 | int bswap = 1; |
| 121 | 197 | ||
| 122 | /* local CPU only; some systems need this */ | 198 | /* local CPU only; some systems need this */ |
| 123 | local_irq_save(flags); | 199 | local_irq_save(flags); |
| @@ -154,91 +230,23 @@ static void do_identify(ide_drive_t *drive, u8 cmd) | |||
| 154 | if (strstr(m, "E X A B Y T E N E S T")) | 230 | if (strstr(m, "E X A B Y T E N E S T")) |
| 155 | goto err_misc; | 231 | goto err_misc; |
| 156 | 232 | ||
| 157 | printk(KERN_INFO "%s: %s, ", drive->name, m); | ||
| 158 | |||
| 159 | drive->dev_flags |= IDE_DFLAG_PRESENT; | 233 | drive->dev_flags |= IDE_DFLAG_PRESENT; |
| 160 | drive->dev_flags &= ~IDE_DFLAG_DEAD; | 234 | drive->dev_flags &= ~IDE_DFLAG_DEAD; |
| 161 | 235 | ||
| 162 | /* | 236 | /* |
| 163 | * Check for an ATAPI device | 237 | * Check for an ATAPI device |
| 164 | */ | 238 | */ |
| 165 | if (cmd == ATA_CMD_ID_ATAPI) { | 239 | if (cmd == ATA_CMD_ID_ATAPI) |
| 166 | u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f; | 240 | ide_classify_atapi_dev(drive); |
| 167 | 241 | else | |
| 168 | printk(KERN_CONT "ATAPI "); | ||
| 169 | switch (type) { | ||
| 170 | case ide_floppy: | ||
| 171 | if (!strstr(m, "CD-ROM")) { | ||
| 172 | if (!strstr(m, "oppy") && | ||
| 173 | !strstr(m, "poyp") && | ||
| 174 | !strstr(m, "ZIP")) | ||
| 175 | printk(KERN_CONT "cdrom or floppy?, assuming "); | ||
| 176 | if (drive->media != ide_cdrom) { | ||
| 177 | printk(KERN_CONT "FLOPPY"); | ||
| 178 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | /* Early cdrom models used zero */ | ||
| 183 | type = ide_cdrom; | ||
| 184 | case ide_cdrom: | ||
| 185 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 186 | #ifdef CONFIG_PPC | ||
| 187 | /* kludge for Apple PowerBook internal zip */ | ||
| 188 | if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { | ||
| 189 | printk(KERN_CONT "FLOPPY"); | ||
| 190 | type = ide_floppy; | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | #endif | ||
| 194 | printk(KERN_CONT "CD/DVD-ROM"); | ||
| 195 | break; | ||
| 196 | case ide_tape: | ||
| 197 | printk(KERN_CONT "TAPE"); | ||
| 198 | break; | ||
| 199 | case ide_optical: | ||
| 200 | printk(KERN_CONT "OPTICAL"); | ||
| 201 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 202 | break; | ||
| 203 | default: | ||
| 204 | printk(KERN_CONT "UNKNOWN (type %d)", type); | ||
| 205 | break; | ||
| 206 | } | ||
| 207 | printk(KERN_CONT " drive\n"); | ||
| 208 | drive->media = type; | ||
| 209 | /* an ATAPI device ignores DRDY */ | ||
| 210 | drive->ready_stat = 0; | ||
| 211 | if (ata_id_cdb_intr(id)) | ||
| 212 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; | ||
| 213 | drive->dev_flags |= IDE_DFLAG_DOORLOCKING; | ||
| 214 | /* we don't do head unloading on ATAPI devices */ | ||
| 215 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; | ||
| 216 | return; | ||
| 217 | } | ||
| 218 | |||
| 219 | /* | 242 | /* |
| 220 | * Not an ATAPI device: looks like a "regular" hard disk | 243 | * Not an ATAPI device: looks like a "regular" hard disk |
| 221 | */ | 244 | */ |
| 222 | 245 | ide_classify_ata_dev(drive); | |
| 223 | is_cfa = ata_id_is_cfa(id); | ||
| 224 | |||
| 225 | /* CF devices are *not* removable in Linux definition of the term */ | ||
| 226 | if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) | ||
| 227 | drive->dev_flags |= IDE_DFLAG_REMOVABLE; | ||
| 228 | |||
| 229 | drive->media = ide_disk; | ||
| 230 | |||
| 231 | if (!ata_id_has_unload(drive->id)) | ||
| 232 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; | ||
| 233 | |||
| 234 | printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA"); | ||
| 235 | |||
| 236 | return; | 246 | return; |
| 237 | |||
| 238 | err_misc: | 247 | err_misc: |
| 239 | kfree(id); | 248 | kfree(id); |
| 240 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; | 249 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
| 241 | return; | ||
| 242 | } | 250 | } |
| 243 | 251 | ||
| 244 | /** | 252 | /** |
| @@ -641,14 +649,9 @@ static int ide_register_port(ide_hwif_t *hwif) | |||
| 641 | /* register with global device tree */ | 649 | /* register with global device tree */ |
| 642 | dev_set_name(&hwif->gendev, hwif->name); | 650 | dev_set_name(&hwif->gendev, hwif->name); |
| 643 | hwif->gendev.driver_data = hwif; | 651 | hwif->gendev.driver_data = hwif; |
| 644 | if (hwif->gendev.parent == NULL) { | 652 | hwif->gendev.parent = hwif->dev; |
| 645 | if (hwif->dev) | ||
| 646 | hwif->gendev.parent = hwif->dev; | ||
| 647 | else | ||
| 648 | /* Would like to do = &device_legacy */ | ||
| 649 | hwif->gendev.parent = NULL; | ||
| 650 | } | ||
| 651 | hwif->gendev.release = hwif_release_dev; | 653 | hwif->gendev.release = hwif_release_dev; |
| 654 | |||
| 652 | ret = device_register(&hwif->gendev); | 655 | ret = device_register(&hwif->gendev); |
| 653 | if (ret < 0) { | 656 | if (ret < 0) { |
| 654 | printk(KERN_WARNING "IDE: %s: device_register error: %d\n", | 657 | printk(KERN_WARNING "IDE: %s: device_register error: %d\n", |
| @@ -878,8 +881,7 @@ static int ide_init_queue(ide_drive_t *drive) | |||
| 878 | * do not. | 881 | * do not. |
| 879 | */ | 882 | */ |
| 880 | 883 | ||
| 881 | q = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock, | 884 | q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif)); |
| 882 | hwif_to_node(hwif)); | ||
| 883 | if (!q) | 885 | if (!q) |
| 884 | return 1; | 886 | return 1; |
| 885 | 887 | ||
| @@ -1139,8 +1141,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) | |||
| 1139 | 1141 | ||
| 1140 | if (drive->media == ide_disk) | 1142 | if (drive->media == ide_disk) |
| 1141 | request_module("ide-disk"); | 1143 | request_module("ide-disk"); |
| 1142 | if (drive->dev_flags & IDE_DFLAG_SCSI) | ||
| 1143 | request_module("ide-scsi"); | ||
| 1144 | if (drive->media == ide_cdrom || drive->media == ide_optical) | 1144 | if (drive->media == ide_cdrom || drive->media == ide_optical) |
| 1145 | request_module("ide-cd"); | 1145 | request_module("ide-cd"); |
| 1146 | if (drive->media == ide_tape) | 1146 | if (drive->media == ide_tape) |
| @@ -1417,58 +1417,6 @@ static void ide_port_cable_detect(ide_hwif_t *hwif) | |||
| 1417 | } | 1417 | } |
| 1418 | } | 1418 | } |
| 1419 | 1419 | ||
| 1420 | static ssize_t store_delete_devices(struct device *portdev, | ||
| 1421 | struct device_attribute *attr, | ||
| 1422 | const char *buf, size_t n) | ||
| 1423 | { | ||
| 1424 | ide_hwif_t *hwif = dev_get_drvdata(portdev); | ||
| 1425 | |||
| 1426 | if (strncmp(buf, "1", n)) | ||
| 1427 | return -EINVAL; | ||
| 1428 | |||
| 1429 | ide_port_unregister_devices(hwif); | ||
| 1430 | |||
| 1431 | return n; | ||
| 1432 | }; | ||
| 1433 | |||
| 1434 | static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices); | ||
| 1435 | |||
| 1436 | static ssize_t store_scan(struct device *portdev, | ||
| 1437 | struct device_attribute *attr, | ||
| 1438 | const char *buf, size_t n) | ||
| 1439 | { | ||
| 1440 | ide_hwif_t *hwif = dev_get_drvdata(portdev); | ||
| 1441 | |||
| 1442 | if (strncmp(buf, "1", n)) | ||
| 1443 | return -EINVAL; | ||
| 1444 | |||
| 1445 | ide_port_unregister_devices(hwif); | ||
| 1446 | ide_port_scan(hwif); | ||
| 1447 | |||
| 1448 | return n; | ||
| 1449 | }; | ||
| 1450 | |||
| 1451 | static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); | ||
| 1452 | |||
| 1453 | static struct device_attribute *ide_port_attrs[] = { | ||
| 1454 | &dev_attr_delete_devices, | ||
| 1455 | &dev_attr_scan, | ||
| 1456 | NULL | ||
| 1457 | }; | ||
| 1458 | |||
| 1459 | static int ide_sysfs_register_port(ide_hwif_t *hwif) | ||
| 1460 | { | ||
| 1461 | int i, uninitialized_var(rc); | ||
| 1462 | |||
| 1463 | for (i = 0; ide_port_attrs[i]; i++) { | ||
| 1464 | rc = device_create_file(hwif->portdev, ide_port_attrs[i]); | ||
| 1465 | if (rc) | ||
| 1466 | break; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | return rc; | ||
| 1470 | } | ||
| 1471 | |||
| 1472 | static unsigned int ide_indexes; | 1420 | static unsigned int ide_indexes; |
| 1473 | 1421 | ||
| 1474 | /** | 1422 | /** |
| @@ -1655,9 +1603,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
| 1655 | if (hwif == NULL) | 1603 | if (hwif == NULL) |
| 1656 | continue; | 1604 | continue; |
| 1657 | 1605 | ||
| 1658 | if (hwif->chipset == ide_unknown) | ||
| 1659 | hwif->chipset = ide_generic; | ||
| 1660 | |||
| 1661 | if (hwif->present) | 1606 | if (hwif->present) |
| 1662 | hwif_register_devices(hwif); | 1607 | hwif_register_devices(hwif); |
| 1663 | } | 1608 | } |
diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.c new file mode 100644 index 000000000000..883ffacaf45a --- /dev/null +++ b/drivers/ide/ide-sysfs.c | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/ide.h> | ||
| 3 | |||
| 4 | char *ide_media_string(ide_drive_t *drive) | ||
| 5 | { | ||
| 6 | switch (drive->media) { | ||
| 7 | case ide_disk: | ||
| 8 | return "disk"; | ||
| 9 | case ide_cdrom: | ||
| 10 | return "cdrom"; | ||
| 11 | case ide_tape: | ||
| 12 | return "tape"; | ||
| 13 | case ide_floppy: | ||
| 14 | return "floppy"; | ||
| 15 | case ide_optical: | ||
| 16 | return "optical"; | ||
| 17 | default: | ||
| 18 | return "UNKNOWN"; | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | static ssize_t media_show(struct device *dev, struct device_attribute *attr, | ||
| 23 | char *buf) | ||
| 24 | { | ||
| 25 | ide_drive_t *drive = to_ide_device(dev); | ||
| 26 | return sprintf(buf, "%s\n", ide_media_string(drive)); | ||
| 27 | } | ||
| 28 | |||
| 29 | static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, | ||
| 30 | char *buf) | ||
| 31 | { | ||
| 32 | ide_drive_t *drive = to_ide_device(dev); | ||
| 33 | return sprintf(buf, "%s\n", drive->name); | ||
| 34 | } | ||
| 35 | |||
| 36 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | ||
| 37 | char *buf) | ||
| 38 | { | ||
| 39 | ide_drive_t *drive = to_ide_device(dev); | ||
| 40 | return sprintf(buf, "ide:m-%s\n", ide_media_string(drive)); | ||
| 41 | } | ||
| 42 | |||
| 43 | static ssize_t model_show(struct device *dev, struct device_attribute *attr, | ||
| 44 | char *buf) | ||
| 45 | { | ||
| 46 | ide_drive_t *drive = to_ide_device(dev); | ||
| 47 | return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]); | ||
| 48 | } | ||
| 49 | |||
| 50 | static ssize_t firmware_show(struct device *dev, struct device_attribute *attr, | ||
| 51 | char *buf) | ||
| 52 | { | ||
| 53 | ide_drive_t *drive = to_ide_device(dev); | ||
| 54 | return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]); | ||
| 55 | } | ||
| 56 | |||
| 57 | static ssize_t serial_show(struct device *dev, struct device_attribute *attr, | ||
| 58 | char *buf) | ||
| 59 | { | ||
| 60 | ide_drive_t *drive = to_ide_device(dev); | ||
| 61 | return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]); | ||
| 62 | } | ||
| 63 | |||
| 64 | struct device_attribute ide_dev_attrs[] = { | ||
| 65 | __ATTR_RO(media), | ||
| 66 | __ATTR_RO(drivename), | ||
| 67 | __ATTR_RO(modalias), | ||
| 68 | __ATTR_RO(model), | ||
| 69 | __ATTR_RO(firmware), | ||
| 70 | __ATTR(serial, 0400, serial_show, NULL), | ||
| 71 | __ATTR(unload_heads, 0644, ide_park_show, ide_park_store), | ||
| 72 | __ATTR_NULL | ||
| 73 | }; | ||
| 74 | |||
| 75 | static ssize_t store_delete_devices(struct device *portdev, | ||
| 76 | struct device_attribute *attr, | ||
| 77 | const char *buf, size_t n) | ||
| 78 | { | ||
| 79 | ide_hwif_t *hwif = dev_get_drvdata(portdev); | ||
| 80 | |||
| 81 | if (strncmp(buf, "1", n)) | ||
| 82 | return -EINVAL; | ||
| 83 | |||
| 84 | ide_port_unregister_devices(hwif); | ||
| 85 | |||
| 86 | return n; | ||
| 87 | }; | ||
| 88 | |||
| 89 | static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices); | ||
| 90 | |||
| 91 | static ssize_t store_scan(struct device *portdev, | ||
| 92 | struct device_attribute *attr, | ||
| 93 | const char *buf, size_t n) | ||
| 94 | { | ||
| 95 | ide_hwif_t *hwif = dev_get_drvdata(portdev); | ||
| 96 | |||
| 97 | if (strncmp(buf, "1", n)) | ||
| 98 | return -EINVAL; | ||
| 99 | |||
| 100 | ide_port_unregister_devices(hwif); | ||
| 101 | ide_port_scan(hwif); | ||
| 102 | |||
| 103 | return n; | ||
| 104 | }; | ||
| 105 | |||
| 106 | static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); | ||
| 107 | |||
| 108 | static struct device_attribute *ide_port_attrs[] = { | ||
| 109 | &dev_attr_delete_devices, | ||
| 110 | &dev_attr_scan, | ||
| 111 | NULL | ||
| 112 | }; | ||
| 113 | |||
| 114 | int ide_sysfs_register_port(ide_hwif_t *hwif) | ||
| 115 | { | ||
| 116 | int i, uninitialized_var(rc); | ||
| 117 | |||
| 118 | for (i = 0; ide_port_attrs[i]; i++) { | ||
| 119 | rc = device_create_file(hwif->portdev, ide_port_attrs[i]); | ||
| 120 | if (rc) | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | |||
| 124 | return rc; | ||
| 125 | } | ||
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a2d470eb2b55..5d2aa22cd6e4 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
| @@ -694,7 +694,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, | |||
| 694 | 694 | ||
| 695 | pc->retries++; | 695 | pc->retries++; |
| 696 | 696 | ||
| 697 | return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL); | 697 | return ide_issue_pc(drive); |
| 698 | } | 698 | } |
| 699 | 699 | ||
| 700 | /* A mode sense command is used to "sense" tape parameters. */ | 700 | /* A mode sense command is used to "sense" tape parameters. */ |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index f0f09f702e9c..46a2d4ca812b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -440,81 +440,13 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv) | |||
| 440 | return 1; | 440 | return 1; |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | static char *media_string(ide_drive_t *drive) | ||
| 444 | { | ||
| 445 | switch (drive->media) { | ||
| 446 | case ide_disk: | ||
| 447 | return "disk"; | ||
| 448 | case ide_cdrom: | ||
| 449 | return "cdrom"; | ||
| 450 | case ide_tape: | ||
| 451 | return "tape"; | ||
| 452 | case ide_floppy: | ||
| 453 | return "floppy"; | ||
| 454 | case ide_optical: | ||
| 455 | return "optical"; | ||
| 456 | default: | ||
| 457 | return "UNKNOWN"; | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 462 | { | ||
| 463 | ide_drive_t *drive = to_ide_device(dev); | ||
| 464 | return sprintf(buf, "%s\n", media_string(drive)); | ||
| 465 | } | ||
| 466 | |||
| 467 | static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 468 | { | ||
| 469 | ide_drive_t *drive = to_ide_device(dev); | ||
| 470 | return sprintf(buf, "%s\n", drive->name); | ||
| 471 | } | ||
| 472 | |||
| 473 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 474 | { | ||
| 475 | ide_drive_t *drive = to_ide_device(dev); | ||
| 476 | return sprintf(buf, "ide:m-%s\n", media_string(drive)); | ||
| 477 | } | ||
| 478 | |||
| 479 | static ssize_t model_show(struct device *dev, struct device_attribute *attr, | ||
| 480 | char *buf) | ||
| 481 | { | ||
| 482 | ide_drive_t *drive = to_ide_device(dev); | ||
| 483 | return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]); | ||
| 484 | } | ||
| 485 | |||
| 486 | static ssize_t firmware_show(struct device *dev, struct device_attribute *attr, | ||
| 487 | char *buf) | ||
| 488 | { | ||
| 489 | ide_drive_t *drive = to_ide_device(dev); | ||
| 490 | return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]); | ||
| 491 | } | ||
| 492 | |||
| 493 | static ssize_t serial_show(struct device *dev, struct device_attribute *attr, | ||
| 494 | char *buf) | ||
| 495 | { | ||
| 496 | ide_drive_t *drive = to_ide_device(dev); | ||
| 497 | return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]); | ||
| 498 | } | ||
| 499 | |||
| 500 | static struct device_attribute ide_dev_attrs[] = { | ||
| 501 | __ATTR_RO(media), | ||
| 502 | __ATTR_RO(drivename), | ||
| 503 | __ATTR_RO(modalias), | ||
| 504 | __ATTR_RO(model), | ||
| 505 | __ATTR_RO(firmware), | ||
| 506 | __ATTR(serial, 0400, serial_show, NULL), | ||
| 507 | __ATTR(unload_heads, 0644, ide_park_show, ide_park_store), | ||
| 508 | __ATTR_NULL | ||
| 509 | }; | ||
| 510 | |||
| 511 | static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) | 443 | static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) |
| 512 | { | 444 | { |
| 513 | ide_drive_t *drive = to_ide_device(dev); | 445 | ide_drive_t *drive = to_ide_device(dev); |
| 514 | 446 | ||
| 515 | add_uevent_var(env, "MEDIA=%s", media_string(drive)); | 447 | add_uevent_var(env, "MEDIA=%s", ide_media_string(drive)); |
| 516 | add_uevent_var(env, "DRIVENAME=%s", drive->name); | 448 | add_uevent_var(env, "DRIVENAME=%s", drive->name); |
| 517 | add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive)); | 449 | add_uevent_var(env, "MODALIAS=ide:m-%s", ide_media_string(drive)); |
| 518 | return 0; | 450 | return 0; |
| 519 | } | 451 | } |
| 520 | 452 | ||
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 13b63e7fa353..b4ef218072cd 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c | |||
| @@ -216,16 +216,17 @@ static const struct ide_tp_ops tx4938ide_tp_ops = { | |||
| 216 | #endif /* __BIG_ENDIAN */ | 216 | #endif /* __BIG_ENDIAN */ |
| 217 | 217 | ||
| 218 | static const struct ide_port_ops tx4938ide_port_ops = { | 218 | static const struct ide_port_ops tx4938ide_port_ops = { |
| 219 | .set_pio_mode = tx4938ide_set_pio_mode, | 219 | .set_pio_mode = tx4938ide_set_pio_mode, |
| 220 | }; | 220 | }; |
| 221 | 221 | ||
| 222 | static const struct ide_port_info tx4938ide_port_info __initdata = { | 222 | static const struct ide_port_info tx4938ide_port_info __initdata = { |
| 223 | .port_ops = &tx4938ide_port_ops, | 223 | .port_ops = &tx4938ide_port_ops, |
| 224 | #ifdef __BIG_ENDIAN | 224 | #ifdef __BIG_ENDIAN |
| 225 | .tp_ops = &tx4938ide_tp_ops, | 225 | .tp_ops = &tx4938ide_tp_ops, |
| 226 | #endif | 226 | #endif |
| 227 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, | 227 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, |
| 228 | .pio_mask = ATA_PIO5, | 228 | .pio_mask = ATA_PIO5, |
| 229 | .chipset = ide_generic, | ||
| 229 | }; | 230 | }; |
| 230 | 231 | ||
| 231 | static int __init tx4938ide_probe(struct platform_device *pdev) | 232 | static int __init tx4938ide_probe(struct platform_device *pdev) |
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 97cd9e0f66f6..4a8c5a21bd4c 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c | |||
| @@ -623,33 +623,34 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { | |||
| 623 | #endif /* __LITTLE_ENDIAN */ | 623 | #endif /* __LITTLE_ENDIAN */ |
| 624 | 624 | ||
| 625 | static const struct ide_port_ops tx4939ide_port_ops = { | 625 | static const struct ide_port_ops tx4939ide_port_ops = { |
| 626 | .set_pio_mode = tx4939ide_set_pio_mode, | 626 | .set_pio_mode = tx4939ide_set_pio_mode, |
| 627 | .set_dma_mode = tx4939ide_set_dma_mode, | 627 | .set_dma_mode = tx4939ide_set_dma_mode, |
| 628 | .clear_irq = tx4939ide_clear_irq, | 628 | .clear_irq = tx4939ide_clear_irq, |
| 629 | .cable_detect = tx4939ide_cable_detect, | 629 | .cable_detect = tx4939ide_cable_detect, |
| 630 | }; | 630 | }; |
| 631 | 631 | ||
| 632 | static const struct ide_dma_ops tx4939ide_dma_ops = { | 632 | static const struct ide_dma_ops tx4939ide_dma_ops = { |
| 633 | .dma_host_set = tx4939ide_dma_host_set, | 633 | .dma_host_set = tx4939ide_dma_host_set, |
| 634 | .dma_setup = tx4939ide_dma_setup, | 634 | .dma_setup = tx4939ide_dma_setup, |
| 635 | .dma_exec_cmd = ide_dma_exec_cmd, | 635 | .dma_exec_cmd = ide_dma_exec_cmd, |
| 636 | .dma_start = ide_dma_start, | 636 | .dma_start = ide_dma_start, |
| 637 | .dma_end = tx4939ide_dma_end, | 637 | .dma_end = tx4939ide_dma_end, |
| 638 | .dma_test_irq = tx4939ide_dma_test_irq, | 638 | .dma_test_irq = tx4939ide_dma_test_irq, |
| 639 | .dma_lost_irq = ide_dma_lost_irq, | 639 | .dma_lost_irq = ide_dma_lost_irq, |
| 640 | .dma_timeout = ide_dma_timeout, | 640 | .dma_timeout = ide_dma_timeout, |
| 641 | }; | 641 | }; |
| 642 | 642 | ||
| 643 | static const struct ide_port_info tx4939ide_port_info __initdata = { | 643 | static const struct ide_port_info tx4939ide_port_info __initdata = { |
| 644 | .init_hwif = tx4939ide_init_hwif, | 644 | .init_hwif = tx4939ide_init_hwif, |
| 645 | .init_dma = tx4939ide_init_dma, | 645 | .init_dma = tx4939ide_init_dma, |
| 646 | .port_ops = &tx4939ide_port_ops, | 646 | .port_ops = &tx4939ide_port_ops, |
| 647 | .dma_ops = &tx4939ide_dma_ops, | 647 | .dma_ops = &tx4939ide_dma_ops, |
| 648 | .tp_ops = &tx4939ide_tp_ops, | 648 | .tp_ops = &tx4939ide_tp_ops, |
| 649 | .host_flags = IDE_HFLAG_MMIO, | 649 | .host_flags = IDE_HFLAG_MMIO, |
| 650 | .pio_mask = ATA_PIO4, | 650 | .pio_mask = ATA_PIO4, |
| 651 | .mwdma_mask = ATA_MWDMA2, | 651 | .mwdma_mask = ATA_MWDMA2, |
| 652 | .udma_mask = ATA_UDMA5, | 652 | .udma_mask = ATA_UDMA5, |
| 653 | .chipset = ide_generic, | ||
| 653 | }; | 654 | }; |
| 654 | 655 | ||
| 655 | static int __init tx4939ide_probe(struct platform_device *pdev) | 656 | static int __init tx4939ide_probe(struct platform_device *pdev) |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 152d4aa9354f..b7322976d2b7 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
| @@ -21,7 +21,7 @@ config SCSI | |||
| 21 | You also need to say Y here if you have a device which speaks | 21 | You also need to say Y here if you have a device which speaks |
| 22 | the SCSI protocol. Examples of this include the parallel port | 22 | the SCSI protocol. Examples of this include the parallel port |
| 23 | version of the IOMEGA ZIP drive, USB storage devices, Fibre | 23 | version of the IOMEGA ZIP drive, USB storage devices, Fibre |
| 24 | Channel, FireWire storage and the IDE-SCSI emulation driver. | 24 | Channel, and FireWire storage. |
| 25 | 25 | ||
| 26 | To compile this driver as a module, choose M here and read | 26 | To compile this driver as a module, choose M here and read |
| 27 | <file:Documentation/scsi/scsi.txt>. | 27 | <file:Documentation/scsi/scsi.txt>. |
| @@ -101,9 +101,9 @@ config CHR_DEV_OSST | |||
| 101 | ---help--- | 101 | ---help--- |
| 102 | The OnStream SC-x0 SCSI tape drives cannot be driven by the | 102 | The OnStream SC-x0 SCSI tape drives cannot be driven by the |
| 103 | standard st driver, but instead need this special osst driver and | 103 | standard st driver, but instead need this special osst driver and |
| 104 | use the /dev/osstX char device nodes (major 206). Via usb-storage | 104 | use the /dev/osstX char device nodes (major 206). Via usb-storage, |
| 105 | and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives | 105 | you may be able to drive the USB-x0 and DI-x0 drives as well. |
| 106 | as well. Note that there is also a second generation of OnStream | 106 | Note that there is also a second generation of OnStream |
| 107 | tape drives (ADR-x0) that supports the standard SCSI-2 commands for | 107 | tape drives (ADR-x0) that supports the standard SCSI-2 commands for |
| 108 | tapes (QIC-157) and can be driven by the standard driver st. | 108 | tapes (QIC-157) and can be driven by the standard driver st. |
| 109 | For more information, you may have a look at the SCSI-HOWTO | 109 | For more information, you may have a look at the SCSI-HOWTO |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 1410697257cb..7461eb09a031 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
| @@ -105,7 +105,6 @@ obj-$(CONFIG_SCSI_GDTH) += gdth.o | |||
| 105 | obj-$(CONFIG_SCSI_INITIO) += initio.o | 105 | obj-$(CONFIG_SCSI_INITIO) += initio.o |
| 106 | obj-$(CONFIG_SCSI_INIA100) += a100u2w.o | 106 | obj-$(CONFIG_SCSI_INIA100) += a100u2w.o |
| 107 | obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o | 107 | obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o |
| 108 | obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o | ||
| 109 | obj-$(CONFIG_SCSI_MESH) += mesh.o | 108 | obj-$(CONFIG_SCSI_MESH) += mesh.o |
| 110 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o | 109 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o |
| 111 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o | 110 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c deleted file mode 100644 index c24140aff8e7..000000000000 --- a/drivers/scsi/ide-scsi.c +++ /dev/null | |||
| @@ -1,840 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il> | ||
| 3 | * Copyright (C) 2004-2005 Bartlomiej Zolnierkiewicz | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Emulation of a SCSI host adapter for IDE ATAPI devices. | ||
| 8 | * | ||
| 9 | * With this driver, one can use the Linux SCSI drivers instead of the | ||
| 10 | * native IDE ATAPI drivers. | ||
| 11 | * | ||
| 12 | * Ver 0.1 Dec 3 96 Initial version. | ||
| 13 | * Ver 0.2 Jan 26 97 Fixed bug in cleanup_module() and added emulation | ||
| 14 | * of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks | ||
| 15 | * to Janos Farkas for pointing this out. | ||
| 16 | * Avoid using bitfields in structures for m68k. | ||
| 17 | * Added Scatter/Gather and DMA support. | ||
| 18 | * Ver 0.4 Dec 7 97 Add support for ATAPI PD/CD drives. | ||
| 19 | * Use variable timeout for each command. | ||
| 20 | * Ver 0.5 Jan 2 98 Fix previous PD/CD support. | ||
| 21 | * Allow disabling of SCSI-6 to SCSI-10 transformation. | ||
| 22 | * Ver 0.6 Jan 27 98 Allow disabling of SCSI command translation layer | ||
| 23 | * for access through /dev/sg. | ||
| 24 | * Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation. | ||
| 25 | * Ver 0.7 Dec 04 98 Ignore commands where lun != 0 to avoid multiple | ||
| 26 | * detection of devices with CONFIG_SCSI_MULTI_LUN | ||
| 27 | * Ver 0.8 Feb 05 99 Optical media need translation too. Reverse 0.7. | ||
| 28 | * Ver 0.9 Jul 04 99 Fix a bug in SG_SET_TRANSFORM. | ||
| 29 | * Ver 0.91 Jun 10 02 Fix "off by one" error in transforms | ||
| 30 | * Ver 0.92 Dec 31 02 Implement new SCSI mid level API | ||
| 31 | */ | ||
| 32 | |||
| 33 | #define IDESCSI_VERSION "0.92" | ||
| 34 | |||
| 35 | #include <linux/module.h> | ||
| 36 | #include <linux/types.h> | ||
| 37 | #include <linux/string.h> | ||
| 38 | #include <linux/kernel.h> | ||
| 39 | #include <linux/mm.h> | ||
| 40 | #include <linux/ioport.h> | ||
| 41 | #include <linux/blkdev.h> | ||
| 42 | #include <linux/errno.h> | ||
| 43 | #include <linux/slab.h> | ||
| 44 | #include <linux/ide.h> | ||
| 45 | #include <linux/scatterlist.h> | ||
| 46 | #include <linux/delay.h> | ||
| 47 | #include <linux/mutex.h> | ||
| 48 | #include <linux/bitops.h> | ||
| 49 | |||
| 50 | #include <asm/io.h> | ||
| 51 | #include <asm/uaccess.h> | ||
| 52 | |||
| 53 | #include <scsi/scsi.h> | ||
| 54 | #include <scsi/scsi_cmnd.h> | ||
| 55 | #include <scsi/scsi_device.h> | ||
| 56 | #include <scsi/scsi_host.h> | ||
| 57 | #include <scsi/scsi_tcq.h> | ||
| 58 | #include <scsi/sg.h> | ||
| 59 | |||
| 60 | #define IDESCSI_DEBUG_LOG 0 | ||
| 61 | |||
| 62 | #if IDESCSI_DEBUG_LOG | ||
| 63 | #define debug_log(fmt, args...) \ | ||
| 64 | printk(KERN_INFO "ide-scsi: " fmt, ## args) | ||
| 65 | #else | ||
| 66 | #define debug_log(fmt, args...) do {} while (0) | ||
| 67 | #endif | ||
| 68 | |||
| 69 | /* | ||
| 70 | * SCSI command transformation layer | ||
| 71 | */ | ||
| 72 | #define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */ | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Log flags | ||
| 76 | */ | ||
| 77 | #define IDESCSI_LOG_CMD 0 /* Log SCSI commands */ | ||
| 78 | |||
| 79 | typedef struct ide_scsi_obj { | ||
| 80 | ide_drive_t *drive; | ||
| 81 | ide_driver_t *driver; | ||
| 82 | struct gendisk *disk; | ||
| 83 | struct Scsi_Host *host; | ||
| 84 | |||
| 85 | unsigned long transform; /* SCSI cmd translation layer */ | ||
| 86 | unsigned long log; /* log flags */ | ||
| 87 | } idescsi_scsi_t; | ||
| 88 | |||
| 89 | static DEFINE_MUTEX(idescsi_ref_mutex); | ||
| 90 | /* Set by module param to skip cd */ | ||
| 91 | static int idescsi_nocd; | ||
| 92 | |||
| 93 | #define ide_scsi_g(disk) \ | ||
| 94 | container_of((disk)->private_data, struct ide_scsi_obj, driver) | ||
| 95 | |||
| 96 | static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk) | ||
| 97 | { | ||
| 98 | struct ide_scsi_obj *scsi = NULL; | ||
| 99 | |||
| 100 | mutex_lock(&idescsi_ref_mutex); | ||
| 101 | scsi = ide_scsi_g(disk); | ||
| 102 | if (scsi) { | ||
| 103 | if (ide_device_get(scsi->drive)) | ||
| 104 | scsi = NULL; | ||
| 105 | else | ||
| 106 | scsi_host_get(scsi->host); | ||
| 107 | } | ||
| 108 | mutex_unlock(&idescsi_ref_mutex); | ||
| 109 | return scsi; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void ide_scsi_put(struct ide_scsi_obj *scsi) | ||
| 113 | { | ||
| 114 | ide_drive_t *drive = scsi->drive; | ||
| 115 | |||
| 116 | mutex_lock(&idescsi_ref_mutex); | ||
| 117 | scsi_host_put(scsi->host); | ||
| 118 | ide_device_put(drive); | ||
| 119 | mutex_unlock(&idescsi_ref_mutex); | ||
| 120 | } | ||
| 121 | |||
| 122 | static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host) | ||
| 123 | { | ||
| 124 | return (idescsi_scsi_t*) (&host[1]); | ||
| 125 | } | ||
| 126 | |||
| 127 | static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) | ||
| 128 | { | ||
| 129 | return scsihost_to_idescsi(ide_drive->driver_data); | ||
| 130 | } | ||
| 131 | |||
| 132 | static void ide_scsi_hex_dump(u8 *data, int len) | ||
| 133 | { | ||
| 134 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); | ||
| 135 | } | ||
| 136 | |||
| 137 | static int idescsi_end_request(ide_drive_t *, int, int); | ||
| 138 | |||
| 139 | static void ide_scsi_callback(ide_drive_t *drive, int dsc) | ||
| 140 | { | ||
| 141 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | ||
| 142 | struct ide_atapi_pc *pc = drive->pc; | ||
| 143 | |||
| 144 | if (pc->flags & PC_FLAG_TIMEDOUT) | ||
| 145 | debug_log("%s: got timed out packet %lu at %lu\n", __func__, | ||
| 146 | pc->scsi_cmd->serial_number, jiffies); | ||
| 147 | /* end this request now - scsi should retry it*/ | ||
| 148 | else if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | ||
| 149 | printk(KERN_INFO "Packet command completed, %d bytes" | ||
| 150 | " transferred\n", pc->xferred); | ||
| 151 | |||
| 152 | idescsi_end_request(drive, 1, 0); | ||
| 153 | } | ||
| 154 | |||
| 155 | static int idescsi_check_condition(ide_drive_t *drive, | ||
| 156 | struct request *failed_cmd) | ||
| 157 | { | ||
| 158 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | ||
| 159 | struct ide_atapi_pc *pc; | ||
| 160 | struct request *rq; | ||
| 161 | u8 *buf; | ||
| 162 | |||
| 163 | /* stuff a sense request in front of our current request */ | ||
| 164 | pc = kzalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC); | ||
| 165 | rq = blk_get_request(drive->queue, READ, GFP_ATOMIC); | ||
| 166 | buf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC); | ||
| 167 | if (!pc || !rq || !buf) { | ||
| 168 | kfree(buf); | ||
| 169 | if (rq) | ||
| 170 | blk_put_request(rq); | ||
| 171 | kfree(pc); | ||
| 172 | return -ENOMEM; | ||
| 173 | } | ||
| 174 | rq->special = (char *) pc; | ||
| 175 | pc->rq = rq; | ||
| 176 | pc->buf = buf; | ||
| 177 | pc->c[0] = REQUEST_SENSE; | ||
| 178 | pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE; | ||
| 179 | rq->cmd_type = REQ_TYPE_SENSE; | ||
| 180 | rq->cmd_flags |= REQ_PREEMPT; | ||
| 181 | pc->timeout = jiffies + WAIT_READY; | ||
| 182 | /* NOTE! Save the failed packet command in "rq->buffer" */ | ||
| 183 | rq->buffer = (void *) failed_cmd->special; | ||
| 184 | pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd; | ||
| 185 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { | ||
| 186 | printk ("ide-scsi: %s: queue cmd = ", drive->name); | ||
| 187 | ide_scsi_hex_dump(pc->c, 6); | ||
| 188 | } | ||
| 189 | rq->rq_disk = scsi->disk; | ||
| 190 | rq->ref_count++; | ||
| 191 | memcpy(rq->cmd, pc->c, 12); | ||
| 192 | ide_do_drive_cmd(drive, rq); | ||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | static ide_startstop_t | ||
| 197 | idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | ||
| 198 | { | ||
| 199 | ide_hwif_t *hwif = drive->hwif; | ||
| 200 | |||
| 201 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) | ||
| 202 | /* force an abort */ | ||
| 203 | hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); | ||
| 204 | |||
| 205 | rq->errors++; | ||
| 206 | |||
| 207 | idescsi_end_request(drive, 0, 0); | ||
| 208 | |||
| 209 | return ide_stopped; | ||
| 210 | } | ||
| 211 | |||
| 212 | static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) | ||
| 213 | { | ||
| 214 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | ||
| 215 | struct request *rq = HWGROUP(drive)->rq; | ||
| 216 | struct ide_atapi_pc *pc = (struct ide_atapi_pc *) rq->special; | ||
| 217 | int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); | ||
| 218 | struct Scsi_Host *host; | ||
| 219 | int errors = rq->errors; | ||
| 220 | unsigned long flags; | ||
| 221 | |||
| 222 | if (!blk_special_request(rq) && !blk_sense_request(rq)) { | ||
| 223 | ide_end_request(drive, uptodate, nrsecs); | ||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | ide_end_drive_cmd (drive, 0, 0); | ||
| 227 | if (blk_sense_request(rq)) { | ||
| 228 | struct ide_atapi_pc *opc = (struct ide_atapi_pc *) rq->buffer; | ||
| 229 | if (log) { | ||
| 230 | printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number); | ||
| 231 | ide_scsi_hex_dump(pc->buf, 16); | ||
| 232 | } | ||
| 233 | memcpy((void *) opc->scsi_cmd->sense_buffer, pc->buf, | ||
| 234 | SCSI_SENSE_BUFFERSIZE); | ||
| 235 | kfree(pc->buf); | ||
| 236 | kfree(pc); | ||
| 237 | blk_put_request(rq); | ||
| 238 | pc = opc; | ||
| 239 | rq = pc->rq; | ||
| 240 | pc->scsi_cmd->result = (CHECK_CONDITION << 1) | | ||
| 241 | (((pc->flags & PC_FLAG_TIMEDOUT) ? | ||
| 242 | DID_TIME_OUT : | ||
| 243 | DID_OK) << 16); | ||
| 244 | } else if (pc->flags & PC_FLAG_TIMEDOUT) { | ||
| 245 | if (log) | ||
| 246 | printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n", | ||
| 247 | drive->name, pc->scsi_cmd->serial_number); | ||
| 248 | pc->scsi_cmd->result = DID_TIME_OUT << 16; | ||
| 249 | } else if (errors >= ERROR_MAX) { | ||
| 250 | pc->scsi_cmd->result = DID_ERROR << 16; | ||
| 251 | if (log) | ||
| 252 | printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); | ||
| 253 | } else if (errors) { | ||
| 254 | if (log) | ||
| 255 | printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); | ||
| 256 | if (!idescsi_check_condition(drive, rq)) | ||
| 257 | /* we started a request sense, so we'll be back, exit for now */ | ||
| 258 | return 0; | ||
| 259 | pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); | ||
| 260 | } else { | ||
| 261 | pc->scsi_cmd->result = DID_OK << 16; | ||
| 262 | } | ||
| 263 | host = pc->scsi_cmd->device->host; | ||
| 264 | spin_lock_irqsave(host->host_lock, flags); | ||
| 265 | pc->done(pc->scsi_cmd); | ||
| 266 | spin_unlock_irqrestore(host->host_lock, flags); | ||
| 267 | kfree(pc); | ||
| 268 | blk_put_request(rq); | ||
| 269 | drive->pc = NULL; | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | static inline int idescsi_set_direction(struct ide_atapi_pc *pc) | ||
| 274 | { | ||
| 275 | switch (pc->c[0]) { | ||
| 276 | case READ_6: case READ_10: case READ_12: | ||
| 277 | pc->flags &= ~PC_FLAG_WRITING; | ||
| 278 | return 0; | ||
| 279 | case WRITE_6: case WRITE_10: case WRITE_12: | ||
| 280 | pc->flags |= PC_FLAG_WRITING; | ||
| 281 | return 0; | ||
| 282 | default: | ||
| 283 | return 1; | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc) | ||
| 288 | { | ||
| 289 | ide_hwif_t *hwif = drive->hwif; | ||
| 290 | struct scatterlist *sg, *scsi_sg; | ||
| 291 | int segments; | ||
| 292 | |||
| 293 | if (!pc->req_xfer || pc->req_xfer % 1024) | ||
| 294 | return 1; | ||
| 295 | |||
| 296 | if (idescsi_set_direction(pc)) | ||
| 297 | return 1; | ||
| 298 | |||
| 299 | sg = hwif->sg_table; | ||
| 300 | scsi_sg = scsi_sglist(pc->scsi_cmd); | ||
| 301 | segments = scsi_sg_count(pc->scsi_cmd); | ||
| 302 | |||
| 303 | if (segments > hwif->sg_max_nents) | ||
| 304 | return 1; | ||
| 305 | |||
| 306 | hwif->sg_nents = segments; | ||
| 307 | memcpy(sg, scsi_sg, sizeof(*sg) * segments); | ||
| 308 | |||
| 309 | return 0; | ||
| 310 | } | ||
| 311 | |||
| 312 | static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, | ||
| 313 | struct ide_atapi_pc *pc) | ||
| 314 | { | ||
| 315 | /* Set the current packet command */ | ||
| 316 | drive->pc = pc; | ||
| 317 | |||
| 318 | return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry); | ||
| 319 | } | ||
| 320 | |||
| 321 | /* | ||
| 322 | * idescsi_do_request is our request handling function. | ||
| 323 | */ | ||
| 324 | static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block) | ||
| 325 | { | ||
| 326 | debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name, | ||
| 327 | rq->cmd[0], rq->errors); | ||
| 328 | debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n", | ||
| 329 | rq->sector, rq->nr_sectors, rq->current_nr_sectors); | ||
| 330 | |||
| 331 | if (blk_sense_request(rq) || blk_special_request(rq)) { | ||
| 332 | struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; | ||
| 333 | |||
| 334 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && | ||
| 335 | idescsi_map_sg(drive, pc) == 0) | ||
| 336 | pc->flags |= PC_FLAG_DMA_OK; | ||
| 337 | |||
| 338 | return idescsi_issue_pc(drive, pc); | ||
| 339 | } | ||
| 340 | blk_dump_rq_flags(rq, "ide-scsi: unsup command"); | ||
| 341 | idescsi_end_request (drive, 0, 0); | ||
| 342 | return ide_stopped; | ||
| 343 | } | ||
| 344 | |||
| 345 | #ifdef CONFIG_IDE_PROC_FS | ||
| 346 | static ide_proc_entry_t idescsi_proc[] = { | ||
| 347 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | ||
| 348 | { NULL, 0, NULL, NULL } | ||
| 349 | }; | ||
| 350 | |||
| 351 | #define ide_scsi_devset_get(name, field) \ | ||
| 352 | static int get_##name(ide_drive_t *drive) \ | ||
| 353 | { \ | ||
| 354 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ | ||
| 355 | return scsi->field; \ | ||
| 356 | } | ||
| 357 | |||
| 358 | #define ide_scsi_devset_set(name, field) \ | ||
| 359 | static int set_##name(ide_drive_t *drive, int arg) \ | ||
| 360 | { \ | ||
| 361 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ | ||
| 362 | scsi->field = arg; \ | ||
| 363 | return 0; \ | ||
| 364 | } | ||
| 365 | |||
| 366 | #define ide_scsi_devset_rw_field(_name, _field) \ | ||
| 367 | ide_scsi_devset_get(_name, _field); \ | ||
| 368 | ide_scsi_devset_set(_name, _field); \ | ||
| 369 | IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name); | ||
| 370 | |||
| 371 | ide_devset_rw_field(bios_cyl, bios_cyl); | ||
| 372 | ide_devset_rw_field(bios_head, bios_head); | ||
| 373 | ide_devset_rw_field(bios_sect, bios_sect); | ||
| 374 | |||
| 375 | ide_scsi_devset_rw_field(transform, transform); | ||
| 376 | ide_scsi_devset_rw_field(log, log); | ||
| 377 | |||
| 378 | static const struct ide_proc_devset idescsi_settings[] = { | ||
| 379 | IDE_PROC_DEVSET(bios_cyl, 0, 1023), | ||
| 380 | IDE_PROC_DEVSET(bios_head, 0, 255), | ||
| 381 | IDE_PROC_DEVSET(bios_sect, 0, 63), | ||
| 382 | IDE_PROC_DEVSET(log, 0, 1), | ||
| 383 | IDE_PROC_DEVSET(transform, 0, 3), | ||
| 384 | { 0 }, | ||
| 385 | }; | ||
| 386 | |||
| 387 | static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive) | ||
| 388 | { | ||
| 389 | return idescsi_proc; | ||
| 390 | } | ||
| 391 | |||
| 392 | static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive) | ||
| 393 | { | ||
| 394 | return idescsi_settings; | ||
| 395 | } | ||
| 396 | #endif | ||
| 397 | |||
| 398 | /* | ||
| 399 | * Driver initialization. | ||
| 400 | */ | ||
| 401 | static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | ||
| 402 | { | ||
| 403 | clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | ||
| 404 | #if IDESCSI_DEBUG_LOG | ||
| 405 | set_bit(IDESCSI_LOG_CMD, &scsi->log); | ||
| 406 | #endif /* IDESCSI_DEBUG_LOG */ | ||
| 407 | |||
| 408 | drive->pc_callback = ide_scsi_callback; | ||
| 409 | drive->pc_update_buffers = NULL; | ||
| 410 | drive->pc_io_buffers = ide_io_buffers; | ||
| 411 | |||
| 412 | ide_proc_register_driver(drive, scsi->driver); | ||
| 413 | } | ||
| 414 | |||
| 415 | static void ide_scsi_remove(ide_drive_t *drive) | ||
| 416 | { | ||
| 417 | struct Scsi_Host *scsihost = drive->driver_data; | ||
| 418 | struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); | ||
| 419 | struct gendisk *g = scsi->disk; | ||
| 420 | |||
| 421 | scsi_remove_host(scsihost); | ||
| 422 | ide_proc_unregister_driver(drive, scsi->driver); | ||
| 423 | |||
| 424 | ide_unregister_region(g); | ||
| 425 | |||
| 426 | drive->driver_data = NULL; | ||
| 427 | g->private_data = NULL; | ||
| 428 | put_disk(g); | ||
| 429 | |||
| 430 | ide_scsi_put(scsi); | ||
| 431 | |||
| 432 | drive->dev_flags &= ~IDE_DFLAG_SCSI; | ||
| 433 | } | ||
| 434 | |||
| 435 | static int ide_scsi_probe(ide_drive_t *); | ||
| 436 | |||
| 437 | static ide_driver_t idescsi_driver = { | ||
| 438 | .gen_driver = { | ||
| 439 | .owner = THIS_MODULE, | ||
| 440 | .name = "ide-scsi", | ||
| 441 | .bus = &ide_bus_type, | ||
| 442 | }, | ||
| 443 | .probe = ide_scsi_probe, | ||
| 444 | .remove = ide_scsi_remove, | ||
| 445 | .version = IDESCSI_VERSION, | ||
| 446 | .do_request = idescsi_do_request, | ||
| 447 | .end_request = idescsi_end_request, | ||
| 448 | .error = idescsi_atapi_error, | ||
| 449 | #ifdef CONFIG_IDE_PROC_FS | ||
| 450 | .proc_entries = ide_scsi_proc_entries, | ||
| 451 | .proc_devsets = ide_scsi_proc_devsets, | ||
| 452 | #endif | ||
| 453 | }; | ||
| 454 | |||
| 455 | static int idescsi_ide_open(struct block_device *bdev, fmode_t mode) | ||
| 456 | { | ||
| 457 | struct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk); | ||
| 458 | |||
| 459 | if (!scsi) | ||
| 460 | return -ENXIO; | ||
| 461 | |||
| 462 | return 0; | ||
| 463 | } | ||
| 464 | |||
| 465 | static int idescsi_ide_release(struct gendisk *disk, fmode_t mode) | ||
| 466 | { | ||
| 467 | ide_scsi_put(ide_scsi_g(disk)); | ||
| 468 | return 0; | ||
| 469 | } | ||
| 470 | |||
| 471 | static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode, | ||
| 472 | unsigned int cmd, unsigned long arg) | ||
| 473 | { | ||
| 474 | struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk); | ||
| 475 | return generic_ide_ioctl(scsi->drive, bdev, cmd, arg); | ||
| 476 | } | ||
| 477 | |||
| 478 | static struct block_device_operations idescsi_ops = { | ||
| 479 | .owner = THIS_MODULE, | ||
| 480 | .open = idescsi_ide_open, | ||
| 481 | .release = idescsi_ide_release, | ||
| 482 | .locked_ioctl = idescsi_ide_ioctl, | ||
| 483 | }; | ||
| 484 | |||
| 485 | static int idescsi_slave_configure(struct scsi_device * sdp) | ||
| 486 | { | ||
| 487 | /* Configure detected device */ | ||
| 488 | sdp->use_10_for_rw = 1; | ||
| 489 | sdp->use_10_for_ms = 1; | ||
| 490 | scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); | ||
| 491 | return 0; | ||
| 492 | } | ||
| 493 | |||
| 494 | static const char *idescsi_info (struct Scsi_Host *host) | ||
| 495 | { | ||
| 496 | return "SCSI host adapter emulation for IDE ATAPI devices"; | ||
| 497 | } | ||
| 498 | |||
| 499 | static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg) | ||
| 500 | { | ||
| 501 | idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host); | ||
| 502 | |||
| 503 | if (cmd == SG_SET_TRANSFORM) { | ||
| 504 | if (arg) | ||
| 505 | set_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | ||
| 506 | else | ||
| 507 | clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | ||
| 508 | return 0; | ||
| 509 | } else if (cmd == SG_GET_TRANSFORM) | ||
| 510 | return put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg); | ||
| 511 | return -EINVAL; | ||
| 512 | } | ||
| 513 | |||
| 514 | static int idescsi_queue (struct scsi_cmnd *cmd, | ||
| 515 | void (*done)(struct scsi_cmnd *)) | ||
| 516 | { | ||
| 517 | struct Scsi_Host *host = cmd->device->host; | ||
| 518 | idescsi_scsi_t *scsi = scsihost_to_idescsi(host); | ||
| 519 | ide_drive_t *drive = scsi->drive; | ||
| 520 | struct request *rq = NULL; | ||
| 521 | struct ide_atapi_pc *pc = NULL; | ||
| 522 | int write = cmd->sc_data_direction == DMA_TO_DEVICE; | ||
| 523 | |||
| 524 | if (!drive) { | ||
| 525 | scmd_printk (KERN_ERR, cmd, "drive not present\n"); | ||
| 526 | goto abort; | ||
| 527 | } | ||
| 528 | scsi = drive_to_idescsi(drive); | ||
| 529 | pc = kmalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC); | ||
| 530 | rq = blk_get_request(drive->queue, write, GFP_ATOMIC); | ||
| 531 | if (rq == NULL || pc == NULL) { | ||
| 532 | printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name); | ||
| 533 | goto abort; | ||
| 534 | } | ||
| 535 | |||
| 536 | memset (pc->c, 0, 12); | ||
| 537 | pc->flags = 0; | ||
| 538 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
| 539 | pc->flags |= PC_FLAG_WRITING; | ||
| 540 | pc->rq = rq; | ||
| 541 | memcpy (pc->c, cmd->cmnd, cmd->cmd_len); | ||
| 542 | pc->buf = NULL; | ||
| 543 | pc->sg = scsi_sglist(cmd); | ||
| 544 | pc->sg_cnt = scsi_sg_count(cmd); | ||
| 545 | pc->b_count = 0; | ||
| 546 | pc->req_xfer = pc->buf_size = scsi_bufflen(cmd); | ||
| 547 | pc->scsi_cmd = cmd; | ||
| 548 | pc->done = done; | ||
| 549 | pc->timeout = jiffies + cmd->request->timeout; | ||
| 550 | |||
| 551 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { | ||
| 552 | printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); | ||
| 553 | ide_scsi_hex_dump(cmd->cmnd, cmd->cmd_len); | ||
| 554 | if (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) { | ||
| 555 | printk ("ide-scsi: %s: que %lu, tsl = ", drive->name, cmd->serial_number); | ||
| 556 | ide_scsi_hex_dump(pc->c, 12); | ||
| 557 | } | ||
| 558 | } | ||
| 559 | |||
| 560 | rq->special = (char *) pc; | ||
| 561 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
| 562 | spin_unlock_irq(host->host_lock); | ||
| 563 | rq->ref_count++; | ||
| 564 | memcpy(rq->cmd, pc->c, 12); | ||
| 565 | blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL); | ||
| 566 | spin_lock_irq(host->host_lock); | ||
| 567 | return 0; | ||
| 568 | abort: | ||
| 569 | kfree (pc); | ||
| 570 | if (rq) | ||
| 571 | blk_put_request(rq); | ||
| 572 | cmd->result = DID_ERROR << 16; | ||
| 573 | done(cmd); | ||
| 574 | return 0; | ||
| 575 | } | ||
| 576 | |||
| 577 | static int idescsi_eh_abort (struct scsi_cmnd *cmd) | ||
| 578 | { | ||
| 579 | idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host); | ||
| 580 | ide_drive_t *drive = scsi->drive; | ||
| 581 | ide_hwif_t *hwif; | ||
| 582 | ide_hwgroup_t *hwgroup; | ||
| 583 | int busy; | ||
| 584 | int ret = FAILED; | ||
| 585 | |||
| 586 | struct ide_atapi_pc *pc; | ||
| 587 | |||
| 588 | /* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */ | ||
| 589 | |||
| 590 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | ||
| 591 | printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number); | ||
| 592 | |||
| 593 | if (!drive) { | ||
| 594 | printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n"); | ||
| 595 | WARN_ON(1); | ||
| 596 | goto no_drive; | ||
| 597 | } | ||
| 598 | |||
| 599 | hwif = drive->hwif; | ||
| 600 | hwgroup = hwif->hwgroup; | ||
| 601 | |||
| 602 | /* First give it some more time, how much is "right" is hard to say :-( | ||
| 603 | FIXME - uses mdelay which causes latency? */ | ||
| 604 | busy = ide_wait_not_busy(hwif, 100); | ||
| 605 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | ||
| 606 | printk (KERN_WARNING "ide-scsi: drive did%s become ready\n", busy?" not":""); | ||
| 607 | |||
| 608 | spin_lock_irq(&hwgroup->lock); | ||
| 609 | |||
| 610 | /* If there is no pc running we're done (our interrupt took care of it) */ | ||
| 611 | pc = drive->pc; | ||
| 612 | if (pc == NULL) { | ||
| 613 | ret = SUCCESS; | ||
| 614 | goto ide_unlock; | ||
| 615 | } | ||
| 616 | |||
| 617 | /* It's somewhere in flight. Does ide subsystem agree? */ | ||
| 618 | if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy && | ||
| 619 | elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) { | ||
| 620 | /* | ||
| 621 | * FIXME - not sure this condition can ever occur | ||
| 622 | */ | ||
| 623 | printk (KERN_ERR "ide-scsi: cmd aborted!\n"); | ||
| 624 | |||
| 625 | if (blk_sense_request(pc->rq)) | ||
| 626 | kfree(pc->buf); | ||
| 627 | /* we need to call blk_put_request twice. */ | ||
| 628 | blk_put_request(pc->rq); | ||
| 629 | blk_put_request(pc->rq); | ||
| 630 | kfree(pc); | ||
| 631 | drive->pc = NULL; | ||
| 632 | |||
| 633 | ret = SUCCESS; | ||
| 634 | } | ||
| 635 | |||
| 636 | ide_unlock: | ||
| 637 | spin_unlock_irq(&hwgroup->lock); | ||
| 638 | no_drive: | ||
| 639 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | ||
| 640 | printk (KERN_WARNING "ide-scsi: abort returns %s\n", ret == SUCCESS?"success":"failed"); | ||
| 641 | |||
| 642 | return ret; | ||
| 643 | } | ||
| 644 | |||
| 645 | static int idescsi_eh_reset (struct scsi_cmnd *cmd) | ||
| 646 | { | ||
| 647 | struct request *req; | ||
| 648 | idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host); | ||
| 649 | ide_drive_t *drive = scsi->drive; | ||
| 650 | ide_hwgroup_t *hwgroup; | ||
| 651 | int ready = 0; | ||
| 652 | int ret = SUCCESS; | ||
| 653 | |||
| 654 | struct ide_atapi_pc *pc; | ||
| 655 | |||
| 656 | /* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */ | ||
| 657 | |||
| 658 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | ||
| 659 | printk (KERN_WARNING "ide-scsi: reset called for %lu\n", cmd->serial_number); | ||
| 660 | |||
| 661 | if (!drive) { | ||
| 662 | printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_reset\n"); | ||
| 663 | WARN_ON(1); | ||
| 664 | return FAILED; | ||
| 665 | } | ||
| 666 | |||
| 667 | hwgroup = drive->hwif->hwgroup; | ||
| 668 | |||
| 669 | spin_lock_irq(cmd->device->host->host_lock); | ||
| 670 | spin_lock(&hwgroup->lock); | ||
| 671 | |||
| 672 | pc = drive->pc; | ||
| 673 | if (pc) | ||
| 674 | req = pc->rq; | ||
| 675 | |||
| 676 | if (pc == NULL || req != hwgroup->rq || hwgroup->handler == NULL) { | ||
| 677 | printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); | ||
| 678 | spin_unlock(&hwgroup->lock); | ||
| 679 | spin_unlock_irq(cmd->device->host->host_lock); | ||
| 680 | return FAILED; | ||
| 681 | } | ||
| 682 | |||
| 683 | /* kill current request */ | ||
| 684 | if (__blk_end_request(req, -EIO, 0)) | ||
| 685 | BUG(); | ||
| 686 | if (blk_sense_request(req)) | ||
| 687 | kfree(pc->buf); | ||
| 688 | kfree(pc); | ||
| 689 | drive->pc = NULL; | ||
| 690 | blk_put_request(req); | ||
| 691 | |||
| 692 | /* now nuke the drive queue */ | ||
| 693 | while ((req = elv_next_request(drive->queue))) { | ||
| 694 | if (__blk_end_request(req, -EIO, 0)) | ||
| 695 | BUG(); | ||
| 696 | } | ||
| 697 | |||
| 698 | hwgroup->rq = NULL; | ||
| 699 | hwgroup->handler = NULL; | ||
| 700 | hwgroup->busy = 1; /* will set this to zero when ide reset finished */ | ||
| 701 | spin_unlock(&hwgroup->lock); | ||
| 702 | |||
| 703 | ide_do_reset(drive); | ||
| 704 | |||
| 705 | /* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */ | ||
| 706 | |||
| 707 | do { | ||
| 708 | spin_unlock_irq(cmd->device->host->host_lock); | ||
| 709 | msleep(50); | ||
| 710 | spin_lock_irq(cmd->device->host->host_lock); | ||
| 711 | } while ( HWGROUP(drive)->handler ); | ||
| 712 | |||
| 713 | ready = drive_is_ready(drive); | ||
| 714 | HWGROUP(drive)->busy--; | ||
| 715 | if (!ready) { | ||
| 716 | printk (KERN_ERR "ide-scsi: reset failed!\n"); | ||
| 717 | ret = FAILED; | ||
| 718 | } | ||
| 719 | |||
| 720 | spin_unlock_irq(cmd->device->host->host_lock); | ||
| 721 | return ret; | ||
| 722 | } | ||
| 723 | |||
| 724 | static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev, | ||
| 725 | sector_t capacity, int *parm) | ||
| 726 | { | ||
| 727 | idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host); | ||
| 728 | ide_drive_t *drive = idescsi->drive; | ||
| 729 | |||
| 730 | if (drive->bios_cyl && drive->bios_head && drive->bios_sect) { | ||
| 731 | parm[0] = drive->bios_head; | ||
| 732 | parm[1] = drive->bios_sect; | ||
| 733 | parm[2] = drive->bios_cyl; | ||
| 734 | } | ||
| 735 | return 0; | ||
| 736 | } | ||
| 737 | |||
| 738 | static struct scsi_host_template idescsi_template = { | ||
| 739 | .module = THIS_MODULE, | ||
| 740 | .name = "idescsi", | ||
| 741 | .info = idescsi_info, | ||
| 742 | .slave_configure = idescsi_slave_configure, | ||
| 743 | .ioctl = idescsi_ioctl, | ||
| 744 | .queuecommand = idescsi_queue, | ||
| 745 | .eh_abort_handler = idescsi_eh_abort, | ||
| 746 | .eh_host_reset_handler = idescsi_eh_reset, | ||
| 747 | .bios_param = idescsi_bios, | ||
| 748 | .can_queue = 40, | ||
| 749 | .this_id = -1, | ||
| 750 | .sg_tablesize = 256, | ||
| 751 | .cmd_per_lun = 5, | ||
| 752 | .max_sectors = 128, | ||
| 753 | .use_clustering = DISABLE_CLUSTERING, | ||
| 754 | .emulated = 1, | ||
| 755 | .proc_name = "ide-scsi", | ||
| 756 | }; | ||
| 757 | |||
| 758 | static int ide_scsi_probe(ide_drive_t *drive) | ||
| 759 | { | ||
| 760 | idescsi_scsi_t *idescsi; | ||
| 761 | struct Scsi_Host *host; | ||
| 762 | struct gendisk *g; | ||
| 763 | static int warned; | ||
| 764 | int err = -ENOMEM; | ||
| 765 | u16 last_lun; | ||
| 766 | |||
| 767 | if (!warned && drive->media == ide_cdrom) { | ||
| 768 | printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); | ||
| 769 | warned = 1; | ||
| 770 | } | ||
| 771 | |||
| 772 | if (idescsi_nocd && drive->media == ide_cdrom) | ||
| 773 | return -ENODEV; | ||
| 774 | |||
| 775 | if (!strstr("ide-scsi", drive->driver_req) || | ||
| 776 | drive->media == ide_disk || | ||
| 777 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) | ||
| 778 | return -ENODEV; | ||
| 779 | |||
| 780 | drive->dev_flags |= IDE_DFLAG_SCSI; | ||
| 781 | |||
| 782 | g = alloc_disk(1 << PARTN_BITS); | ||
| 783 | if (!g) | ||
| 784 | goto out_host_put; | ||
| 785 | |||
| 786 | ide_init_disk(g, drive); | ||
| 787 | |||
| 788 | host->max_id = 1; | ||
| 789 | |||
| 790 | last_lun = drive->id[ATA_ID_LAST_LUN]; | ||
| 791 | if (last_lun) | ||
| 792 | debug_log("%s: last_lun=%u\n", drive->name, last_lun); | ||
| 793 | |||
| 794 | if ((last_lun & 7) != 7) | ||
| 795 | host->max_lun = (last_lun & 7) + 1; | ||
| 796 | else | ||
| 797 | host->max_lun = 1; | ||
| 798 | |||
| 799 | drive->driver_data = host; | ||
| 800 | idescsi = scsihost_to_idescsi(host); | ||
| 801 | idescsi->drive = drive; | ||
| 802 | idescsi->driver = &idescsi_driver; | ||
| 803 | idescsi->host = host; | ||
| 804 | idescsi->disk = g; | ||
| 805 | g->private_data = &idescsi->driver; | ||
| 806 | err = 0; | ||
| 807 | idescsi_setup(drive, idescsi); | ||
| 808 | g->fops = &idescsi_ops; | ||
| 809 | ide_register_region(g); | ||
| 810 | err = scsi_add_host(host, &drive->gendev); | ||
| 811 | if (!err) { | ||
| 812 | scsi_scan_host(host); | ||
| 813 | return 0; | ||
| 814 | } | ||
| 815 | /* fall through on error */ | ||
| 816 | ide_unregister_region(g); | ||
| 817 | ide_proc_unregister_driver(drive, &idescsi_driver); | ||
| 818 | |||
| 819 | put_disk(g); | ||
| 820 | out_host_put: | ||
| 821 | drive->dev_flags &= ~IDE_DFLAG_SCSI; | ||
| 822 | scsi_host_put(host); | ||
| 823 | return err; | ||
| 824 | } | ||
| 825 | |||
| 826 | static int __init init_idescsi_module(void) | ||
| 827 | { | ||
| 828 | return driver_register(&idescsi_driver.gen_driver); | ||
| 829 | } | ||
| 830 | |||
| 831 | static void __exit exit_idescsi_module(void) | ||
| 832 | { | ||
| 833 | driver_unregister(&idescsi_driver.gen_driver); | ||
| 834 | } | ||
| 835 | |||
| 836 | module_param(idescsi_nocd, int, 0600); | ||
| 837 | MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd"); | ||
| 838 | module_init(init_idescsi_module); | ||
| 839 | module_exit(exit_idescsi_module); | ||
| 840 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index e99c56de7f56..db5ef8ae1ab9 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -32,13 +32,6 @@ | |||
| 32 | # define SUPPORT_VLB_SYNC 1 | 32 | # define SUPPORT_VLB_SYNC 1 |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | /* | ||
| 36 | * Used to indicate "no IRQ", should be a value that cannot be an IRQ | ||
| 37 | * number. | ||
| 38 | */ | ||
| 39 | |||
| 40 | #define IDE_NO_IRQ (-1) | ||
| 41 | |||
| 42 | typedef unsigned char byte; /* used everywhere */ | 35 | typedef unsigned char byte; /* used everywhere */ |
| 43 | 36 | ||
| 44 | /* | 37 | /* |
| @@ -403,6 +396,7 @@ enum { | |||
| 403 | * This is used for several packet commands (not for READ/WRITE commands). | 396 | * This is used for several packet commands (not for READ/WRITE commands). |
| 404 | */ | 397 | */ |
| 405 | #define IDE_PC_BUFFER_SIZE 256 | 398 | #define IDE_PC_BUFFER_SIZE 256 |
| 399 | #define ATAPI_WAIT_PC (60 * HZ) | ||
| 406 | 400 | ||
| 407 | struct ide_atapi_pc { | 401 | struct ide_atapi_pc { |
| 408 | /* actual packet bytes */ | 402 | /* actual packet bytes */ |
| @@ -480,53 +474,53 @@ enum { | |||
| 480 | 474 | ||
| 481 | /* ide-cd */ | 475 | /* ide-cd */ |
| 482 | /* Drive cannot eject the disc. */ | 476 | /* Drive cannot eject the disc. */ |
| 483 | IDE_AFLAG_NO_EJECT = (1 << 3), | 477 | IDE_AFLAG_NO_EJECT = (1 << 1), |
| 484 | /* Drive is a pre ATAPI 1.2 drive. */ | 478 | /* Drive is a pre ATAPI 1.2 drive. */ |
| 485 | IDE_AFLAG_PRE_ATAPI12 = (1 << 4), | 479 | IDE_AFLAG_PRE_ATAPI12 = (1 << 2), |
| 486 | /* TOC addresses are in BCD. */ | 480 | /* TOC addresses are in BCD. */ |
| 487 | IDE_AFLAG_TOCADDR_AS_BCD = (1 << 5), | 481 | IDE_AFLAG_TOCADDR_AS_BCD = (1 << 3), |
| 488 | /* TOC track numbers are in BCD. */ | 482 | /* TOC track numbers are in BCD. */ |
| 489 | IDE_AFLAG_TOCTRACKS_AS_BCD = (1 << 6), | 483 | IDE_AFLAG_TOCTRACKS_AS_BCD = (1 << 4), |
| 490 | /* | 484 | /* |
| 491 | * Drive does not provide data in multiples of SECTOR_SIZE | 485 | * Drive does not provide data in multiples of SECTOR_SIZE |
| 492 | * when more than one interrupt is needed. | 486 | * when more than one interrupt is needed. |
| 493 | */ | 487 | */ |
| 494 | IDE_AFLAG_LIMIT_NFRAMES = (1 << 7), | 488 | IDE_AFLAG_LIMIT_NFRAMES = (1 << 5), |
| 495 | /* Saved TOC information is current. */ | 489 | /* Saved TOC information is current. */ |
| 496 | IDE_AFLAG_TOC_VALID = (1 << 9), | 490 | IDE_AFLAG_TOC_VALID = (1 << 6), |
| 497 | /* We think that the drive door is locked. */ | 491 | /* We think that the drive door is locked. */ |
| 498 | IDE_AFLAG_DOOR_LOCKED = (1 << 10), | 492 | IDE_AFLAG_DOOR_LOCKED = (1 << 7), |
| 499 | /* SET_CD_SPEED command is unsupported. */ | 493 | /* SET_CD_SPEED command is unsupported. */ |
| 500 | IDE_AFLAG_NO_SPEED_SELECT = (1 << 11), | 494 | IDE_AFLAG_NO_SPEED_SELECT = (1 << 8), |
| 501 | IDE_AFLAG_VERTOS_300_SSD = (1 << 12), | 495 | IDE_AFLAG_VERTOS_300_SSD = (1 << 9), |
| 502 | IDE_AFLAG_VERTOS_600_ESD = (1 << 13), | 496 | IDE_AFLAG_VERTOS_600_ESD = (1 << 10), |
| 503 | IDE_AFLAG_SANYO_3CD = (1 << 14), | 497 | IDE_AFLAG_SANYO_3CD = (1 << 11), |
| 504 | IDE_AFLAG_FULL_CAPS_PAGE = (1 << 15), | 498 | IDE_AFLAG_FULL_CAPS_PAGE = (1 << 12), |
| 505 | IDE_AFLAG_PLAY_AUDIO_OK = (1 << 16), | 499 | IDE_AFLAG_PLAY_AUDIO_OK = (1 << 13), |
| 506 | IDE_AFLAG_LE_SPEED_FIELDS = (1 << 17), | 500 | IDE_AFLAG_LE_SPEED_FIELDS = (1 << 14), |
| 507 | 501 | ||
| 508 | /* ide-floppy */ | 502 | /* ide-floppy */ |
| 509 | /* Avoid commands not supported in Clik drive */ | 503 | /* Avoid commands not supported in Clik drive */ |
| 510 | IDE_AFLAG_CLIK_DRIVE = (1 << 19), | 504 | IDE_AFLAG_CLIK_DRIVE = (1 << 15), |
| 511 | /* Requires BH algorithm for packets */ | 505 | /* Requires BH algorithm for packets */ |
| 512 | IDE_AFLAG_ZIP_DRIVE = (1 << 20), | 506 | IDE_AFLAG_ZIP_DRIVE = (1 << 16), |
| 513 | /* Supports format progress report */ | 507 | /* Supports format progress report */ |
| 514 | IDE_AFLAG_SRFP = (1 << 22), | 508 | IDE_AFLAG_SRFP = (1 << 17), |
| 515 | 509 | ||
| 516 | /* ide-tape */ | 510 | /* ide-tape */ |
| 517 | IDE_AFLAG_IGNORE_DSC = (1 << 23), | 511 | IDE_AFLAG_IGNORE_DSC = (1 << 18), |
| 518 | /* 0 When the tape position is unknown */ | 512 | /* 0 When the tape position is unknown */ |
| 519 | IDE_AFLAG_ADDRESS_VALID = (1 << 24), | 513 | IDE_AFLAG_ADDRESS_VALID = (1 << 19), |
| 520 | /* Device already opened */ | 514 | /* Device already opened */ |
| 521 | IDE_AFLAG_BUSY = (1 << 25), | 515 | IDE_AFLAG_BUSY = (1 << 20), |
| 522 | /* Attempt to auto-detect the current user block size */ | 516 | /* Attempt to auto-detect the current user block size */ |
| 523 | IDE_AFLAG_DETECT_BS = (1 << 26), | 517 | IDE_AFLAG_DETECT_BS = (1 << 21), |
| 524 | /* Currently on a filemark */ | 518 | /* Currently on a filemark */ |
| 525 | IDE_AFLAG_FILEMARK = (1 << 27), | 519 | IDE_AFLAG_FILEMARK = (1 << 22), |
| 526 | /* 0 = no tape is loaded, so we don't rewind after ejecting */ | 520 | /* 0 = no tape is loaded, so we don't rewind after ejecting */ |
| 527 | IDE_AFLAG_MEDIUM_PRESENT = (1 << 28), | 521 | IDE_AFLAG_MEDIUM_PRESENT = (1 << 23), |
| 528 | 522 | ||
| 529 | IDE_AFLAG_NO_AUTOCLOSE = (1 << 29), | 523 | IDE_AFLAG_NO_AUTOCLOSE = (1 << 24), |
| 530 | }; | 524 | }; |
| 531 | 525 | ||
| 532 | /* device flags */ | 526 | /* device flags */ |
| @@ -565,28 +559,26 @@ enum { | |||
| 565 | IDE_DFLAG_NODMA = (1 << 16), | 559 | IDE_DFLAG_NODMA = (1 << 16), |
| 566 | /* powermanagment told us not to do anything, so sleep nicely */ | 560 | /* powermanagment told us not to do anything, so sleep nicely */ |
| 567 | IDE_DFLAG_BLOCKED = (1 << 17), | 561 | IDE_DFLAG_BLOCKED = (1 << 17), |
| 568 | /* ide-scsi emulation */ | ||
| 569 | IDE_DFLAG_SCSI = (1 << 18), | ||
| 570 | /* sleeping & sleep field valid */ | 562 | /* sleeping & sleep field valid */ |
| 571 | IDE_DFLAG_SLEEPING = (1 << 19), | 563 | IDE_DFLAG_SLEEPING = (1 << 18), |
| 572 | IDE_DFLAG_POST_RESET = (1 << 20), | 564 | IDE_DFLAG_POST_RESET = (1 << 19), |
| 573 | IDE_DFLAG_UDMA33_WARNED = (1 << 21), | 565 | IDE_DFLAG_UDMA33_WARNED = (1 << 20), |
| 574 | IDE_DFLAG_LBA48 = (1 << 22), | 566 | IDE_DFLAG_LBA48 = (1 << 21), |
| 575 | /* status of write cache */ | 567 | /* status of write cache */ |
| 576 | IDE_DFLAG_WCACHE = (1 << 23), | 568 | IDE_DFLAG_WCACHE = (1 << 22), |
| 577 | /* used for ignoring ATA_DF */ | 569 | /* used for ignoring ATA_DF */ |
| 578 | IDE_DFLAG_NOWERR = (1 << 24), | 570 | IDE_DFLAG_NOWERR = (1 << 23), |
| 579 | /* retrying in PIO */ | 571 | /* retrying in PIO */ |
| 580 | IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), | 572 | IDE_DFLAG_DMA_PIO_RETRY = (1 << 24), |
| 581 | IDE_DFLAG_LBA = (1 << 26), | 573 | IDE_DFLAG_LBA = (1 << 25), |
| 582 | /* don't unload heads */ | 574 | /* don't unload heads */ |
| 583 | IDE_DFLAG_NO_UNLOAD = (1 << 27), | 575 | IDE_DFLAG_NO_UNLOAD = (1 << 26), |
| 584 | /* heads unloaded, please don't reset port */ | 576 | /* heads unloaded, please don't reset port */ |
| 585 | IDE_DFLAG_PARKED = (1 << 28), | 577 | IDE_DFLAG_PARKED = (1 << 27), |
| 586 | IDE_DFLAG_MEDIA_CHANGED = (1 << 29), | 578 | IDE_DFLAG_MEDIA_CHANGED = (1 << 28), |
| 587 | /* write protect */ | 579 | /* write protect */ |
| 588 | IDE_DFLAG_WP = (1 << 30), | 580 | IDE_DFLAG_WP = (1 << 29), |
| 589 | IDE_DFLAG_FORMAT_IN_PROGRESS = (1 << 31), | 581 | IDE_DFLAG_FORMAT_IN_PROGRESS = (1 << 30), |
| 590 | }; | 582 | }; |
| 591 | 583 | ||
| 592 | struct ide_drive_s { | 584 | struct ide_drive_s { |
| @@ -610,8 +602,6 @@ struct ide_drive_s { | |||
| 610 | unsigned long dev_flags; | 602 | unsigned long dev_flags; |
| 611 | 603 | ||
| 612 | unsigned long sleep; /* sleep until this time */ | 604 | unsigned long sleep; /* sleep until this time */ |
| 613 | unsigned long service_start; /* time we started last request */ | ||
| 614 | unsigned long service_time; /* service time of last request */ | ||
| 615 | unsigned long timeout; /* max time to wait for irq */ | 605 | unsigned long timeout; /* max time to wait for irq */ |
| 616 | 606 | ||
| 617 | special_t special; /* special action flags */ | 607 | special_t special; /* special action flags */ |
| @@ -879,8 +869,6 @@ typedef struct hwgroup_s { | |||
| 879 | 869 | ||
| 880 | /* BOOL: protects all fields below */ | 870 | /* BOOL: protects all fields below */ |
| 881 | volatile int busy; | 871 | volatile int busy; |
| 882 | /* BOOL: wake us up on timer expiry */ | ||
| 883 | unsigned int sleeping : 1; | ||
| 884 | /* BOOL: polling active & poll_timeout field valid */ | 872 | /* BOOL: polling active & poll_timeout field valid */ |
| 885 | unsigned int polling : 1; | 873 | unsigned int polling : 1; |
| 886 | 874 | ||
| @@ -1258,14 +1246,11 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); | |||
| 1258 | void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); | 1246 | void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); |
| 1259 | void ide_retry_pc(ide_drive_t *, struct gendisk *); | 1247 | void ide_retry_pc(ide_drive_t *, struct gendisk *); |
| 1260 | 1248 | ||
| 1261 | static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) | 1249 | int ide_cd_expiry(ide_drive_t *); |
| 1262 | { | ||
| 1263 | return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies); | ||
| 1264 | } | ||
| 1265 | 1250 | ||
| 1266 | int ide_scsi_expiry(ide_drive_t *); | 1251 | int ide_cd_get_xferlen(struct request *); |
| 1267 | 1252 | ||
| 1268 | ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *); | 1253 | ide_startstop_t ide_issue_pc(ide_drive_t *); |
| 1269 | 1254 | ||
| 1270 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); | 1255 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); |
| 1271 | 1256 | ||
| @@ -1287,6 +1272,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); | |||
| 1287 | 1272 | ||
| 1288 | extern void ide_timer_expiry(unsigned long); | 1273 | extern void ide_timer_expiry(unsigned long); |
| 1289 | extern irqreturn_t ide_intr(int irq, void *dev_id); | 1274 | extern irqreturn_t ide_intr(int irq, void *dev_id); |
| 1275 | |||
| 1276 | static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup) | ||
| 1277 | { | ||
| 1278 | if (hwgroup->busy) | ||
| 1279 | return 1; | ||
| 1280 | |||
| 1281 | hwgroup->busy = 1; | ||
| 1282 | /* for atari only */ | ||
| 1283 | ide_get_lock(ide_intr, hwgroup); | ||
| 1284 | |||
| 1285 | return 0; | ||
| 1286 | } | ||
| 1287 | |||
| 1288 | static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup) | ||
| 1289 | { | ||
| 1290 | /* for atari only */ | ||
| 1291 | ide_release_lock(); | ||
| 1292 | hwgroup->busy = 0; | ||
| 1293 | } | ||
| 1294 | |||
| 1290 | extern void do_ide_request(struct request_queue *); | 1295 | extern void do_ide_request(struct request_queue *); |
| 1291 | 1296 | ||
| 1292 | void ide_init_disk(struct gendisk *, ide_drive_t *); | 1297 | void ide_init_disk(struct gendisk *, ide_drive_t *); |
| @@ -1533,6 +1538,7 @@ void ide_unregister_region(struct gendisk *); | |||
| 1533 | void ide_undecoded_slave(ide_drive_t *); | 1538 | void ide_undecoded_slave(ide_drive_t *); |
| 1534 | 1539 | ||
| 1535 | void ide_port_apply_params(ide_hwif_t *); | 1540 | void ide_port_apply_params(ide_hwif_t *); |
| 1541 | int ide_sysfs_register_port(ide_hwif_t *); | ||
| 1536 | 1542 | ||
| 1537 | struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); | 1543 | struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); |
| 1538 | void ide_host_free(struct ide_host *); | 1544 | void ide_host_free(struct ide_host *); |
| @@ -1627,6 +1633,9 @@ extern struct mutex ide_cfg_mtx; | |||
| 1627 | 1633 | ||
| 1628 | #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) | 1634 | #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) |
| 1629 | 1635 | ||
| 1636 | char *ide_media_string(ide_drive_t *); | ||
| 1637 | |||
| 1638 | extern struct device_attribute ide_dev_attrs[]; | ||
| 1630 | extern struct bus_type ide_bus_type; | 1639 | extern struct bus_type ide_bus_type; |
| 1631 | extern struct class *ide_port_class; | 1640 | extern struct class *ide_port_class; |
| 1632 | 1641 | ||
