diff options
Diffstat (limited to 'drivers/block/swim3.c')
-rw-r--r-- | drivers/block/swim3.c | 107 |
1 files changed, 54 insertions, 53 deletions
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 612965307ba0..80df93e3cdd0 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -251,6 +251,20 @@ static int floppy_release(struct gendisk *disk, fmode_t mode); | |||
251 | static int floppy_check_change(struct gendisk *disk); | 251 | static int floppy_check_change(struct gendisk *disk); |
252 | static int floppy_revalidate(struct gendisk *disk); | 252 | static int floppy_revalidate(struct gendisk *disk); |
253 | 253 | ||
254 | static bool swim3_end_request(int err, unsigned int nr_bytes) | ||
255 | { | ||
256 | if (__blk_end_request(fd_req, err, nr_bytes)) | ||
257 | return true; | ||
258 | |||
259 | fd_req = NULL; | ||
260 | return false; | ||
261 | } | ||
262 | |||
263 | static bool swim3_end_request_cur(int err) | ||
264 | { | ||
265 | return swim3_end_request(err, blk_rq_cur_bytes(fd_req)); | ||
266 | } | ||
267 | |||
254 | static void swim3_select(struct floppy_state *fs, int sel) | 268 | static void swim3_select(struct floppy_state *fs, int sel) |
255 | { | 269 | { |
256 | struct swim3 __iomem *sw = fs->swim3; | 270 | struct swim3 __iomem *sw = fs->swim3; |
@@ -310,25 +324,27 @@ static void start_request(struct floppy_state *fs) | |||
310 | wake_up(&fs->wait); | 324 | wake_up(&fs->wait); |
311 | return; | 325 | return; |
312 | } | 326 | } |
313 | while (fs->state == idle && (req = elv_next_request(swim3_queue))) { | 327 | while (fs->state == idle) { |
328 | if (!fd_req) { | ||
329 | fd_req = blk_fetch_request(swim3_queue); | ||
330 | if (!fd_req) | ||
331 | break; | ||
332 | } | ||
333 | req = fd_req; | ||
314 | #if 0 | 334 | #if 0 |
315 | printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", | 335 | printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n", |
316 | req->rq_disk->disk_name, req->cmd, | 336 | req->rq_disk->disk_name, req->cmd, |
317 | (long)req->sector, req->nr_sectors, req->buffer); | 337 | (long)blk_rq_pos(req), blk_rq_sectors(req), req->buffer); |
318 | printk(" errors=%d current_nr_sectors=%ld\n", | 338 | printk(" errors=%d current_nr_sectors=%u\n", |
319 | req->errors, req->current_nr_sectors); | 339 | req->errors, blk_rq_cur_sectors(req)); |
320 | #endif | 340 | #endif |
321 | 341 | ||
322 | if (req->sector < 0 || req->sector >= fs->total_secs) { | 342 | if (blk_rq_pos(req) >= fs->total_secs) { |
323 | end_request(req, 0); | 343 | swim3_end_request_cur(-EIO); |
324 | continue; | ||
325 | } | ||
326 | if (req->current_nr_sectors == 0) { | ||
327 | end_request(req, 1); | ||
328 | continue; | 344 | continue; |
329 | } | 345 | } |
330 | if (fs->ejected) { | 346 | if (fs->ejected) { |
331 | end_request(req, 0); | 347 | swim3_end_request_cur(-EIO); |
332 | continue; | 348 | continue; |
333 | } | 349 | } |
334 | 350 | ||
@@ -336,18 +352,19 @@ static void start_request(struct floppy_state *fs) | |||
336 | if (fs->write_prot < 0) | 352 | if (fs->write_prot < 0) |
337 | fs->write_prot = swim3_readbit(fs, WRITE_PROT); | 353 | fs->write_prot = swim3_readbit(fs, WRITE_PROT); |
338 | if (fs->write_prot) { | 354 | if (fs->write_prot) { |
339 | end_request(req, 0); | 355 | swim3_end_request_cur(-EIO); |
340 | continue; | 356 | continue; |
341 | } | 357 | } |
342 | } | 358 | } |
343 | 359 | ||
344 | /* Do not remove the cast. req->sector is now a sector_t and | 360 | /* Do not remove the cast. blk_rq_pos(req) is now a |
345 | * can be 64 bits, but it will never go past 32 bits for this | 361 | * sector_t and can be 64 bits, but it will never go |
346 | * driver anyway, so we can safely cast it down and not have | 362 | * past 32 bits for this driver anyway, so we can |
347 | * to do a 64/32 division | 363 | * safely cast it down and not have to do a 64/32 |
364 | * division | ||
348 | */ | 365 | */ |
349 | fs->req_cyl = ((long)req->sector) / fs->secpercyl; | 366 | fs->req_cyl = ((long)blk_rq_pos(req)) / fs->secpercyl; |
350 | x = ((long)req->sector) % fs->secpercyl; | 367 | x = ((long)blk_rq_pos(req)) % fs->secpercyl; |
351 | fs->head = x / fs->secpertrack; | 368 | fs->head = x / fs->secpertrack; |
352 | fs->req_sector = x % fs->secpertrack + 1; | 369 | fs->req_sector = x % fs->secpertrack + 1; |
353 | fd_req = req; | 370 | fd_req = req; |
@@ -424,7 +441,7 @@ static inline void setup_transfer(struct floppy_state *fs) | |||
424 | struct dbdma_cmd *cp = fs->dma_cmd; | 441 | struct dbdma_cmd *cp = fs->dma_cmd; |
425 | struct dbdma_regs __iomem *dr = fs->dma; | 442 | struct dbdma_regs __iomem *dr = fs->dma; |
426 | 443 | ||
427 | if (fd_req->current_nr_sectors <= 0) { | 444 | if (blk_rq_cur_sectors(fd_req) <= 0) { |
428 | printk(KERN_ERR "swim3: transfer 0 sectors?\n"); | 445 | printk(KERN_ERR "swim3: transfer 0 sectors?\n"); |
429 | return; | 446 | return; |
430 | } | 447 | } |
@@ -432,8 +449,8 @@ static inline void setup_transfer(struct floppy_state *fs) | |||
432 | n = 1; | 449 | n = 1; |
433 | else { | 450 | else { |
434 | n = fs->secpertrack - fs->req_sector + 1; | 451 | n = fs->secpertrack - fs->req_sector + 1; |
435 | if (n > fd_req->current_nr_sectors) | 452 | if (n > blk_rq_cur_sectors(fd_req)) |
436 | n = fd_req->current_nr_sectors; | 453 | n = blk_rq_cur_sectors(fd_req); |
437 | } | 454 | } |
438 | fs->scount = n; | 455 | fs->scount = n; |
439 | swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0); | 456 | swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0); |
@@ -508,7 +525,7 @@ static void act(struct floppy_state *fs) | |||
508 | case do_transfer: | 525 | case do_transfer: |
509 | if (fs->cur_cyl != fs->req_cyl) { | 526 | if (fs->cur_cyl != fs->req_cyl) { |
510 | if (fs->retries > 5) { | 527 | if (fs->retries > 5) { |
511 | end_request(fd_req, 0); | 528 | swim3_end_request_cur(-EIO); |
512 | fs->state = idle; | 529 | fs->state = idle; |
513 | return; | 530 | return; |
514 | } | 531 | } |
@@ -540,7 +557,7 @@ static void scan_timeout(unsigned long data) | |||
540 | out_8(&sw->intr_enable, 0); | 557 | out_8(&sw->intr_enable, 0); |
541 | fs->cur_cyl = -1; | 558 | fs->cur_cyl = -1; |
542 | if (fs->retries > 5) { | 559 | if (fs->retries > 5) { |
543 | end_request(fd_req, 0); | 560 | swim3_end_request_cur(-EIO); |
544 | fs->state = idle; | 561 | fs->state = idle; |
545 | start_request(fs); | 562 | start_request(fs); |
546 | } else { | 563 | } else { |
@@ -559,7 +576,7 @@ static void seek_timeout(unsigned long data) | |||
559 | out_8(&sw->select, RELAX); | 576 | out_8(&sw->select, RELAX); |
560 | out_8(&sw->intr_enable, 0); | 577 | out_8(&sw->intr_enable, 0); |
561 | printk(KERN_ERR "swim3: seek timeout\n"); | 578 | printk(KERN_ERR "swim3: seek timeout\n"); |
562 | end_request(fd_req, 0); | 579 | swim3_end_request_cur(-EIO); |
563 | fs->state = idle; | 580 | fs->state = idle; |
564 | start_request(fs); | 581 | start_request(fs); |
565 | } | 582 | } |
@@ -583,7 +600,7 @@ static void settle_timeout(unsigned long data) | |||
583 | return; | 600 | return; |
584 | } | 601 | } |
585 | printk(KERN_ERR "swim3: seek settle timeout\n"); | 602 | printk(KERN_ERR "swim3: seek settle timeout\n"); |
586 | end_request(fd_req, 0); | 603 | swim3_end_request_cur(-EIO); |
587 | fs->state = idle; | 604 | fs->state = idle; |
588 | start_request(fs); | 605 | start_request(fs); |
589 | } | 606 | } |
@@ -593,8 +610,6 @@ static void xfer_timeout(unsigned long data) | |||
593 | struct floppy_state *fs = (struct floppy_state *) data; | 610 | struct floppy_state *fs = (struct floppy_state *) data; |
594 | struct swim3 __iomem *sw = fs->swim3; | 611 | struct swim3 __iomem *sw = fs->swim3; |
595 | struct dbdma_regs __iomem *dr = fs->dma; | 612 | struct dbdma_regs __iomem *dr = fs->dma; |
596 | struct dbdma_cmd *cp = fs->dma_cmd; | ||
597 | unsigned long s; | ||
598 | int n; | 613 | int n; |
599 | 614 | ||
600 | fs->timeout_pending = 0; | 615 | fs->timeout_pending = 0; |
@@ -605,17 +620,10 @@ static void xfer_timeout(unsigned long data) | |||
605 | out_8(&sw->intr_enable, 0); | 620 | out_8(&sw->intr_enable, 0); |
606 | out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); | 621 | out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); |
607 | out_8(&sw->select, RELAX); | 622 | out_8(&sw->select, RELAX); |
608 | if (rq_data_dir(fd_req) == WRITE) | ||
609 | ++cp; | ||
610 | if (ld_le16(&cp->xfer_status) != 0) | ||
611 | s = fs->scount - ((ld_le16(&cp->res_count) + 511) >> 9); | ||
612 | else | ||
613 | s = 0; | ||
614 | fd_req->sector += s; | ||
615 | fd_req->current_nr_sectors -= s; | ||
616 | printk(KERN_ERR "swim3: timeout %sing sector %ld\n", | 623 | printk(KERN_ERR "swim3: timeout %sing sector %ld\n", |
617 | (rq_data_dir(fd_req)==WRITE? "writ": "read"), (long)fd_req->sector); | 624 | (rq_data_dir(fd_req)==WRITE? "writ": "read"), |
618 | end_request(fd_req, 0); | 625 | (long)blk_rq_pos(fd_req)); |
626 | swim3_end_request_cur(-EIO); | ||
619 | fs->state = idle; | 627 | fs->state = idle; |
620 | start_request(fs); | 628 | start_request(fs); |
621 | } | 629 | } |
@@ -646,7 +654,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
646 | printk(KERN_ERR "swim3: seen sector but cyl=ff?\n"); | 654 | printk(KERN_ERR "swim3: seen sector but cyl=ff?\n"); |
647 | fs->cur_cyl = -1; | 655 | fs->cur_cyl = -1; |
648 | if (fs->retries > 5) { | 656 | if (fs->retries > 5) { |
649 | end_request(fd_req, 0); | 657 | swim3_end_request_cur(-EIO); |
650 | fs->state = idle; | 658 | fs->state = idle; |
651 | start_request(fs); | 659 | start_request(fs); |
652 | } else { | 660 | } else { |
@@ -719,9 +727,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
719 | if (intr & ERROR_INTR) { | 727 | if (intr & ERROR_INTR) { |
720 | n = fs->scount - 1 - resid / 512; | 728 | n = fs->scount - 1 - resid / 512; |
721 | if (n > 0) { | 729 | if (n > 0) { |
722 | fd_req->sector += n; | 730 | blk_update_request(fd_req, 0, n << 9); |
723 | fd_req->current_nr_sectors -= n; | ||
724 | fd_req->buffer += n * 512; | ||
725 | fs->req_sector += n; | 731 | fs->req_sector += n; |
726 | } | 732 | } |
727 | if (fs->retries < 5) { | 733 | if (fs->retries < 5) { |
@@ -730,8 +736,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
730 | } else { | 736 | } else { |
731 | printk("swim3: error %sing block %ld (err=%x)\n", | 737 | printk("swim3: error %sing block %ld (err=%x)\n", |
732 | rq_data_dir(fd_req) == WRITE? "writ": "read", | 738 | rq_data_dir(fd_req) == WRITE? "writ": "read", |
733 | (long)fd_req->sector, err); | 739 | (long)blk_rq_pos(fd_req), err); |
734 | end_request(fd_req, 0); | 740 | swim3_end_request_cur(-EIO); |
735 | fs->state = idle; | 741 | fs->state = idle; |
736 | } | 742 | } |
737 | } else { | 743 | } else { |
@@ -740,18 +746,12 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
740 | printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); | 746 | printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); |
741 | printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n", | 747 | printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n", |
742 | fs->state, rq_data_dir(fd_req), intr, err); | 748 | fs->state, rq_data_dir(fd_req), intr, err); |
743 | end_request(fd_req, 0); | 749 | swim3_end_request_cur(-EIO); |
744 | fs->state = idle; | 750 | fs->state = idle; |
745 | start_request(fs); | 751 | start_request(fs); |
746 | break; | 752 | break; |
747 | } | 753 | } |
748 | fd_req->sector += fs->scount; | 754 | if (swim3_end_request(0, fs->scount << 9)) { |
749 | fd_req->current_nr_sectors -= fs->scount; | ||
750 | fd_req->buffer += fs->scount * 512; | ||
751 | if (fd_req->current_nr_sectors <= 0) { | ||
752 | end_request(fd_req, 1); | ||
753 | fs->state = idle; | ||
754 | } else { | ||
755 | fs->req_sector += fs->scount; | 755 | fs->req_sector += fs->scount; |
756 | if (fs->req_sector > fs->secpertrack) { | 756 | if (fs->req_sector > fs->secpertrack) { |
757 | fs->req_sector -= fs->secpertrack; | 757 | fs->req_sector -= fs->secpertrack; |
@@ -761,7 +761,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
761 | } | 761 | } |
762 | } | 762 | } |
763 | act(fs); | 763 | act(fs); |
764 | } | 764 | } else |
765 | fs->state = idle; | ||
765 | } | 766 | } |
766 | if (fs->state == idle) | 767 | if (fs->state == idle) |
767 | start_request(fs); | 768 | start_request(fs); |