diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 525 |
1 files changed, 168 insertions, 357 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3f630e4080d4..35729a47f797 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> | 4 | * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> |
5 | * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> | 5 | * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> |
6 | * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> | 6 | * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> |
7 | * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz | 7 | * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz |
8 | * | 8 | * |
9 | * May be copied or modified under the terms of the GNU General Public | 9 | * May be copied or modified under the terms of the GNU General Public |
10 | * License. See linux/COPYING for more information. | 10 | * License. See linux/COPYING for more information. |
@@ -12,12 +12,9 @@ | |||
12 | * See Documentation/cdrom/ide-cd for usage information. | 12 | * See Documentation/cdrom/ide-cd for usage information. |
13 | * | 13 | * |
14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) | 14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) |
15 | * For those wishing to work on this driver, please be sure you download | 15 | * |
16 | * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI | 16 | * Documentation: |
17 | * (SFF-8020i rev 2.6) standards. These documents can be obtained by | 17 | * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards. |
18 | * anonymous ftp from: | ||
19 | * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps | ||
20 | * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf | ||
21 | * | 18 | * |
22 | * For historical changelog please see: | 19 | * For historical changelog please see: |
23 | * Documentation/ide/ChangeLog.ide-cd.1994-2004 | 20 | * Documentation/ide/ChangeLog.ide-cd.1994-2004 |
@@ -245,73 +242,34 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | |||
245 | elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); | 242 | elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); |
246 | } | 243 | } |
247 | 244 | ||
248 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) | 245 | static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) |
249 | { | 246 | { |
250 | struct request *rq = drive->hwif->rq; | 247 | /* |
251 | int nsectors = rq->hard_cur_sectors; | 248 | * For REQ_TYPE_SENSE, "rq->buffer" points to the original |
252 | 249 | * failed request | |
253 | ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, uptodate: 0x%x, nsectors: %d", | 250 | */ |
254 | rq->cmd[0], uptodate, nsectors); | 251 | struct request *failed = (struct request *)rq->buffer; |
255 | 252 | struct cdrom_info *info = drive->driver_data; | |
256 | if (blk_sense_request(rq) && uptodate) { | 253 | void *sense = &info->sense_data; |
257 | /* | ||
258 | * For REQ_TYPE_SENSE, "rq->buffer" points to the original | ||
259 | * failed request | ||
260 | */ | ||
261 | struct request *failed = (struct request *) rq->buffer; | ||
262 | struct cdrom_info *info = drive->driver_data; | ||
263 | void *sense = &info->sense_data; | ||
264 | |||
265 | if (failed) { | ||
266 | if (failed->sense) { | ||
267 | sense = failed->sense; | ||
268 | failed->sense_len = rq->sense_len; | ||
269 | } | ||
270 | cdrom_analyze_sense_data(drive, failed, sense); | ||
271 | /* | ||
272 | * now end the failed request | ||
273 | */ | ||
274 | if (blk_fs_request(failed)) { | ||
275 | if (ide_end_rq(drive, failed, -EIO, | ||
276 | failed->hard_nr_sectors << 9)) | ||
277 | BUG(); | ||
278 | } else { | ||
279 | if (blk_end_request(failed, -EIO, | ||
280 | failed->data_len)) | ||
281 | BUG(); | ||
282 | } | ||
283 | } else | ||
284 | cdrom_analyze_sense_data(drive, NULL, sense); | ||
285 | } | ||
286 | |||
287 | if (!rq->current_nr_sectors && blk_fs_request(rq)) | ||
288 | uptodate = 1; | ||
289 | /* make sure it's fully ended */ | ||
290 | if (blk_pc_request(rq)) | ||
291 | nsectors = (rq->data_len + 511) >> 9; | ||
292 | if (!nsectors) | ||
293 | nsectors = 1; | ||
294 | |||
295 | ide_debug_log(IDE_DBG_FUNC, "uptodate: 0x%x, nsectors: %d", | ||
296 | uptodate, nsectors); | ||
297 | |||
298 | if (blk_fs_request(rq) == 0 && uptodate <= 0 && rq->errors == 0) | ||
299 | rq->errors = -EIO; | ||
300 | 254 | ||
301 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); | 255 | if (failed) { |
302 | } | 256 | if (failed->sense) { |
257 | sense = failed->sense; | ||
258 | failed->sense_len = rq->sense_len; | ||
259 | } | ||
260 | cdrom_analyze_sense_data(drive, failed, sense); | ||
303 | 261 | ||
304 | static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st) | 262 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) |
305 | { | 263 | BUG(); |
306 | if (st & 0x80) | 264 | } else |
307 | return; | 265 | cdrom_analyze_sense_data(drive, NULL, sense); |
308 | ide_dump_status(drive, msg, st); | ||
309 | } | 266 | } |
310 | 267 | ||
311 | /* | 268 | /* |
312 | * Returns: | 269 | * Returns: |
313 | * 0: if the request should be continued. | 270 | * 0: if the request should be continued. |
314 | * 1: if the request was ended. | 271 | * 1: if the request will be going through error recovery. |
272 | * 2: if the request should be ended. | ||
315 | */ | 273 | */ |
316 | static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | 274 | static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) |
317 | { | 275 | { |
@@ -332,12 +290,6 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
332 | err = ide_read_error(drive); | 290 | err = ide_read_error(drive); |
333 | sense_key = err >> 4; | 291 | sense_key = err >> 4; |
334 | 292 | ||
335 | if (rq == NULL) { | ||
336 | printk(KERN_ERR PFX "%s: missing rq in %s\n", | ||
337 | drive->name, __func__); | ||
338 | return 1; | ||
339 | } | ||
340 | |||
341 | ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " | 293 | ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " |
342 | "rq->cmd_type: 0x%x, err: 0x%x", | 294 | "rq->cmd_type: 0x%x, err: 0x%x", |
343 | stat, good_stat, rq->cmd[0], rq->cmd_type, | 295 | stat, good_stat, rq->cmd[0], rq->cmd_type, |
@@ -350,10 +302,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
350 | * Just give up. | 302 | * Just give up. |
351 | */ | 303 | */ |
352 | rq->cmd_flags |= REQ_FAILED; | 304 | rq->cmd_flags |= REQ_FAILED; |
353 | cdrom_end_request(drive, 0); | 305 | return 2; |
354 | ide_error(drive, "request sense failure", stat); | ||
355 | return 1; | ||
356 | |||
357 | } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { | 306 | } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { |
358 | /* All other functions, except for READ. */ | 307 | /* All other functions, except for READ. */ |
359 | 308 | ||
@@ -456,21 +405,19 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
456 | * No point in retrying after an illegal request or data | 405 | * No point in retrying after an illegal request or data |
457 | * protect error. | 406 | * protect error. |
458 | */ | 407 | */ |
459 | ide_dump_status_no_sense(drive, "command error", stat); | 408 | ide_dump_status(drive, "command error", stat); |
460 | do_end_request = 1; | 409 | do_end_request = 1; |
461 | } else if (sense_key == MEDIUM_ERROR) { | 410 | } else if (sense_key == MEDIUM_ERROR) { |
462 | /* | 411 | /* |
463 | * No point in re-trying a zillion times on a bad | 412 | * No point in re-trying a zillion times on a bad |
464 | * sector. If we got here the error is not correctable. | 413 | * sector. If we got here the error is not correctable. |
465 | */ | 414 | */ |
466 | ide_dump_status_no_sense(drive, | 415 | ide_dump_status(drive, "media error (bad sector)", |
467 | "media error (bad sector)", | 416 | stat); |
468 | stat); | ||
469 | do_end_request = 1; | 417 | do_end_request = 1; |
470 | } else if (sense_key == BLANK_CHECK) { | 418 | } else if (sense_key == BLANK_CHECK) { |
471 | /* disk appears blank ?? */ | 419 | /* disk appears blank ?? */ |
472 | ide_dump_status_no_sense(drive, "media error (blank)", | 420 | ide_dump_status(drive, "media error (blank)", stat); |
473 | stat); | ||
474 | do_end_request = 1; | 421 | do_end_request = 1; |
475 | } else if ((err & ~ATA_ABORTED) != 0) { | 422 | } else if ((err & ~ATA_ABORTED) != 0) { |
476 | /* go to the default handler for other errors */ | 423 | /* go to the default handler for other errors */ |
@@ -495,14 +442,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
495 | */ | 442 | */ |
496 | if (stat & ATA_ERR) | 443 | if (stat & ATA_ERR) |
497 | cdrom_queue_request_sense(drive, NULL, NULL); | 444 | cdrom_queue_request_sense(drive, NULL, NULL); |
445 | return 1; | ||
498 | } else { | 446 | } else { |
499 | blk_dump_rq_flags(rq, PFX "bad rq"); | 447 | blk_dump_rq_flags(rq, PFX "bad rq"); |
500 | cdrom_end_request(drive, 0); | 448 | return 2; |
501 | } | 449 | } |
502 | 450 | ||
503 | /* retry, or handle the next request */ | ||
504 | return 1; | ||
505 | |||
506 | end_request: | 451 | end_request: |
507 | if (stat & ATA_ERR) { | 452 | if (stat & ATA_ERR) { |
508 | struct request_queue *q = drive->queue; | 453 | struct request_queue *q = drive->queue; |
@@ -515,10 +460,9 @@ end_request: | |||
515 | hwif->rq = NULL; | 460 | hwif->rq = NULL; |
516 | 461 | ||
517 | cdrom_queue_request_sense(drive, rq->sense, rq); | 462 | cdrom_queue_request_sense(drive, rq->sense, rq); |
463 | return 1; | ||
518 | } else | 464 | } else |
519 | cdrom_end_request(drive, 0); | 465 | return 2; |
520 | |||
521 | return 1; | ||
522 | } | 466 | } |
523 | 467 | ||
524 | /* | 468 | /* |
@@ -562,101 +506,13 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, | |||
562 | if (rq->cmd_type == REQ_TYPE_ATA_PC) | 506 | if (rq->cmd_type == REQ_TYPE_ATA_PC) |
563 | rq->cmd_flags |= REQ_FAILED; | 507 | rq->cmd_flags |= REQ_FAILED; |
564 | 508 | ||
565 | cdrom_end_request(drive, 0); | ||
566 | return -1; | 509 | return -1; |
567 | } | 510 | } |
568 | 511 | ||
569 | /* | 512 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) |
570 | * Assume that the drive will always provide data in multiples of at least | ||
571 | * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise. | ||
572 | */ | ||
573 | static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) | ||
574 | { | 513 | { |
575 | ide_debug_log(IDE_DBG_FUNC, "len: %d", len); | 514 | struct request *rq = cmd->rq; |
576 | |||
577 | if ((len % SECTOR_SIZE) == 0) | ||
578 | return 0; | ||
579 | 515 | ||
580 | printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name, | ||
581 | __func__, len); | ||
582 | |||
583 | if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES) | ||
584 | printk(KERN_ERR PFX "This drive is not supported by this " | ||
585 | "version of the driver\n"); | ||
586 | else { | ||
587 | printk(KERN_ERR PFX "Trying to limit transfer sizes\n"); | ||
588 | drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES; | ||
589 | } | ||
590 | |||
591 | return 1; | ||
592 | } | ||
593 | |||
594 | static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, | ||
595 | struct request *rq) | ||
596 | { | ||
597 | ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags); | ||
598 | |||
599 | if (rq_data_dir(rq) == READ) { | ||
600 | unsigned short sectors_per_frame = | ||
601 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; | ||
602 | int nskip = rq->sector & (sectors_per_frame - 1); | ||
603 | |||
604 | /* | ||
605 | * If the requested sector doesn't start on a frame boundary, | ||
606 | * we must adjust the start of the transfer so that it does, | ||
607 | * and remember to skip the first few sectors. | ||
608 | * | ||
609 | * If the rq->current_nr_sectors field is larger than the size | ||
610 | * of the buffer, it will mean that we're to skip a number of | ||
611 | * sectors equal to the amount by which rq->current_nr_sectors | ||
612 | * is larger than the buffer size. | ||
613 | */ | ||
614 | if (nskip > 0) { | ||
615 | /* sanity check... */ | ||
616 | if (rq->current_nr_sectors != | ||
617 | bio_cur_sectors(rq->bio)) { | ||
618 | printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n", | ||
619 | drive->name, __func__, | ||
620 | rq->current_nr_sectors); | ||
621 | cdrom_end_request(drive, 0); | ||
622 | return ide_stopped; | ||
623 | } | ||
624 | rq->current_nr_sectors += nskip; | ||
625 | } | ||
626 | } | ||
627 | |||
628 | /* set up the command */ | ||
629 | rq->timeout = ATAPI_WAIT_PC; | ||
630 | |||
631 | return ide_started; | ||
632 | } | ||
633 | |||
634 | /* | ||
635 | * Fix up a possibly partially-processed request so that we can start it over | ||
636 | * entirely, or even put it back on the request queue. | ||
637 | */ | ||
638 | static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) | ||
639 | { | ||
640 | |||
641 | ide_debug_log(IDE_DBG_FUNC, "enter"); | ||
642 | |||
643 | if (rq->buffer != bio_data(rq->bio)) { | ||
644 | sector_t n = | ||
645 | (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE; | ||
646 | |||
647 | rq->buffer = bio_data(rq->bio); | ||
648 | rq->nr_sectors += n; | ||
649 | rq->sector -= n; | ||
650 | } | ||
651 | rq->current_nr_sectors = bio_cur_sectors(rq->bio); | ||
652 | rq->hard_cur_sectors = rq->current_nr_sectors; | ||
653 | rq->hard_nr_sectors = rq->nr_sectors; | ||
654 | rq->hard_sector = rq->sector; | ||
655 | rq->q->prep_rq_fn(rq->q, rq); | ||
656 | } | ||
657 | |||
658 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) | ||
659 | { | ||
660 | ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); | 516 | ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); |
661 | 517 | ||
662 | /* | 518 | /* |
@@ -664,11 +520,14 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) | |||
664 | * and some drives don't send them. Sigh. | 520 | * and some drives don't send them. Sigh. |
665 | */ | 521 | */ |
666 | if (rq->cmd[0] == GPCMD_REQUEST_SENSE && | 522 | if (rq->cmd[0] == GPCMD_REQUEST_SENSE && |
667 | rq->data_len > 0 && rq->data_len <= 5) | 523 | cmd->nleft > 0 && cmd->nleft <= 5) { |
668 | while (rq->data_len > 0) { | 524 | unsigned int ofs = cmd->nbytes - cmd->nleft; |
669 | *(u8 *)rq->data++ = 0; | 525 | |
670 | --rq->data_len; | 526 | while (cmd->nleft > 0) { |
527 | *((u8 *)rq->data + ofs++) = 0; | ||
528 | cmd->nleft--; | ||
671 | } | 529 | } |
530 | } | ||
672 | } | 531 | } |
673 | 532 | ||
674 | int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | 533 | int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, |
@@ -748,24 +607,26 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | |||
748 | return (flags & REQ_FAILED) ? -EIO : 0; | 607 | return (flags & REQ_FAILED) ? -EIO : 0; |
749 | } | 608 | } |
750 | 609 | ||
751 | /* | 610 | static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) |
752 | * Called from blk_end_request_callback() after the data of the request is | ||
753 | * completed and before the request itself is completed. By returning value '1', | ||
754 | * blk_end_request_callback() returns immediately without completing it. | ||
755 | */ | ||
756 | static int cdrom_newpc_intr_dummy_cb(struct request *rq) | ||
757 | { | 611 | { |
758 | return 1; | 612 | unsigned int nr_bytes = cmd->nbytes - cmd->nleft; |
613 | |||
614 | if (cmd->tf_flags & IDE_TFLAG_WRITE) | ||
615 | nr_bytes -= cmd->last_xfer_len; | ||
616 | |||
617 | if (nr_bytes > 0) | ||
618 | ide_complete_rq(drive, 0, nr_bytes); | ||
759 | } | 619 | } |
760 | 620 | ||
761 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | 621 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) |
762 | { | 622 | { |
763 | ide_hwif_t *hwif = drive->hwif; | 623 | ide_hwif_t *hwif = drive->hwif; |
624 | struct ide_cmd *cmd = &hwif->cmd; | ||
764 | struct request *rq = hwif->rq; | 625 | struct request *rq = hwif->rq; |
765 | xfer_func_t *xferfunc; | ||
766 | ide_expiry_t *expiry = NULL; | 626 | ide_expiry_t *expiry = NULL; |
767 | int dma_error = 0, dma, stat, thislen, uptodate = 0; | 627 | int dma_error = 0, dma, stat, thislen, uptodate = 0; |
768 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0; | 628 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; |
629 | int sense = blk_sense_request(rq); | ||
769 | unsigned int timeout; | 630 | unsigned int timeout; |
770 | u16 len; | 631 | u16 len; |
771 | u8 ireason; | 632 | u8 ireason; |
@@ -777,7 +638,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
777 | dma = drive->dma; | 638 | dma = drive->dma; |
778 | if (dma) { | 639 | if (dma) { |
779 | drive->dma = 0; | 640 | drive->dma = 0; |
641 | drive->waiting_for_dma = 0; | ||
780 | dma_error = hwif->dma_ops->dma_end(drive); | 642 | dma_error = hwif->dma_ops->dma_end(drive); |
643 | ide_dma_unmap_sg(drive, cmd); | ||
781 | if (dma_error) { | 644 | if (dma_error) { |
782 | printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, | 645 | printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, |
783 | write ? "write" : "read"); | 646 | write ? "write" : "read"); |
@@ -785,27 +648,24 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
785 | } | 648 | } |
786 | } | 649 | } |
787 | 650 | ||
788 | if (cdrom_decode_status(drive, 0, &stat)) | 651 | rc = cdrom_decode_status(drive, 0, &stat); |
652 | if (rc) { | ||
653 | if (rc == 2) | ||
654 | goto out_end; | ||
789 | return ide_stopped; | 655 | return ide_stopped; |
656 | } | ||
790 | 657 | ||
791 | /* using dma, transfer is complete now */ | 658 | /* using dma, transfer is complete now */ |
792 | if (dma) { | 659 | if (dma) { |
793 | if (dma_error) | 660 | if (dma_error) |
794 | return ide_error(drive, "dma error", stat); | 661 | return ide_error(drive, "dma error", stat); |
795 | if (blk_fs_request(rq)) { | 662 | uptodate = 1; |
796 | ide_complete_rq(drive, 0, rq->nr_sectors | 663 | goto out_end; |
797 | ? (rq->nr_sectors << 9) : ide_rq_bytes(rq)); | ||
798 | return ide_stopped; | ||
799 | } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) { | ||
800 | ide_complete_rq(drive, 0, 512); | ||
801 | return ide_stopped; | ||
802 | } | ||
803 | goto end_request; | ||
804 | } | 664 | } |
805 | 665 | ||
806 | ide_read_bcount_and_ireason(drive, &len, &ireason); | 666 | ide_read_bcount_and_ireason(drive, &len, &ireason); |
807 | 667 | ||
808 | thislen = blk_fs_request(rq) ? len : rq->data_len; | 668 | thislen = blk_fs_request(rq) ? len : cmd->nleft; |
809 | if (thislen > len) | 669 | if (thislen > len) |
810 | thislen = len; | 670 | thislen = len; |
811 | 671 | ||
@@ -820,60 +680,30 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
820 | * Otherwise, complete the command normally. | 680 | * Otherwise, complete the command normally. |
821 | */ | 681 | */ |
822 | uptodate = 1; | 682 | uptodate = 1; |
823 | if (rq->current_nr_sectors > 0) { | 683 | if (cmd->nleft > 0) { |
824 | printk(KERN_ERR PFX "%s: %s: data underrun " | 684 | printk(KERN_ERR PFX "%s: %s: data underrun " |
825 | "(%d blocks)\n", | 685 | "(%u bytes)\n", drive->name, __func__, |
826 | drive->name, __func__, | 686 | cmd->nleft); |
827 | rq->current_nr_sectors); | ||
828 | if (!write) | 687 | if (!write) |
829 | rq->cmd_flags |= REQ_FAILED; | 688 | rq->cmd_flags |= REQ_FAILED; |
830 | uptodate = 0; | 689 | uptodate = 0; |
831 | } | 690 | } |
832 | cdrom_end_request(drive, uptodate); | ||
833 | return ide_stopped; | ||
834 | } else if (!blk_pc_request(rq)) { | 691 | } else if (!blk_pc_request(rq)) { |
835 | ide_cd_request_sense_fixup(drive, rq); | 692 | ide_cd_request_sense_fixup(drive, cmd); |
836 | /* complain if we still have data left to transfer */ | 693 | /* complain if we still have data left to transfer */ |
837 | uptodate = rq->data_len ? 0 : 1; | 694 | uptodate = cmd->nleft ? 0 : 1; |
695 | if (uptodate == 0) | ||
696 | rq->cmd_flags |= REQ_FAILED; | ||
838 | } | 697 | } |
839 | goto end_request; | 698 | goto out_end; |
840 | } | 699 | } |
841 | 700 | ||
842 | /* check which way to transfer data */ | 701 | /* check which way to transfer data */ |
843 | if (ide_cd_check_ireason(drive, rq, len, ireason, write)) | 702 | rc = ide_cd_check_ireason(drive, rq, len, ireason, write); |
844 | return ide_stopped; | 703 | if (rc) |
704 | goto out_end; | ||
845 | 705 | ||
846 | if (blk_fs_request(rq)) { | 706 | cmd->last_xfer_len = 0; |
847 | if (write == 0) { | ||
848 | int nskip; | ||
849 | |||
850 | if (ide_cd_check_transfer_size(drive, len)) { | ||
851 | cdrom_end_request(drive, 0); | ||
852 | return ide_stopped; | ||
853 | } | ||
854 | |||
855 | /* | ||
856 | * First, figure out if we need to bit-bucket | ||
857 | * any of the leading sectors. | ||
858 | */ | ||
859 | nskip = min_t(int, rq->current_nr_sectors | ||
860 | - bio_cur_sectors(rq->bio), | ||
861 | thislen >> 9); | ||
862 | if (nskip > 0) { | ||
863 | ide_pad_transfer(drive, write, nskip << 9); | ||
864 | rq->current_nr_sectors -= nskip; | ||
865 | thislen -= (nskip << 9); | ||
866 | } | ||
867 | } | ||
868 | } | ||
869 | |||
870 | if (ireason == 0) { | ||
871 | write = 1; | ||
872 | xferfunc = hwif->tp_ops->output_data; | ||
873 | } else { | ||
874 | write = 0; | ||
875 | xferfunc = hwif->tp_ops->input_data; | ||
876 | } | ||
877 | 707 | ||
878 | ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " | 708 | ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " |
879 | "ireason: 0x%x", | 709 | "ireason: 0x%x", |
@@ -881,75 +711,31 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
881 | 711 | ||
882 | /* transfer data */ | 712 | /* transfer data */ |
883 | while (thislen > 0) { | 713 | while (thislen > 0) { |
884 | u8 *ptr = blk_fs_request(rq) ? NULL : rq->data; | 714 | int blen = min_t(int, thislen, cmd->nleft); |
885 | int blen = rq->data_len; | ||
886 | |||
887 | /* bio backed? */ | ||
888 | if (rq->bio) { | ||
889 | if (blk_fs_request(rq)) { | ||
890 | ptr = rq->buffer; | ||
891 | blen = rq->current_nr_sectors << 9; | ||
892 | } else { | ||
893 | ptr = bio_data(rq->bio); | ||
894 | blen = bio_iovec(rq->bio)->bv_len; | ||
895 | } | ||
896 | } | ||
897 | 715 | ||
898 | if (!ptr) { | 716 | if (cmd->nleft == 0) |
899 | if (blk_fs_request(rq) && !write) | ||
900 | /* | ||
901 | * If the buffers are full, pipe the rest into | ||
902 | * oblivion. | ||
903 | */ | ||
904 | ide_pad_transfer(drive, 0, thislen); | ||
905 | else { | ||
906 | printk(KERN_ERR PFX "%s: confused, missing data\n", | ||
907 | drive->name); | ||
908 | blk_dump_rq_flags(rq, rq_data_dir(rq) | ||
909 | ? "cdrom_newpc_intr, write" | ||
910 | : "cdrom_newpc_intr, read"); | ||
911 | } | ||
912 | break; | 717 | break; |
913 | } | ||
914 | |||
915 | if (blen > thislen) | ||
916 | blen = thislen; | ||
917 | 718 | ||
918 | xferfunc(drive, NULL, ptr, blen); | 719 | ide_pio_bytes(drive, cmd, write, blen); |
720 | cmd->last_xfer_len += blen; | ||
919 | 721 | ||
920 | thislen -= blen; | 722 | thislen -= blen; |
921 | len -= blen; | 723 | len -= blen; |
922 | 724 | ||
923 | if (blk_fs_request(rq)) { | 725 | if (sense && write == 0) |
924 | rq->buffer += blen; | ||
925 | rq->nr_sectors -= (blen >> 9); | ||
926 | rq->current_nr_sectors -= (blen >> 9); | ||
927 | rq->sector += (blen >> 9); | ||
928 | |||
929 | if (rq->current_nr_sectors == 0 && rq->nr_sectors) | ||
930 | cdrom_end_request(drive, 1); | ||
931 | } else { | ||
932 | rq->data_len -= blen; | ||
933 | |||
934 | /* | ||
935 | * The request can't be completed until DRQ is cleared. | ||
936 | * So complete the data, but don't complete the request | ||
937 | * using the dummy function for the callback feature | ||
938 | * of blk_end_request_callback(). | ||
939 | */ | ||
940 | if (rq->bio) | ||
941 | blk_end_request_callback(rq, 0, blen, | ||
942 | cdrom_newpc_intr_dummy_cb); | ||
943 | else | ||
944 | rq->data += blen; | ||
945 | } | ||
946 | if (!write && blk_sense_request(rq)) | ||
947 | rq->sense_len += blen; | 726 | rq->sense_len += blen; |
948 | } | 727 | } |
949 | 728 | ||
950 | /* pad, if necessary */ | 729 | /* pad, if necessary */ |
951 | if (!blk_fs_request(rq) && len > 0) | 730 | if (len > 0) { |
952 | ide_pad_transfer(drive, write, len); | 731 | if (blk_fs_request(rq) == 0 || write == 0) |
732 | ide_pad_transfer(drive, write, len); | ||
733 | else { | ||
734 | printk(KERN_ERR PFX "%s: confused, missing data\n", | ||
735 | drive->name); | ||
736 | blk_dump_rq_flags(rq, "cdrom_newpc_intr"); | ||
737 | } | ||
738 | } | ||
953 | 739 | ||
954 | if (blk_pc_request(rq)) { | 740 | if (blk_pc_request(rq)) { |
955 | timeout = rq->timeout; | 741 | timeout = rq->timeout; |
@@ -963,21 +749,50 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
963 | ide_set_handler(drive, cdrom_newpc_intr, timeout); | 749 | ide_set_handler(drive, cdrom_newpc_intr, timeout); |
964 | return ide_started; | 750 | return ide_started; |
965 | 751 | ||
966 | end_request: | 752 | out_end: |
967 | if (blk_pc_request(rq)) { | 753 | if (blk_pc_request(rq) && rc == 0) { |
968 | unsigned int dlen = rq->data_len; | 754 | unsigned int dlen = rq->data_len; |
969 | 755 | ||
970 | if (dma) | 756 | rq->data_len = 0; |
971 | rq->data_len = 0; | ||
972 | 757 | ||
973 | if (blk_end_request(rq, 0, dlen)) | 758 | if (blk_end_request(rq, 0, dlen)) |
974 | BUG(); | 759 | BUG(); |
975 | 760 | ||
976 | hwif->rq = NULL; | 761 | hwif->rq = NULL; |
977 | } else { | 762 | } else { |
978 | if (!uptodate) | 763 | if (sense && uptodate) |
979 | rq->cmd_flags |= REQ_FAILED; | 764 | ide_cd_complete_failed_rq(drive, rq); |
980 | cdrom_end_request(drive, uptodate); | 765 | |
766 | if (blk_fs_request(rq)) { | ||
767 | if (cmd->nleft == 0) | ||
768 | uptodate = 1; | ||
769 | } else { | ||
770 | if (uptodate <= 0 && rq->errors == 0) | ||
771 | rq->errors = -EIO; | ||
772 | } | ||
773 | |||
774 | if (uptodate == 0) | ||
775 | ide_cd_error_cmd(drive, cmd); | ||
776 | |||
777 | /* make sure it's fully ended */ | ||
778 | if (blk_pc_request(rq)) | ||
779 | nsectors = (rq->data_len + 511) >> 9; | ||
780 | else | ||
781 | nsectors = rq->hard_nr_sectors; | ||
782 | |||
783 | if (nsectors == 0) | ||
784 | nsectors = 1; | ||
785 | |||
786 | if (blk_fs_request(rq) == 0) { | ||
787 | rq->data_len -= (cmd->nbytes - cmd->nleft); | ||
788 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) | ||
789 | rq->data_len += cmd->last_xfer_len; | ||
790 | } | ||
791 | |||
792 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); | ||
793 | |||
794 | if (sense && rc == 2) | ||
795 | ide_error(drive, "request sense failure", stat); | ||
981 | } | 796 | } |
982 | return ide_stopped; | 797 | return ide_stopped; |
983 | } | 798 | } |
@@ -985,42 +800,40 @@ end_request: | |||
985 | static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | 800 | static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) |
986 | { | 801 | { |
987 | struct cdrom_info *cd = drive->driver_data; | 802 | struct cdrom_info *cd = drive->driver_data; |
803 | struct request_queue *q = drive->queue; | ||
988 | int write = rq_data_dir(rq) == WRITE; | 804 | int write = rq_data_dir(rq) == WRITE; |
989 | unsigned short sectors_per_frame = | 805 | unsigned short sectors_per_frame = |
990 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; | 806 | queue_hardsect_size(q) >> SECTOR_BITS; |
991 | 807 | ||
992 | ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, " | 808 | ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, " |
993 | "secs_per_frame: %u", | 809 | "secs_per_frame: %u", |
994 | rq->cmd[0], write, sectors_per_frame); | 810 | rq->cmd[0], rq->cmd_flags, sectors_per_frame); |
995 | 811 | ||
996 | if (write) { | 812 | if (write) { |
997 | /* disk has become write protected */ | 813 | /* disk has become write protected */ |
998 | if (get_disk_ro(cd->disk)) { | 814 | if (get_disk_ro(cd->disk)) |
999 | cdrom_end_request(drive, 0); | ||
1000 | return ide_stopped; | 815 | return ide_stopped; |
1001 | } | ||
1002 | } else { | 816 | } else { |
1003 | /* | 817 | /* |
1004 | * We may be retrying this request after an error. Fix up any | 818 | * We may be retrying this request after an error. Fix up any |
1005 | * weirdness which might be present in the request packet. | 819 | * weirdness which might be present in the request packet. |
1006 | */ | 820 | */ |
1007 | ide_cd_restore_request(drive, rq); | 821 | q->prep_rq_fn(q, rq); |
1008 | } | 822 | } |
1009 | 823 | ||
1010 | /* use DMA, if possible / writes *must* be hardware frame aligned */ | 824 | /* fs requests *must* be hardware frame aligned */ |
1011 | if ((rq->nr_sectors & (sectors_per_frame - 1)) || | 825 | if ((rq->nr_sectors & (sectors_per_frame - 1)) || |
1012 | (rq->sector & (sectors_per_frame - 1))) { | 826 | (rq->sector & (sectors_per_frame - 1))) |
1013 | if (write) { | 827 | return ide_stopped; |
1014 | cdrom_end_request(drive, 0); | 828 | |
1015 | return ide_stopped; | 829 | /* use DMA, if possible */ |
1016 | } | 830 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
1017 | drive->dma = 0; | ||
1018 | } else | ||
1019 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
1020 | 831 | ||
1021 | if (write) | 832 | if (write) |
1022 | cd->devinfo.media_written = 1; | 833 | cd->devinfo.media_written = 1; |
1023 | 834 | ||
835 | rq->timeout = ATAPI_WAIT_PC; | ||
836 | |||
1024 | return ide_started; | 837 | return ide_started; |
1025 | } | 838 | } |
1026 | 839 | ||
@@ -1068,6 +881,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1068 | sector_t block) | 881 | sector_t block) |
1069 | { | 882 | { |
1070 | struct ide_cmd cmd; | 883 | struct ide_cmd cmd; |
884 | int uptodate = 0, nsectors; | ||
1071 | 885 | ||
1072 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", | 886 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", |
1073 | rq->cmd[0], (unsigned long long)block); | 887 | rq->cmd[0], (unsigned long long)block); |
@@ -1077,10 +891,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1077 | 891 | ||
1078 | if (blk_fs_request(rq)) { | 892 | if (blk_fs_request(rq)) { |
1079 | if (cdrom_start_rw(drive, rq) == ide_stopped) | 893 | if (cdrom_start_rw(drive, rq) == ide_stopped) |
1080 | return ide_stopped; | 894 | goto out_end; |
1081 | |||
1082 | if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped) | ||
1083 | return ide_stopped; | ||
1084 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || | 895 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || |
1085 | rq->cmd_type == REQ_TYPE_ATA_PC) { | 896 | rq->cmd_type == REQ_TYPE_ATA_PC) { |
1086 | if (!rq->timeout) | 897 | if (!rq->timeout) |
@@ -1089,12 +900,13 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1089 | cdrom_do_block_pc(drive, rq); | 900 | cdrom_do_block_pc(drive, rq); |
1090 | } else if (blk_special_request(rq)) { | 901 | } else if (blk_special_request(rq)) { |
1091 | /* right now this can only be a reset... */ | 902 | /* right now this can only be a reset... */ |
1092 | cdrom_end_request(drive, 1); | 903 | uptodate = 1; |
1093 | return ide_stopped; | 904 | goto out_end; |
1094 | } else { | 905 | } else { |
1095 | blk_dump_rq_flags(rq, DRV_NAME " bad flags"); | 906 | blk_dump_rq_flags(rq, DRV_NAME " bad flags"); |
1096 | cdrom_end_request(drive, 0); | 907 | if (rq->errors == 0) |
1097 | return ide_stopped; | 908 | rq->errors = -EIO; |
909 | goto out_end; | ||
1098 | } | 910 | } |
1099 | 911 | ||
1100 | memset(&cmd, 0, sizeof(cmd)); | 912 | memset(&cmd, 0, sizeof(cmd)); |
@@ -1104,7 +916,22 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1104 | 916 | ||
1105 | cmd.rq = rq; | 917 | cmd.rq = rq; |
1106 | 918 | ||
919 | if (blk_fs_request(rq) || rq->data_len) { | ||
920 | ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9) | ||
921 | : rq->data_len); | ||
922 | ide_map_sg(drive, &cmd); | ||
923 | } | ||
924 | |||
1107 | return ide_issue_pc(drive, &cmd); | 925 | return ide_issue_pc(drive, &cmd); |
926 | out_end: | ||
927 | nsectors = rq->hard_nr_sectors; | ||
928 | |||
929 | if (nsectors == 0) | ||
930 | nsectors = 1; | ||
931 | |||
932 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); | ||
933 | |||
934 | return ide_stopped; | ||
1108 | } | 935 | } |
1109 | 936 | ||
1110 | /* | 937 | /* |
@@ -1696,9 +1523,6 @@ static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) | |||
1696 | #endif | 1523 | #endif |
1697 | 1524 | ||
1698 | static const struct cd_list_entry ide_cd_quirks_list[] = { | 1525 | static const struct cd_list_entry ide_cd_quirks_list[] = { |
1699 | /* Limit transfer size per interrupt. */ | ||
1700 | { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_AFLAG_LIMIT_NFRAMES }, | ||
1701 | { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_AFLAG_LIMIT_NFRAMES }, | ||
1702 | /* SCR-3231 doesn't support the SET_CD_SPEED command. */ | 1526 | /* SCR-3231 doesn't support the SET_CD_SPEED command. */ |
1703 | { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT }, | 1527 | { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT }, |
1704 | /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ | 1528 | /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ |
@@ -1759,18 +1583,18 @@ static int ide_cdrom_setup(ide_drive_t *drive) | |||
1759 | { | 1583 | { |
1760 | struct cdrom_info *cd = drive->driver_data; | 1584 | struct cdrom_info *cd = drive->driver_data; |
1761 | struct cdrom_device_info *cdi = &cd->devinfo; | 1585 | struct cdrom_device_info *cdi = &cd->devinfo; |
1586 | struct request_queue *q = drive->queue; | ||
1762 | u16 *id = drive->id; | 1587 | u16 *id = drive->id; |
1763 | char *fw_rev = (char *)&id[ATA_ID_FW_REV]; | 1588 | char *fw_rev = (char *)&id[ATA_ID_FW_REV]; |
1764 | int nslots; | 1589 | int nslots; |
1765 | 1590 | ||
1766 | ide_debug_log(IDE_DBG_PROBE, "enter"); | 1591 | ide_debug_log(IDE_DBG_PROBE, "enter"); |
1767 | 1592 | ||
1768 | blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); | 1593 | blk_queue_prep_rq(q, ide_cdrom_prep_fn); |
1769 | blk_queue_dma_alignment(drive->queue, 31); | 1594 | blk_queue_dma_alignment(q, 31); |
1770 | blk_queue_update_dma_pad(drive->queue, 15); | 1595 | blk_queue_update_dma_pad(q, 15); |
1771 | drive->queue->unplug_delay = (1 * HZ) / 1000; | 1596 | |
1772 | if (!drive->queue->unplug_delay) | 1597 | q->unplug_delay = max((1 * HZ) / 1000, 1); |
1773 | drive->queue->unplug_delay = 1; | ||
1774 | 1598 | ||
1775 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; | 1599 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
1776 | drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); | 1600 | drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); |
@@ -1788,8 +1612,7 @@ static int ide_cdrom_setup(ide_drive_t *drive) | |||
1788 | 1612 | ||
1789 | nslots = ide_cdrom_probe_capabilities(drive); | 1613 | nslots = ide_cdrom_probe_capabilities(drive); |
1790 | 1614 | ||
1791 | /* set correct block size */ | 1615 | blk_queue_hardsect_size(q, CD_FRAMESIZE); |
1792 | blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); | ||
1793 | 1616 | ||
1794 | if (ide_cdrom_register(drive, nslots)) { | 1617 | if (ide_cdrom_register(drive, nslots)) { |
1795 | printk(KERN_ERR PFX "%s: %s failed to register device with the" | 1618 | printk(KERN_ERR PFX "%s: %s failed to register device with the" |
@@ -1968,9 +1791,6 @@ static struct block_device_operations idecd_ops = { | |||
1968 | }; | 1791 | }; |
1969 | 1792 | ||
1970 | /* module options */ | 1793 | /* module options */ |
1971 | static char *ignore; | ||
1972 | module_param(ignore, charp, 0400); | ||
1973 | |||
1974 | static unsigned long debug_mask; | 1794 | static unsigned long debug_mask; |
1975 | module_param(debug_mask, ulong, 0644); | 1795 | module_param(debug_mask, ulong, 0644); |
1976 | 1796 | ||
@@ -1991,15 +1811,6 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
1991 | if (drive->media != ide_cdrom && drive->media != ide_optical) | 1811 | if (drive->media != ide_cdrom && drive->media != ide_optical) |
1992 | goto failed; | 1812 | goto failed; |
1993 | 1813 | ||
1994 | /* skip drives that we were told to ignore */ | ||
1995 | if (ignore != NULL) { | ||
1996 | if (strstr(ignore, drive->name)) { | ||
1997 | printk(KERN_INFO PFX "ignoring drive %s\n", | ||
1998 | drive->name); | ||
1999 | goto failed; | ||
2000 | } | ||
2001 | } | ||
2002 | |||
2003 | drive->debug_mask = debug_mask; | 1814 | drive->debug_mask = debug_mask; |
2004 | drive->irq_handler = cdrom_newpc_intr; | 1815 | drive->irq_handler = cdrom_newpc_intr; |
2005 | 1816 | ||