diff options
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r-- | drivers/ide/ide-floppy.c | 357 |
1 files changed, 71 insertions, 286 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index f05fbc2bd7a8..b3689437269f 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -286,11 +286,12 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
286 | { | 286 | { |
287 | struct ide_floppy_obj *floppy = drive->driver_data; | 287 | struct ide_floppy_obj *floppy = drive->driver_data; |
288 | 288 | ||
289 | ide_init_drive_cmd(rq); | 289 | blk_rq_init(NULL, rq); |
290 | rq->buffer = (char *) pc; | 290 | rq->buffer = (char *) pc; |
291 | rq->cmd_type = REQ_TYPE_SPECIAL; | 291 | rq->cmd_type = REQ_TYPE_SPECIAL; |
292 | rq->cmd_flags |= REQ_PREEMPT; | ||
292 | rq->rq_disk = floppy->disk; | 293 | rq->rq_disk = floppy->disk; |
293 | (void) ide_do_drive_cmd(drive, rq, ide_preempt); | 294 | ide_do_drive_cmd(drive, rq); |
294 | } | 295 | } |
295 | 296 | ||
296 | static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive) | 297 | static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive) |
@@ -311,50 +312,41 @@ static struct request *idefloppy_next_rq_storage(ide_drive_t *drive) | |||
311 | return (&floppy->rq_stack[floppy->rq_stack_index++]); | 312 | return (&floppy->rq_stack[floppy->rq_stack_index++]); |
312 | } | 313 | } |
313 | 314 | ||
314 | static void idefloppy_request_sense_callback(ide_drive_t *drive) | 315 | static void ide_floppy_callback(ide_drive_t *drive) |
315 | { | 316 | { |
316 | idefloppy_floppy_t *floppy = drive->driver_data; | 317 | idefloppy_floppy_t *floppy = drive->driver_data; |
317 | u8 *buf = floppy->pc->buf; | 318 | struct ide_atapi_pc *pc = floppy->pc; |
319 | int uptodate = pc->error ? 0 : 1; | ||
318 | 320 | ||
319 | debug_log("Reached %s\n", __func__); | 321 | debug_log("Reached %s\n", __func__); |
320 | 322 | ||
321 | if (!floppy->pc->error) { | 323 | if (floppy->failed_pc == pc) |
322 | floppy->sense_key = buf[2] & 0x0F; | 324 | floppy->failed_pc = NULL; |
323 | floppy->asc = buf[12]; | ||
324 | floppy->ascq = buf[13]; | ||
325 | floppy->progress_indication = buf[15] & 0x80 ? | ||
326 | (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; | ||
327 | 325 | ||
328 | if (floppy->failed_pc) | 326 | if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || |
329 | debug_log("pc = %x, sense key = %x, asc = %x," | 327 | (pc->rq && blk_pc_request(pc->rq))) |
330 | " ascq = %x\n", | 328 | uptodate = 1; /* FIXME */ |
331 | floppy->failed_pc->c[0], | 329 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { |
332 | floppy->sense_key, | 330 | u8 *buf = floppy->pc->buf; |
333 | floppy->asc, | ||
334 | floppy->ascq); | ||
335 | else | ||
336 | debug_log("sense key = %x, asc = %x, ascq = %x\n", | ||
337 | floppy->sense_key, | ||
338 | floppy->asc, | ||
339 | floppy->ascq); | ||
340 | 331 | ||
332 | if (!pc->error) { | ||
333 | floppy->sense_key = buf[2] & 0x0F; | ||
334 | floppy->asc = buf[12]; | ||
335 | floppy->ascq = buf[13]; | ||
336 | floppy->progress_indication = buf[15] & 0x80 ? | ||
337 | (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; | ||
341 | 338 | ||
342 | idefloppy_end_request(drive, 1, 0); | 339 | if (floppy->failed_pc) |
343 | } else { | 340 | debug_log("pc = %x, ", floppy->failed_pc->c[0]); |
344 | printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting" | ||
345 | " request!\n"); | ||
346 | idefloppy_end_request(drive, 0, 0); | ||
347 | } | ||
348 | } | ||
349 | 341 | ||
350 | /* General packet command callback function. */ | 342 | debug_log("sense key = %x, asc = %x, ascq = %x\n", |
351 | static void idefloppy_pc_callback(ide_drive_t *drive) | 343 | floppy->sense_key, floppy->asc, floppy->ascq); |
352 | { | 344 | } else |
353 | idefloppy_floppy_t *floppy = drive->driver_data; | 345 | printk(KERN_ERR "Error in REQUEST SENSE itself - " |
354 | 346 | "Aborting request!\n"); | |
355 | debug_log("Reached %s\n", __func__); | 347 | } |
356 | 348 | ||
357 | idefloppy_end_request(drive, floppy->pc->error ? 0 : 1, 0); | 349 | idefloppy_end_request(drive, uptodate, 0); |
358 | } | 350 | } |
359 | 351 | ||
360 | static void idefloppy_init_pc(struct ide_atapi_pc *pc) | 352 | static void idefloppy_init_pc(struct ide_atapi_pc *pc) |
@@ -365,7 +357,7 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc) | |||
365 | pc->req_xfer = 0; | 357 | pc->req_xfer = 0; |
366 | pc->buf = pc->pc_buf; | 358 | pc->buf = pc->pc_buf; |
367 | pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; | 359 | pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; |
368 | pc->idefloppy_callback = &idefloppy_pc_callback; | 360 | pc->callback = ide_floppy_callback; |
369 | } | 361 | } |
370 | 362 | ||
371 | static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) | 363 | static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) |
@@ -374,7 +366,6 @@ static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) | |||
374 | pc->c[0] = GPCMD_REQUEST_SENSE; | 366 | pc->c[0] = GPCMD_REQUEST_SENSE; |
375 | pc->c[4] = 255; | 367 | pc->c[4] = 255; |
376 | pc->req_xfer = 18; | 368 | pc->req_xfer = 18; |
377 | pc->idefloppy_callback = &idefloppy_request_sense_callback; | ||
378 | } | 369 | } |
379 | 370 | ||
380 | /* | 371 | /* |
@@ -397,174 +388,19 @@ static void idefloppy_retry_pc(ide_drive_t *drive) | |||
397 | static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) | 388 | static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) |
398 | { | 389 | { |
399 | idefloppy_floppy_t *floppy = drive->driver_data; | 390 | idefloppy_floppy_t *floppy = drive->driver_data; |
400 | ide_hwif_t *hwif = drive->hwif; | ||
401 | struct ide_atapi_pc *pc = floppy->pc; | ||
402 | struct request *rq = pc->rq; | ||
403 | xfer_func_t *xferfunc; | ||
404 | unsigned int temp; | ||
405 | int dma_error = 0; | ||
406 | u16 bcount; | ||
407 | u8 stat, ireason; | ||
408 | |||
409 | debug_log("Reached %s interrupt handler\n", __func__); | ||
410 | |||
411 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | ||
412 | dma_error = hwif->dma_ops->dma_end(drive); | ||
413 | if (dma_error) { | ||
414 | printk(KERN_ERR "%s: DMA %s error\n", drive->name, | ||
415 | rq_data_dir(rq) ? "write" : "read"); | ||
416 | pc->flags |= PC_FLAG_DMA_ERROR; | ||
417 | } else { | ||
418 | pc->xferred = pc->req_xfer; | ||
419 | idefloppy_update_buffers(drive, pc); | ||
420 | } | ||
421 | debug_log("DMA finished\n"); | ||
422 | } | ||
423 | |||
424 | /* Clear the interrupt */ | ||
425 | stat = ide_read_status(drive); | ||
426 | |||
427 | /* No more interrupts */ | ||
428 | if ((stat & DRQ_STAT) == 0) { | ||
429 | debug_log("Packet command completed, %d bytes transferred\n", | ||
430 | pc->xferred); | ||
431 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | ||
432 | |||
433 | local_irq_enable_in_hardirq(); | ||
434 | |||
435 | if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { | ||
436 | /* Error detected */ | ||
437 | debug_log("%s: I/O error\n", drive->name); | ||
438 | rq->errors++; | ||
439 | if (pc->c[0] == GPCMD_REQUEST_SENSE) { | ||
440 | printk(KERN_ERR "ide-floppy: I/O error in " | ||
441 | "request sense command\n"); | ||
442 | return ide_do_reset(drive); | ||
443 | } | ||
444 | /* Retry operation */ | ||
445 | idefloppy_retry_pc(drive); | ||
446 | /* queued, but not started */ | ||
447 | return ide_stopped; | ||
448 | } | ||
449 | pc->error = 0; | ||
450 | if (floppy->failed_pc == pc) | ||
451 | floppy->failed_pc = NULL; | ||
452 | /* Command finished - Call the callback function */ | ||
453 | pc->idefloppy_callback(drive); | ||
454 | return ide_stopped; | ||
455 | } | ||
456 | |||
457 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | ||
458 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | ||
459 | printk(KERN_ERR "ide-floppy: The floppy wants to issue " | ||
460 | "more interrupts in DMA mode\n"); | ||
461 | ide_dma_off(drive); | ||
462 | return ide_do_reset(drive); | ||
463 | } | ||
464 | |||
465 | /* Get the number of bytes to transfer */ | ||
466 | bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | | ||
467 | hwif->INB(hwif->io_ports.lbam_addr); | ||
468 | /* on this interrupt */ | ||
469 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
470 | |||
471 | if (ireason & CD) { | ||
472 | printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__); | ||
473 | return ide_do_reset(drive); | ||
474 | } | ||
475 | if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { | ||
476 | /* Hopefully, we will never get here */ | ||
477 | printk(KERN_ERR "ide-floppy: We wanted to %s, ", | ||
478 | (ireason & IO) ? "Write" : "Read"); | ||
479 | printk(KERN_ERR "but the floppy wants us to %s !\n", | ||
480 | (ireason & IO) ? "Read" : "Write"); | ||
481 | return ide_do_reset(drive); | ||
482 | } | ||
483 | if (!(pc->flags & PC_FLAG_WRITING)) { | ||
484 | /* Reading - Check that we have enough space */ | ||
485 | temp = pc->xferred + bcount; | ||
486 | if (temp > pc->req_xfer) { | ||
487 | if (temp > pc->buf_size) { | ||
488 | printk(KERN_ERR "ide-floppy: The floppy wants " | ||
489 | "to send us more data than expected " | ||
490 | "- discarding data\n"); | ||
491 | ide_pad_transfer(drive, 0, bcount); | ||
492 | |||
493 | ide_set_handler(drive, | ||
494 | &idefloppy_pc_intr, | ||
495 | IDEFLOPPY_WAIT_CMD, | ||
496 | NULL); | ||
497 | return ide_started; | ||
498 | } | ||
499 | debug_log("The floppy wants to send us more data than" | ||
500 | " expected - allowing transfer\n"); | ||
501 | } | ||
502 | } | ||
503 | if (pc->flags & PC_FLAG_WRITING) | ||
504 | xferfunc = hwif->output_data; | ||
505 | else | ||
506 | xferfunc = hwif->input_data; | ||
507 | |||
508 | if (pc->buf) | ||
509 | xferfunc(drive, NULL, pc->cur_pos, bcount); | ||
510 | else | ||
511 | ide_floppy_io_buffers(drive, pc, bcount, | ||
512 | !!(pc->flags & PC_FLAG_WRITING)); | ||
513 | |||
514 | /* Update the current position */ | ||
515 | pc->xferred += bcount; | ||
516 | pc->cur_pos += bcount; | ||
517 | |||
518 | /* And set the interrupt handler again */ | ||
519 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); | ||
520 | return ide_started; | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * This is the original routine that did the packet transfer. | ||
525 | * It fails at high speeds on the Iomega ZIP drive, so there's a slower version | ||
526 | * for that drive below. The algorithm is chosen based on drive type | ||
527 | */ | ||
528 | static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive) | ||
529 | { | ||
530 | ide_hwif_t *hwif = drive->hwif; | ||
531 | ide_startstop_t startstop; | ||
532 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
533 | u8 ireason; | ||
534 | |||
535 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | ||
536 | printk(KERN_ERR "ide-floppy: Strange, packet command " | ||
537 | "initiated yet DRQ isn't asserted\n"); | ||
538 | return startstop; | ||
539 | } | ||
540 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
541 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
542 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " | ||
543 | "issuing a packet command\n"); | ||
544 | return ide_do_reset(drive); | ||
545 | } | ||
546 | 391 | ||
547 | /* Set the interrupt routine */ | 392 | return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr, |
548 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); | 393 | IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers, |
549 | 394 | idefloppy_retry_pc, NULL, ide_floppy_io_buffers); | |
550 | /* Send the actual packet */ | ||
551 | hwif->output_data(drive, NULL, floppy->pc->c, 12); | ||
552 | |||
553 | return ide_started; | ||
554 | } | 395 | } |
555 | 396 | ||
556 | |||
557 | /* | 397 | /* |
558 | * What we have here is a classic case of a top half / bottom half interrupt | 398 | * What we have here is a classic case of a top half / bottom half interrupt |
559 | * service routine. In interrupt mode, the device sends an interrupt to signal | 399 | * service routine. In interrupt mode, the device sends an interrupt to signal |
560 | * that it is ready to receive a packet. However, we need to delay about 2-3 | 400 | * that it is ready to receive a packet. However, we need to delay about 2-3 |
561 | * ticks before issuing the packet or we gets in trouble. | 401 | * ticks before issuing the packet or we gets in trouble. |
562 | * | ||
563 | * So, follow carefully. transfer_pc1 is called as an interrupt (or directly). | ||
564 | * In either case, when the device says it's ready for a packet, we schedule | ||
565 | * the packet transfer to occur about 2-3 ticks later in transfer_pc2. | ||
566 | */ | 402 | */ |
567 | static int idefloppy_transfer_pc2(ide_drive_t *drive) | 403 | static int idefloppy_transfer_pc(ide_drive_t *drive) |
568 | { | 404 | { |
569 | idefloppy_floppy_t *floppy = drive->driver_data; | 405 | idefloppy_floppy_t *floppy = drive->driver_data; |
570 | 406 | ||
@@ -575,24 +411,19 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) | |||
575 | return IDEFLOPPY_WAIT_CMD; | 411 | return IDEFLOPPY_WAIT_CMD; |
576 | } | 412 | } |
577 | 413 | ||
578 | static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) | 414 | |
415 | /* | ||
416 | * Called as an interrupt (or directly). When the device says it's ready for a | ||
417 | * packet, we schedule the packet transfer to occur about 2-3 ticks later in | ||
418 | * transfer_pc. | ||
419 | */ | ||
420 | static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive) | ||
579 | { | 421 | { |
580 | ide_hwif_t *hwif = drive->hwif; | ||
581 | idefloppy_floppy_t *floppy = drive->driver_data; | 422 | idefloppy_floppy_t *floppy = drive->driver_data; |
582 | ide_startstop_t startstop; | 423 | struct ide_atapi_pc *pc = floppy->pc; |
583 | u8 ireason; | 424 | ide_expiry_t *expiry; |
425 | unsigned int timeout; | ||
584 | 426 | ||
585 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | ||
586 | printk(KERN_ERR "ide-floppy: Strange, packet command " | ||
587 | "initiated yet DRQ isn't asserted\n"); | ||
588 | return startstop; | ||
589 | } | ||
590 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
591 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
592 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " | ||
593 | "while issuing a packet command\n"); | ||
594 | return ide_do_reset(drive); | ||
595 | } | ||
596 | /* | 427 | /* |
597 | * The following delay solves a problem with ATAPI Zip 100 drives | 428 | * The following delay solves a problem with ATAPI Zip 100 drives |
598 | * where the Busy flag was apparently being deasserted before the | 429 | * where the Busy flag was apparently being deasserted before the |
@@ -601,10 +432,15 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) | |||
601 | * 40 and 50msec work well. idefloppy_pc_intr will not be actually | 432 | * 40 and 50msec work well. idefloppy_pc_intr will not be actually |
602 | * used until after the packet is moved in about 50 msec. | 433 | * used until after the packet is moved in about 50 msec. |
603 | */ | 434 | */ |
435 | if (pc->flags & PC_FLAG_ZIP_DRIVE) { | ||
436 | timeout = floppy->ticks; | ||
437 | expiry = &idefloppy_transfer_pc; | ||
438 | } else { | ||
439 | timeout = IDEFLOPPY_WAIT_CMD; | ||
440 | expiry = NULL; | ||
441 | } | ||
604 | 442 | ||
605 | ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks, | 443 | return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); |
606 | &idefloppy_transfer_pc2); | ||
607 | return ide_started; | ||
608 | } | 444 | } |
609 | 445 | ||
610 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | 446 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, |
@@ -627,10 +463,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | |||
627 | struct ide_atapi_pc *pc) | 463 | struct ide_atapi_pc *pc) |
628 | { | 464 | { |
629 | idefloppy_floppy_t *floppy = drive->driver_data; | 465 | idefloppy_floppy_t *floppy = drive->driver_data; |
630 | ide_hwif_t *hwif = drive->hwif; | ||
631 | ide_handler_t *pkt_xfer_routine; | ||
632 | u16 bcount; | ||
633 | u8 dma; | ||
634 | 466 | ||
635 | if (floppy->failed_pc == NULL && | 467 | if (floppy->failed_pc == NULL && |
636 | pc->c[0] != GPCMD_REQUEST_SENSE) | 468 | pc->c[0] != GPCMD_REQUEST_SENSE) |
@@ -645,65 +477,16 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | |||
645 | pc->error = IDEFLOPPY_ERROR_GENERAL; | 477 | pc->error = IDEFLOPPY_ERROR_GENERAL; |
646 | 478 | ||
647 | floppy->failed_pc = NULL; | 479 | floppy->failed_pc = NULL; |
648 | pc->idefloppy_callback(drive); | 480 | pc->callback(drive); |
649 | return ide_stopped; | 481 | return ide_stopped; |
650 | } | 482 | } |
651 | 483 | ||
652 | debug_log("Retry number - %d\n", pc->retries); | 484 | debug_log("Retry number - %d\n", pc->retries); |
653 | 485 | ||
654 | pc->retries++; | 486 | pc->retries++; |
655 | /* We haven't transferred any data yet */ | ||
656 | pc->xferred = 0; | ||
657 | pc->cur_pos = pc->buf; | ||
658 | bcount = min(pc->req_xfer, 63 * 1024); | ||
659 | |||
660 | if (pc->flags & PC_FLAG_DMA_ERROR) { | ||
661 | pc->flags &= ~PC_FLAG_DMA_ERROR; | ||
662 | ide_dma_off(drive); | ||
663 | } | ||
664 | dma = 0; | ||
665 | |||
666 | if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) | ||
667 | dma = !hwif->dma_ops->dma_setup(drive); | ||
668 | 487 | ||
669 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | | 488 | return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer, |
670 | IDE_TFLAG_OUT_DEVICE, bcount, dma); | 489 | IDEFLOPPY_WAIT_CMD, NULL); |
671 | |||
672 | if (dma) { | ||
673 | /* Begin DMA, if necessary */ | ||
674 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
675 | hwif->dma_ops->dma_start(drive); | ||
676 | } | ||
677 | |||
678 | /* Can we transfer the packet when we get the interrupt or wait? */ | ||
679 | if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) { | ||
680 | /* wait */ | ||
681 | pkt_xfer_routine = &idefloppy_transfer_pc1; | ||
682 | } else { | ||
683 | /* immediate */ | ||
684 | pkt_xfer_routine = &idefloppy_transfer_pc; | ||
685 | } | ||
686 | |||
687 | if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) { | ||
688 | /* Issue the packet command */ | ||
689 | ide_execute_command(drive, WIN_PACKETCMD, | ||
690 | pkt_xfer_routine, | ||
691 | IDEFLOPPY_WAIT_CMD, | ||
692 | NULL); | ||
693 | return ide_started; | ||
694 | } else { | ||
695 | /* Issue the packet command */ | ||
696 | ide_execute_pkt_cmd(drive); | ||
697 | return (*pkt_xfer_routine) (drive); | ||
698 | } | ||
699 | } | ||
700 | |||
701 | static void idefloppy_rw_callback(ide_drive_t *drive) | ||
702 | { | ||
703 | debug_log("Reached %s\n", __func__); | ||
704 | |||
705 | idefloppy_end_request(drive, 1, 0); | ||
706 | return; | ||
707 | } | 490 | } |
708 | 491 | ||
709 | static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) | 492 | static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) |
@@ -800,21 +583,19 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, | |||
800 | put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); | 583 | put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); |
801 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); | 584 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); |
802 | 585 | ||
803 | pc->idefloppy_callback = &idefloppy_rw_callback; | ||
804 | pc->rq = rq; | 586 | pc->rq = rq; |
805 | pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; | 587 | pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; |
806 | if (rq->cmd_flags & REQ_RW) | 588 | if (rq->cmd_flags & REQ_RW) |
807 | pc->flags |= PC_FLAG_WRITING; | 589 | pc->flags |= PC_FLAG_WRITING; |
808 | pc->buf = NULL; | 590 | pc->buf = NULL; |
809 | pc->req_xfer = pc->buf_size = blocks * floppy->block_size; | 591 | pc->req_xfer = pc->buf_size = blocks * floppy->block_size; |
810 | pc->flags |= PC_FLAG_DMA_RECOMMENDED; | 592 | pc->flags |= PC_FLAG_DMA_OK; |
811 | } | 593 | } |
812 | 594 | ||
813 | static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | 595 | static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, |
814 | struct ide_atapi_pc *pc, struct request *rq) | 596 | struct ide_atapi_pc *pc, struct request *rq) |
815 | { | 597 | { |
816 | idefloppy_init_pc(pc); | 598 | idefloppy_init_pc(pc); |
817 | pc->idefloppy_callback = &idefloppy_rw_callback; | ||
818 | memcpy(pc->c, rq->cmd, sizeof(pc->c)); | 599 | memcpy(pc->c, rq->cmd, sizeof(pc->c)); |
819 | pc->rq = rq; | 600 | pc->rq = rq; |
820 | pc->b_count = rq->data_len; | 601 | pc->b_count = rq->data_len; |
@@ -822,7 +603,7 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | |||
822 | pc->flags |= PC_FLAG_WRITING; | 603 | pc->flags |= PC_FLAG_WRITING; |
823 | pc->buf = rq->data; | 604 | pc->buf = rq->data; |
824 | if (rq->bio) | 605 | if (rq->bio) |
825 | pc->flags |= PC_FLAG_DMA_RECOMMENDED; | 606 | pc->flags |= PC_FLAG_DMA_OK; |
826 | /* | 607 | /* |
827 | * possibly problematic, doesn't look like ide-floppy correctly | 608 | * possibly problematic, doesn't look like ide-floppy correctly |
828 | * handled scattered requests if dma fails... | 609 | * handled scattered requests if dma fails... |
@@ -875,7 +656,14 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
875 | return ide_stopped; | 656 | return ide_stopped; |
876 | } | 657 | } |
877 | 658 | ||
659 | if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) | ||
660 | pc->flags |= PC_FLAG_DRQ_INTERRUPT; | ||
661 | |||
662 | if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) | ||
663 | pc->flags |= PC_FLAG_ZIP_DRIVE; | ||
664 | |||
878 | pc->rq = rq; | 665 | pc->rq = rq; |
666 | |||
879 | return idefloppy_issue_pc(drive, pc); | 667 | return idefloppy_issue_pc(drive, pc); |
880 | } | 668 | } |
881 | 669 | ||
@@ -886,14 +674,16 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
886 | static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) | 674 | static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) |
887 | { | 675 | { |
888 | struct ide_floppy_obj *floppy = drive->driver_data; | 676 | struct ide_floppy_obj *floppy = drive->driver_data; |
889 | struct request rq; | 677 | struct request *rq; |
678 | int error; | ||
890 | 679 | ||
891 | ide_init_drive_cmd(&rq); | 680 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
892 | rq.buffer = (char *) pc; | 681 | rq->buffer = (char *) pc; |
893 | rq.cmd_type = REQ_TYPE_SPECIAL; | 682 | rq->cmd_type = REQ_TYPE_SPECIAL; |
894 | rq.rq_disk = floppy->disk; | 683 | error = blk_execute_rq(drive->queue, floppy->disk, rq, 0); |
684 | blk_put_request(rq); | ||
895 | 685 | ||
896 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 686 | return error; |
897 | } | 687 | } |
898 | 688 | ||
899 | /* | 689 | /* |
@@ -1622,11 +1412,6 @@ static int ide_floppy_probe(ide_drive_t *drive) | |||
1622 | " of ide-floppy\n", drive->name); | 1412 | " of ide-floppy\n", drive->name); |
1623 | goto failed; | 1413 | goto failed; |
1624 | } | 1414 | } |
1625 | if (drive->scsi) { | ||
1626 | printk(KERN_INFO "ide-floppy: passing drive %s to ide-scsi" | ||
1627 | " emulation.\n", drive->name); | ||
1628 | goto failed; | ||
1629 | } | ||
1630 | floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); | 1415 | floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); |
1631 | if (!floppy) { | 1416 | if (!floppy) { |
1632 | printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" | 1417 | printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" |