Lines Matching refs:host
149 static bool mg_end_request(struct mg_host *host, int err, unsigned int nr_bytes) in mg_end_request() argument
151 if (__blk_end_request(host->req, err, nr_bytes)) in mg_end_request()
154 host->req = NULL; in mg_end_request()
158 static bool mg_end_request_cur(struct mg_host *host, int err) in mg_end_request_cur() argument
160 return mg_end_request(host, err, blk_rq_cur_bytes(host->req)); in mg_end_request_cur()
164 struct mg_host *host) in mg_dump_status() argument
168 if (host->req) in mg_dump_status()
169 name = host->req->rq_disk->disk_name; in mg_dump_status()
188 host->error = 0; in mg_dump_status()
190 host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR); in mg_dump_status()
192 host->error & 0xff); in mg_dump_status()
193 if (host->error & ATA_BBK) in mg_dump_status()
195 if (host->error & ATA_UNC) in mg_dump_status()
197 if (host->error & ATA_IDNF) in mg_dump_status()
199 if (host->error & ATA_ABORTED) in mg_dump_status()
201 if (host->error & ATA_AMNF) in mg_dump_status()
204 if (host->error & (ATA_BBK | ATA_UNC | ATA_IDNF | ATA_AMNF)) { in mg_dump_status()
205 if (host->req) in mg_dump_status()
207 (unsigned int)blk_rq_pos(host->req)); in mg_dump_status()
213 static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec) in mg_wait() argument
217 struct mg_drv_data *prv_data = host->dev->platform_data; in mg_wait()
219 host->error = MG_ERR_NONE; in mg_wait()
228 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_wait()
229 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_wait()
232 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_wait()
242 mg_dump_status("mg_wait", status, host); in mg_wait()
255 mg_dump_status("not ready", status, host); in mg_wait()
259 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_wait()
263 host->error = MG_ERR_TIMEOUT; in mg_wait()
265 return host->error; in mg_wait()
282 static void mg_unexpected_intr(struct mg_host *host) in mg_unexpected_intr() argument
284 u32 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_unexpected_intr()
286 mg_dump_status("mg_unexpected_intr", status, host); in mg_unexpected_intr()
291 struct mg_host *host = dev_id; in mg_irq() local
292 void (*handler)(struct mg_host *) = host->mg_do_intr; in mg_irq()
294 spin_lock(&host->lock); in mg_irq()
296 host->mg_do_intr = NULL; in mg_irq()
297 del_timer(&host->timer); in mg_irq()
300 handler(host); in mg_irq()
302 spin_unlock(&host->lock); in mg_irq()
343 static int mg_get_disk_id(struct mg_host *host) in mg_get_disk_id() argument
347 const u16 *id = host->id; in mg_get_disk_id()
348 struct mg_drv_data *prv_data = host->dev->platform_data; in mg_get_disk_id()
354 outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_get_disk_id()
356 outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_get_disk_id()
357 err = mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_RD_DRQ); in mg_get_disk_id()
362 host->id[i] = le16_to_cpu(inw((unsigned long)host->dev_base + in mg_get_disk_id()
365 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_get_disk_id()
366 err = mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD); in mg_get_disk_id()
373 host->n_sectors = ata_id_u32(id, ATA_ID_LBA_CAPACITY); in mg_get_disk_id()
374 host->cyls = id[ATA_ID_CYLS]; in mg_get_disk_id()
375 host->heads = id[ATA_ID_HEADS]; in mg_get_disk_id()
376 host->sectors = id[ATA_ID_SECTORS]; in mg_get_disk_id()
378 if (MG_RES_SEC && host->heads && host->sectors) { in mg_get_disk_id()
380 host->cyls = (host->n_sectors - MG_RES_SEC) / in mg_get_disk_id()
381 host->heads / host->sectors; in mg_get_disk_id()
382 host->nres_sectors = host->n_sectors - host->cyls * in mg_get_disk_id()
383 host->heads * host->sectors; in mg_get_disk_id()
384 host->n_sectors -= host->nres_sectors; in mg_get_disk_id()
394 host->n_sectors, host->nres_sectors); in mg_get_disk_id()
397 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_get_disk_id()
403 static int mg_disk_init(struct mg_host *host) in mg_disk_init() argument
405 struct mg_drv_data *prv_data = host->dev->platform_data; in mg_disk_init()
410 gpio_set_value(host->rst, 0); in mg_disk_init()
411 err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY); in mg_disk_init()
416 gpio_set_value(host->rst, 1); in mg_disk_init()
417 err = mg_wait(host, MG_STAT_READY, MG_TMAX_HDRST_TO_RDY); in mg_disk_init()
423 (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_disk_init()
424 err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY); in mg_disk_init()
430 (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_disk_init()
431 err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY); in mg_disk_init()
435 init_status = inb((unsigned long)host->dev_base + MG_REG_STATUS) & 0xf; in mg_disk_init()
443 static void mg_bad_rw_intr(struct mg_host *host) in mg_bad_rw_intr() argument
445 if (host->req) in mg_bad_rw_intr()
446 if (++host->req->errors >= MG_MAX_ERRORS || in mg_bad_rw_intr()
447 host->error == MG_ERR_TIMEOUT) in mg_bad_rw_intr()
448 mg_end_request_cur(host, -EIO); in mg_bad_rw_intr()
451 static unsigned int mg_out(struct mg_host *host, in mg_out() argument
457 struct mg_drv_data *prv_data = host->dev->platform_data; in mg_out()
459 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) in mg_out()
460 return host->error; in mg_out()
463 host->mg_do_intr = intr_addr; in mg_out()
464 mod_timer(&host->timer, jiffies + 3 * HZ); in mg_out()
468 outb((u8)sect_cnt, (unsigned long)host->dev_base + MG_REG_SECT_CNT); in mg_out()
469 outb((u8)sect_num, (unsigned long)host->dev_base + MG_REG_SECT_NUM); in mg_out()
470 outb((u8)(sect_num >> 8), (unsigned long)host->dev_base + in mg_out()
472 outb((u8)(sect_num >> 16), (unsigned long)host->dev_base + in mg_out()
475 (unsigned long)host->dev_base + MG_REG_DRV_HEAD); in mg_out()
476 outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_out()
480 static void mg_read_one(struct mg_host *host, struct request *req) in mg_read_one() argument
486 *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + in mg_read_one()
492 struct mg_host *host = req->rq_disk->private_data; in mg_read() local
494 if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req), in mg_read()
496 mg_bad_rw_intr(host); in mg_read()
502 if (mg_wait(host, ATA_DRQ, in mg_read()
504 mg_bad_rw_intr(host); in mg_read()
508 mg_read_one(host, req); in mg_read()
510 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + in mg_read()
512 } while (mg_end_request(host, 0, MG_SECTOR_SIZE)); in mg_read()
515 static void mg_write_one(struct mg_host *host, struct request *req) in mg_write_one() argument
521 outw(*buff++, (unsigned long)host->dev_base + MG_BUFF_OFFSET + in mg_write_one()
527 struct mg_host *host = req->rq_disk->private_data; in mg_write() local
530 if (mg_out(host, blk_rq_pos(req), rem, in mg_write()
532 mg_bad_rw_intr(host); in mg_write()
539 if (mg_wait(host, ATA_DRQ, in mg_write()
541 mg_bad_rw_intr(host); in mg_write()
546 mg_write_one(host, req); in mg_write()
548 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + in mg_write()
552 if (rem > 1 && mg_wait(host, ATA_DRQ, in mg_write()
554 mg_bad_rw_intr(host); in mg_write()
556 } else if (mg_wait(host, MG_STAT_READY, in mg_write()
558 mg_bad_rw_intr(host); in mg_write()
561 } while (mg_end_request(host, 0, MG_SECTOR_SIZE)); in mg_write()
564 static void mg_read_intr(struct mg_host *host) in mg_read_intr() argument
566 struct request *req = host->req; in mg_read_intr()
571 i = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_read_intr()
579 mg_dump_status("mg_read_intr", i, host); in mg_read_intr()
580 mg_bad_rw_intr(host); in mg_read_intr()
581 mg_request(host->breq); in mg_read_intr()
585 mg_read_one(host, req); in mg_read_intr()
591 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_read_intr()
593 if (mg_end_request(host, 0, MG_SECTOR_SIZE)) { in mg_read_intr()
595 host->mg_do_intr = mg_read_intr; in mg_read_intr()
596 mod_timer(&host->timer, jiffies + 3 * HZ); in mg_read_intr()
598 mg_request(host->breq); in mg_read_intr()
601 static void mg_write_intr(struct mg_host *host) in mg_write_intr() argument
603 struct request *req = host->req; in mg_write_intr()
609 i = inb((unsigned long)host->dev_base + MG_REG_STATUS); in mg_write_intr()
617 mg_dump_status("mg_write_intr", i, host); in mg_write_intr()
618 mg_bad_rw_intr(host); in mg_write_intr()
619 mg_request(host->breq); in mg_write_intr()
623 if ((rem = mg_end_request(host, 0, MG_SECTOR_SIZE))) { in mg_write_intr()
625 mg_write_one(host, req); in mg_write_intr()
628 host->mg_do_intr = mg_write_intr; in mg_write_intr()
629 mod_timer(&host->timer, jiffies + 3 * HZ); in mg_write_intr()
633 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_write_intr()
636 mg_request(host->breq); in mg_write_intr()
641 struct mg_host *host = (struct mg_host *)data; in mg_times_out() local
644 spin_lock_irq(&host->lock); in mg_times_out()
646 if (!host->req) in mg_times_out()
649 host->mg_do_intr = NULL; in mg_times_out()
651 name = host->req->rq_disk->disk_name; in mg_times_out()
654 host->error = MG_ERR_TIMEOUT; in mg_times_out()
655 mg_bad_rw_intr(host); in mg_times_out()
658 mg_request(host->breq); in mg_times_out()
659 spin_unlock_irq(&host->lock); in mg_times_out()
664 struct mg_host *host = q->queuedata; in mg_request_poll() local
667 if (!host->req) { in mg_request_poll()
668 host->req = blk_fetch_request(q); in mg_request_poll()
669 if (!host->req) in mg_request_poll()
673 if (unlikely(host->req->cmd_type != REQ_TYPE_FS)) { in mg_request_poll()
674 mg_end_request_cur(host, -EIO); in mg_request_poll()
678 if (rq_data_dir(host->req) == READ) in mg_request_poll()
679 mg_read(host->req); in mg_request_poll()
681 mg_write(host->req); in mg_request_poll()
686 struct mg_host *host, in mg_issue_req() argument
692 if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr) in mg_issue_req()
694 mg_bad_rw_intr(host); in mg_issue_req()
695 return host->error; in mg_issue_req()
700 outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_issue_req()
701 if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr) in mg_issue_req()
703 mg_bad_rw_intr(host); in mg_issue_req()
704 return host->error; in mg_issue_req()
706 del_timer(&host->timer); in mg_issue_req()
707 mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ); in mg_issue_req()
708 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_issue_req()
709 if (host->error) { in mg_issue_req()
710 mg_bad_rw_intr(host); in mg_issue_req()
711 return host->error; in mg_issue_req()
713 mg_write_one(host, req); in mg_issue_req()
714 mod_timer(&host->timer, jiffies + 3 * HZ); in mg_issue_req()
715 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + in mg_issue_req()
725 struct mg_host *host = q->queuedata; in mg_request() local
730 if (!host->req) { in mg_request()
731 host->req = blk_fetch_request(q); in mg_request()
732 if (!host->req) in mg_request()
735 req = host->req; in mg_request()
738 if (host->mg_do_intr) in mg_request()
741 del_timer(&host->timer); in mg_request()
755 mg_end_request_cur(host, -EIO); in mg_request()
760 mg_end_request_cur(host, -EIO); in mg_request()
764 if (!mg_issue_req(req, host, sect_num, sect_cnt)) in mg_request()
771 struct mg_host *host = bdev->bd_disk->private_data; in mg_getgeo() local
773 geo->cylinders = (unsigned short)host->cyls; in mg_getgeo()
774 geo->heads = (unsigned char)host->heads; in mg_getgeo()
775 geo->sectors = (unsigned char)host->sectors; in mg_getgeo()
787 struct mg_host *host = prv_data->host; in mg_suspend() local
789 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) in mg_suspend()
793 outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_suspend()
795 outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_suspend()
799 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) { in mg_suspend()
801 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_suspend()
811 struct mg_host *host = prv_data->host; in mg_resume() local
813 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) in mg_resume()
816 outb(MG_CMD_WAKEUP, (unsigned long)host->dev_base + MG_REG_COMMAND); in mg_resume()
820 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) in mg_resume()
824 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); in mg_resume()
834 struct mg_host *host; in mg_probe() local
847 host = kzalloc(sizeof(struct mg_host), GFP_KERNEL); in mg_probe()
848 if (!host) { in mg_probe()
854 host->major = MG_DISK_MAJ; in mg_probe()
857 prv_data->host = host; in mg_probe()
858 host->dev = &plat_dev->dev; in mg_probe()
868 host->dev_base = ioremap(rsc->start, resource_size(rsc)); in mg_probe()
869 if (!host->dev_base) { in mg_probe()
875 MG_DBG("dev_base = 0x%x\n", (u32)host->dev_base); in mg_probe()
886 host->rst = rsc->start; in mg_probe()
889 err = gpio_request(host->rst, MG_RST_PIN); in mg_probe()
892 gpio_direction_output(host->rst, 1); in mg_probe()
909 host->rstout = rsc->start; in mg_probe()
910 err = gpio_request(host->rstout, MG_RSTOUT_PIN); in mg_probe()
913 gpio_direction_input(host->rstout); in mg_probe()
919 err = mg_wait_rstout(host->rstout, MG_TMAX_RSTOUT); in mg_probe()
922 err = mg_disk_init(host); in mg_probe()
933 host->irq = platform_get_irq(plat_dev, 0); in mg_probe()
934 if (host->irq == -ENXIO) { in mg_probe()
935 err = host->irq; in mg_probe()
938 err = request_irq(host->irq, mg_irq, in mg_probe()
940 MG_DEV_NAME, host); in mg_probe()
950 err = mg_get_disk_id(host); in mg_probe()
958 err = register_blkdev(host->major, MG_DISK_NAME); in mg_probe()
964 if (!host->major) in mg_probe()
965 host->major = err; in mg_probe()
967 spin_lock_init(&host->lock); in mg_probe()
970 host->breq = blk_init_queue(mg_request_poll, &host->lock); in mg_probe()
972 host->breq = blk_init_queue(mg_request, &host->lock); in mg_probe()
974 if (!host->breq) { in mg_probe()
980 host->breq->queuedata = host; in mg_probe()
983 err = elevator_change(host->breq, "noop"); in mg_probe()
989 blk_queue_max_hw_sectors(host->breq, MG_MAX_SECTS); in mg_probe()
990 blk_queue_logical_block_size(host->breq, MG_SECTOR_SIZE); in mg_probe()
992 init_timer(&host->timer); in mg_probe()
993 host->timer.function = mg_times_out; in mg_probe()
994 host->timer.data = (unsigned long)host; in mg_probe()
996 host->gd = alloc_disk(MG_DISK_MAX_PART); in mg_probe()
997 if (!host->gd) { in mg_probe()
1003 host->gd->major = host->major; in mg_probe()
1004 host->gd->first_minor = 0; in mg_probe()
1005 host->gd->fops = &mg_disk_ops; in mg_probe()
1006 host->gd->queue = host->breq; in mg_probe()
1007 host->gd->private_data = host; in mg_probe()
1008 sprintf(host->gd->disk_name, MG_DISK_NAME"a"); in mg_probe()
1010 set_capacity(host->gd, host->n_sectors); in mg_probe()
1012 add_disk(host->gd); in mg_probe()
1017 del_timer_sync(&host->timer); in mg_probe()
1019 blk_cleanup_queue(host->breq); in mg_probe()
1024 free_irq(host->irq, host); in mg_probe()
1026 gpio_free(host->rstout); in mg_probe()
1028 gpio_free(host->rst); in mg_probe()
1030 iounmap(host->dev_base); in mg_probe()
1032 kfree(host); in mg_probe()
1040 struct mg_host *host = prv_data->host; in mg_remove() local
1044 del_timer_sync(&host->timer); in mg_remove()
1047 if (host->gd) { in mg_remove()
1048 del_gendisk(host->gd); in mg_remove()
1049 put_disk(host->gd); in mg_remove()
1052 if (host->breq) in mg_remove()
1053 blk_cleanup_queue(host->breq); in mg_remove()
1056 unregister_blkdev(host->major, MG_DISK_NAME); in mg_remove()
1060 free_irq(host->irq, host); in mg_remove()
1064 gpio_free(host->rstout); in mg_remove()
1067 if (host->rst) in mg_remove()
1068 gpio_free(host->rst); in mg_remove()
1071 if (host->dev_base) in mg_remove()
1072 iounmap(host->dev_base); in mg_remove()
1075 kfree(host); in mg_remove()