aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/mg_disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/mg_disk.c')
-rw-r--r--drivers/block/mg_disk.c117
1 files changed, 33 insertions, 84 deletions
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index 2c6127ee8343..1a4cc968cfee 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -503,95 +503,68 @@ static unsigned int mg_out(struct mg_host *host,
503 503
504static void mg_read(struct request *req) 504static void mg_read(struct request *req)
505{ 505{
506 u32 remains, j; 506 u32 j;
507 struct mg_host *host = req->rq_disk->private_data; 507 struct mg_host *host = req->rq_disk->private_data;
508 508
509 remains = req->nr_sectors;
510
511 if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) != 509 if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) !=
512 MG_ERR_NONE) 510 MG_ERR_NONE)
513 mg_bad_rw_intr(host); 511 mg_bad_rw_intr(host);
514 512
515 MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", 513 MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
516 remains, req->sector, req->buffer); 514 req->nr_sectors, req->sector, req->buffer);
515
516 do {
517 u16 *buff = (u16 *)req->buffer;
517 518
518 while (remains) {
519 if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, 519 if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
520 MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) { 520 MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
521 mg_bad_rw_intr(host); 521 mg_bad_rw_intr(host);
522 return; 522 return;
523 } 523 }
524 for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) { 524 for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
525 *(u16 *)req->buffer = 525 *buff++ = inw((unsigned long)host->dev_base +
526 inw((unsigned long)host->dev_base + 526 MG_BUFF_OFFSET + (j << 1));
527 MG_BUFF_OFFSET + (j << 1));
528 req->buffer += 2;
529 }
530
531 req->sector++;
532 req->errors = 0;
533 remains = --req->nr_sectors;
534 --req->current_nr_sectors;
535
536 if (req->current_nr_sectors <= 0) {
537 MG_DBG("remain : %d sects\n", remains);
538 __blk_end_request_cur(req, 0);
539 if (remains > 0)
540 req = elv_next_request(host->breq);
541 }
542 527
543 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + 528 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
544 MG_REG_COMMAND); 529 MG_REG_COMMAND);
545 } 530 } while (__blk_end_request(req, 0, MG_SECTOR_SIZE));
546} 531}
547 532
548static void mg_write(struct request *req) 533static void mg_write(struct request *req)
549{ 534{
550 u32 remains, j; 535 u32 j;
551 struct mg_host *host = req->rq_disk->private_data; 536 struct mg_host *host = req->rq_disk->private_data;
552 537
553 remains = req->nr_sectors;
554
555 if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) != 538 if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) !=
556 MG_ERR_NONE) { 539 MG_ERR_NONE) {
557 mg_bad_rw_intr(host); 540 mg_bad_rw_intr(host);
558 return; 541 return;
559 } 542 }
560 543
561
562 MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", 544 MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
563 remains, req->sector, req->buffer); 545 req->nr_sectors, req->sector, req->buffer);
564 while (remains) { 546
547 do {
548 u16 *buff = (u16 *)req->buffer;
549
565 if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, 550 if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
566 MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { 551 MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
567 mg_bad_rw_intr(host); 552 mg_bad_rw_intr(host);
568 return; 553 return;
569 } 554 }
570 for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) { 555 for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
571 outw(*(u16 *)req->buffer, 556 outw(*buff++, (unsigned long)host->dev_base +
572 (unsigned long)host->dev_base + 557 MG_BUFF_OFFSET + (j << 1));
573 MG_BUFF_OFFSET + (j << 1));
574 req->buffer += 2;
575 }
576 req->sector++;
577 remains = --req->nr_sectors;
578 --req->current_nr_sectors;
579
580 if (req->current_nr_sectors <= 0) {
581 MG_DBG("remain : %d sects\n", remains);
582 __blk_end_request_cur(req, 0);
583 if (remains > 0)
584 req = elv_next_request(host->breq);
585 }
586 558
587 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + 559 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
588 MG_REG_COMMAND); 560 MG_REG_COMMAND);
589 } 561 } while (__blk_end_request(req, 0, MG_SECTOR_SIZE));
590} 562}
591 563
592static void mg_read_intr(struct mg_host *host) 564static void mg_read_intr(struct mg_host *host)
593{ 565{
594 u32 i; 566 u32 i;
567 u16 *buff;
595 struct request *req; 568 struct request *req;
596 569
597 /* check status */ 570 /* check status */
@@ -612,39 +585,24 @@ static void mg_read_intr(struct mg_host *host)
612ok_to_read: 585ok_to_read:
613 /* get current segment of request */ 586 /* get current segment of request */
614 req = elv_next_request(host->breq); 587 req = elv_next_request(host->breq);
588 buff = (u16 *)req->buffer;
615 589
616 /* read 1 sector */ 590 /* read 1 sector */
617 for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) { 591 for (i = 0; i < MG_SECTOR_SIZE >> 1; i++)
618 *(u16 *)req->buffer = 592 *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
619 inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + 593 (i << 1));
620 (i << 1));
621 req->buffer += 2;
622 }
623 594
624 /* manipulate request */
625 MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n", 595 MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
626 req->sector, req->nr_sectors - 1, req->buffer); 596 req->sector, req->nr_sectors - 1, req->buffer);
627 597
628 req->sector++;
629 req->errors = 0;
630 i = --req->nr_sectors;
631 --req->current_nr_sectors;
632
633 /* let know if current segment done */
634 if (req->current_nr_sectors <= 0)
635 __blk_end_request_cur(req, 0);
636
637 /* set handler if read remains */
638 if (i > 0) {
639 host->mg_do_intr = mg_read_intr;
640 mod_timer(&host->timer, jiffies + 3 * HZ);
641 }
642
643 /* send read confirm */ 598 /* send read confirm */
644 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); 599 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
645 600
646 /* goto next request */ 601 if (__blk_end_request(req, 0, MG_SECTOR_SIZE)) {
647 if (!i) 602 /* set handler if read remains */
603 host->mg_do_intr = mg_read_intr;
604 mod_timer(&host->timer, jiffies + 3 * HZ);
605 } else /* goto next request */
648 mg_request(host->breq); 606 mg_request(host->breq);
649} 607}
650 608
@@ -653,6 +611,7 @@ static void mg_write_intr(struct mg_host *host)
653 u32 i, j; 611 u32 i, j;
654 u16 *buff; 612 u16 *buff;
655 struct request *req; 613 struct request *req;
614 bool rem;
656 615
657 /* get current segment of request */ 616 /* get current segment of request */
658 req = elv_next_request(host->breq); 617 req = elv_next_request(host->breq);
@@ -673,18 +632,8 @@ static void mg_write_intr(struct mg_host *host)
673 return; 632 return;
674 633
675ok_to_write: 634ok_to_write:
676 /* manipulate request */ 635 if ((rem = __blk_end_request(req, 0, MG_SECTOR_SIZE))) {
677 req->sector++; 636 /* write 1 sector and set handler if remains */
678 i = --req->nr_sectors;
679 --req->current_nr_sectors;
680 req->buffer += MG_SECTOR_SIZE;
681
682 /* let know if current segment or all done */
683 if (!i || (req->bio && req->current_nr_sectors <= 0))
684 __blk_end_request_cur(req, 0);
685
686 /* write 1 sector and set handler if remains */
687 if (i > 0) {
688 buff = (u16 *)req->buffer; 637 buff = (u16 *)req->buffer;
689 for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) { 638 for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
690 outw(*buff, (unsigned long)host->dev_base + 639 outw(*buff, (unsigned long)host->dev_base +
@@ -700,7 +649,7 @@ ok_to_write:
700 /* send write confirm */ 649 /* send write confirm */
701 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); 650 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
702 651
703 if (!i) 652 if (!rem)
704 mg_request(host->breq); 653 mg_request(host->breq);
705} 654}
706 655