aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-atapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-atapi.c')
-rw-r--r--drivers/ide/ide-atapi.c257
1 files changed, 147 insertions, 110 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 4e58b9e7a58a..e96c01260598 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
20static 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}
234EXPORT_SYMBOL_GPL(ide_retry_pc); 242EXPORT_SYMBOL_GPL(ide_retry_pc);
235 243
236int ide_scsi_expiry(ide_drive_t *drive) 244int ide_cd_expiry(ide_drive_t *drive)
237{ 245{
238 struct ide_atapi_pc *pc = drive->pc; 246 struct request *rq = drive->hwif->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}
274EXPORT_SYMBOL_GPL(ide_cd_expiry);
244 275
245 return 0; /* we do not want the IDE subsystem to retry */ 276int 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}
247EXPORT_SYMBOL_GPL(ide_scsi_expiry); 286EXPORT_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
@@ -255,24 +294,17 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
255{ 294{
256 struct ide_atapi_pc *pc = drive->pc; 295 struct ide_atapi_pc *pc = drive->pc;
257 ide_hwif_t *hwif = drive->hwif; 296 ide_hwif_t *hwif = drive->hwif;
258 struct request *rq = hwif->hwgroup->rq; 297 struct request *rq = hwif->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 }
338cmd_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);
431next_irq: 441next_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
480static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) 490static 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->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,127 @@ 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,
553 (dev_is_idecd(drive) ? drive->irq_handler
554 : ide_pc_intr),
555 timeout, expiry);
528 556
529 /* Begin DMA, if necessary */ 557 /* Begin DMA, if necessary */
530 if (pc->flags & PC_FLAG_DMA_OK) { 558 if (dev_is_idecd(drive)) {
531 pc->flags |= PC_FLAG_DMA_IN_PROGRESS; 559 if (drive->dma)
532 hwif->dma_ops->dma_start(drive); 560 hwif->dma_ops->dma_start(drive);
561 } else {
562 if (pc->flags & PC_FLAG_DMA_OK) {
563 pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
564 hwif->dma_ops->dma_start(drive);
565 }
533 } 566 }
534 567
535 /* Send the actual packet */ 568 /* Send the actual packet */
536 if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) 569 if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
537 hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12); 570 hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
538 571
539 return ide_started; 572 return ide_started;
540} 573}
541 574
542ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, 575ide_startstop_t ide_issue_pc(ide_drive_t *drive)
543 ide_expiry_t *expiry)
544{ 576{
545 struct ide_atapi_pc *pc = drive->pc; 577 struct ide_atapi_pc *pc;
546 ide_hwif_t *hwif = drive->hwif; 578 ide_hwif_t *hwif = drive->hwif;
579 ide_expiry_t *expiry = NULL;
580 unsigned int timeout;
547 u32 tf_flags; 581 u32 tf_flags;
548 u16 bcount; 582 u16 bcount;
549 u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI);
550 583
551 /* We haven't transferred any data yet */ 584 if (dev_is_idecd(drive)) {
552 pc->xferred = 0; 585 tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
553 pc->cur_pos = pc->buf; 586 bcount = ide_cd_get_xferlen(hwif->rq);
587 expiry = ide_cd_expiry;
588 timeout = ATAPI_WAIT_PC;
554 589
555 /* Request to transfer the entire buffer at once */ 590 if (drive->dma)
556 if (drive->media == ide_tape && scsi == 0) 591 drive->dma = !hwif->dma_ops->dma_setup(drive);
557 bcount = pc->req_xfer; 592 } else {
558 else 593 pc = drive->pc;
559 bcount = min(pc->req_xfer, 63 * 1024);
560 594
561 if (pc->flags & PC_FLAG_DMA_ERROR) { 595 /* We haven't transferred any data yet */
562 pc->flags &= ~PC_FLAG_DMA_ERROR; 596 pc->xferred = 0;
563 ide_dma_off(drive); 597 pc->cur_pos = pc->buf;
564 }
565 598
566 if ((pc->flags & PC_FLAG_DMA_OK) && 599 tf_flags = IDE_TFLAG_OUT_DEVICE;
567 (drive->dev_flags & IDE_DFLAG_USING_DMA)) { 600 bcount = ((drive->media == ide_tape) ?
568 if (scsi) 601 pc->req_xfer :
569 hwif->sg_mapped = 1; 602 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 603
575 if (!drive->dma) 604 if (pc->flags & PC_FLAG_DMA_ERROR) {
576 pc->flags &= ~PC_FLAG_DMA_OK; 605 pc->flags &= ~PC_FLAG_DMA_ERROR;
606 ide_dma_off(drive);
607 }
577 608
578 if (scsi) 609 if ((pc->flags & PC_FLAG_DMA_OK) &&
579 tf_flags = 0; 610 (drive->dev_flags & IDE_DFLAG_USING_DMA))
580 else if (drive->media == ide_cdrom || drive->media == ide_optical) 611 drive->dma = !hwif->dma_ops->dma_setup(drive);
581 tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; 612
582 else 613 if (!drive->dma)
583 tf_flags = IDE_TFLAG_OUT_DEVICE; 614 pc->flags &= ~PC_FLAG_DMA_OK;
615
616 timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
617 : WAIT_TAPE_CMD;
618 }
584 619
585 ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); 620 ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
586 621
587 /* Issue the packet command */ 622 /* Issue the packet command */
588 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { 623 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
624 if (drive->dma)
625 drive->waiting_for_dma = 0;
589 ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, 626 ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
590 timeout, NULL); 627 timeout, expiry);
591 return ide_started; 628 return ide_started;
592 } else { 629 } else {
593 ide_execute_pkt_cmd(drive); 630 ide_execute_pkt_cmd(drive);