at v2.6.31-rc2 1097 lines 26 kB view raw
1/* 2 * drivers/block/mg_disk.c 3 * 4 * Support for the mGine m[g]flash IO mode. 5 * Based on legacy hd.c 6 * 7 * (c) 2008 mGine Co.,LTD 8 * (c) 2008 unsik Kim <donari75@gmail.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/fs.h> 18#include <linux/blkdev.h> 19#include <linux/hdreg.h> 20#include <linux/ata.h> 21#include <linux/interrupt.h> 22#include <linux/delay.h> 23#include <linux/platform_device.h> 24#include <linux/gpio.h> 25#include <linux/mg_disk.h> 26 27#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) 28 29/* name for block device */ 30#define MG_DISK_NAME "mgd" 31 32#define MG_DISK_MAJ 0 33#define MG_DISK_MAX_PART 16 34#define MG_SECTOR_SIZE 512 35#define MG_MAX_SECTS 256 36 37/* Register offsets */ 38#define MG_BUFF_OFFSET 0x8000 39#define MG_STORAGE_BUFFER_SIZE 0x200 40#define MG_REG_OFFSET 0xC000 41#define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */ 42#define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */ 43#define MG_REG_SECT_CNT (MG_REG_OFFSET + 4) 44#define MG_REG_SECT_NUM (MG_REG_OFFSET + 6) 45#define MG_REG_CYL_LOW (MG_REG_OFFSET + 8) 46#define MG_REG_CYL_HIGH (MG_REG_OFFSET + 0xA) 47#define MG_REG_DRV_HEAD (MG_REG_OFFSET + 0xC) 48#define MG_REG_COMMAND (MG_REG_OFFSET + 0xE) /* write case */ 49#define MG_REG_STATUS (MG_REG_OFFSET + 0xE) /* read case */ 50#define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10) 51#define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12) 52 53/* handy status */ 54#define MG_STAT_READY (ATA_DRDY | ATA_DSC) 55#define MG_READY_OK(s) (((s) & (MG_STAT_READY | (ATA_BUSY | ATA_DF | \ 56 ATA_ERR))) == MG_STAT_READY) 57 58/* error code for others */ 59#define MG_ERR_NONE 0 60#define MG_ERR_TIMEOUT 0x100 61#define MG_ERR_INIT_STAT 0x101 62#define MG_ERR_TRANSLATION 0x102 63#define MG_ERR_CTRL_RST 0x103 64#define MG_ERR_INV_STAT 0x104 65#define MG_ERR_RSTOUT 0x105 66 67#define MG_MAX_ERRORS 6 /* Max read/write errors */ 68 69/* command */ 70#define MG_CMD_RD 0x20 71#define MG_CMD_WR 0x30 72#define MG_CMD_SLEEP 0x99 73#define MG_CMD_WAKEUP 0xC3 74#define MG_CMD_ID 0xEC 75#define MG_CMD_WR_CONF 0x3C 76#define MG_CMD_RD_CONF 0x40 77 78/* operation mode */ 79#define MG_OP_CASCADE (1 << 0) 80#define MG_OP_CASCADE_SYNC_RD (1 << 1) 81#define MG_OP_CASCADE_SYNC_WR (1 << 2) 82#define MG_OP_INTERLEAVE (1 << 3) 83 84/* synchronous */ 85#define MG_BURST_LAT_4 (3 << 4) 86#define MG_BURST_LAT_5 (4 << 4) 87#define MG_BURST_LAT_6 (5 << 4) 88#define MG_BURST_LAT_7 (6 << 4) 89#define MG_BURST_LAT_8 (7 << 4) 90#define MG_BURST_LEN_4 (1 << 1) 91#define MG_BURST_LEN_8 (2 << 1) 92#define MG_BURST_LEN_16 (3 << 1) 93#define MG_BURST_LEN_32 (4 << 1) 94#define MG_BURST_LEN_CONT (0 << 1) 95 96/* timeout value (unit: ms) */ 97#define MG_TMAX_CONF_TO_CMD 1 98#define MG_TMAX_WAIT_RD_DRQ 10 99#define MG_TMAX_WAIT_WR_DRQ 500 100#define MG_TMAX_RST_TO_BUSY 10 101#define MG_TMAX_HDRST_TO_RDY 500 102#define MG_TMAX_SWRST_TO_RDY 500 103#define MG_TMAX_RSTOUT 3000 104 105#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST) 106 107/* main structure for mflash driver */ 108struct mg_host { 109 struct device *dev; 110 111 struct request_queue *breq; 112 struct request *req; 113 spinlock_t lock; 114 struct gendisk *gd; 115 116 struct timer_list timer; 117 void (*mg_do_intr) (struct mg_host *); 118 119 u16 id[ATA_ID_WORDS]; 120 121 u16 cyls; 122 u16 heads; 123 u16 sectors; 124 u32 n_sectors; 125 u32 nres_sectors; 126 127 void __iomem *dev_base; 128 unsigned int irq; 129 unsigned int rst; 130 unsigned int rstout; 131 132 u32 major; 133 u32 error; 134}; 135 136/* 137 * Debugging macro and defines 138 */ 139#undef DO_MG_DEBUG 140#ifdef DO_MG_DEBUG 141# define MG_DBG(fmt, args...) \ 142 printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args) 143#else /* CONFIG_MG_DEBUG */ 144# define MG_DBG(fmt, args...) do { } while (0) 145#endif /* CONFIG_MG_DEBUG */ 146 147static void mg_request(struct request_queue *); 148 149static bool mg_end_request(struct mg_host *host, int err, unsigned int nr_bytes) 150{ 151 if (__blk_end_request(host->req, err, nr_bytes)) 152 return true; 153 154 host->req = NULL; 155 return false; 156} 157 158static bool mg_end_request_cur(struct mg_host *host, int err) 159{ 160 return mg_end_request(host, err, blk_rq_cur_bytes(host->req)); 161} 162 163static void mg_dump_status(const char *msg, unsigned int stat, 164 struct mg_host *host) 165{ 166 char *name = MG_DISK_NAME; 167 168 if (host->req) 169 name = host->req->rq_disk->disk_name; 170 171 printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff); 172 if (stat & ATA_BUSY) 173 printk("Busy "); 174 if (stat & ATA_DRDY) 175 printk("DriveReady "); 176 if (stat & ATA_DF) 177 printk("WriteFault "); 178 if (stat & ATA_DSC) 179 printk("SeekComplete "); 180 if (stat & ATA_DRQ) 181 printk("DataRequest "); 182 if (stat & ATA_CORR) 183 printk("CorrectedError "); 184 if (stat & ATA_ERR) 185 printk("Error "); 186 printk("}\n"); 187 if ((stat & ATA_ERR) == 0) { 188 host->error = 0; 189 } else { 190 host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR); 191 printk(KERN_ERR "%s: %s: error=0x%02x { ", name, msg, 192 host->error & 0xff); 193 if (host->error & ATA_BBK) 194 printk("BadSector "); 195 if (host->error & ATA_UNC) 196 printk("UncorrectableError "); 197 if (host->error & ATA_IDNF) 198 printk("SectorIdNotFound "); 199 if (host->error & ATA_ABORTED) 200 printk("DriveStatusError "); 201 if (host->error & ATA_AMNF) 202 printk("AddrMarkNotFound "); 203 printk("}"); 204 if (host->error & (ATA_BBK | ATA_UNC | ATA_IDNF | ATA_AMNF)) { 205 if (host->req) 206 printk(", sector=%u", 207 (unsigned int)blk_rq_pos(host->req)); 208 } 209 printk("\n"); 210 } 211} 212 213static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec) 214{ 215 u8 status; 216 unsigned long expire, cur_jiffies; 217 struct mg_drv_data *prv_data = host->dev->platform_data; 218 219 host->error = MG_ERR_NONE; 220 expire = jiffies + msecs_to_jiffies(msec); 221 222 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); 223 224 do { 225 cur_jiffies = jiffies; 226 if (status & ATA_BUSY) { 227 if (expect == ATA_BUSY) 228 break; 229 } else { 230 /* Check the error condition! */ 231 if (status & ATA_ERR) { 232 mg_dump_status("mg_wait", status, host); 233 break; 234 } 235 236 if (expect == MG_STAT_READY) 237 if (MG_READY_OK(status)) 238 break; 239 240 if (expect == ATA_DRQ) 241 if (status & ATA_DRQ) 242 break; 243 } 244 if (!msec) { 245 mg_dump_status("not ready", status, host); 246 return MG_ERR_INV_STAT; 247 } 248 if (prv_data->use_polling) 249 msleep(1); 250 251 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); 252 } while (time_before(cur_jiffies, expire)); 253 254 if (time_after_eq(cur_jiffies, expire) && msec) 255 host->error = MG_ERR_TIMEOUT; 256 257 return host->error; 258} 259 260static unsigned int mg_wait_rstout(u32 rstout, u32 msec) 261{ 262 unsigned long expire; 263 264 expire = jiffies + msecs_to_jiffies(msec); 265 while (time_before(jiffies, expire)) { 266 if (gpio_get_value(rstout) == 1) 267 return MG_ERR_NONE; 268 msleep(10); 269 } 270 271 return MG_ERR_RSTOUT; 272} 273 274static void mg_unexpected_intr(struct mg_host *host) 275{ 276 u32 status = inb((unsigned long)host->dev_base + MG_REG_STATUS); 277 278 mg_dump_status("mg_unexpected_intr", status, host); 279} 280 281static irqreturn_t mg_irq(int irq, void *dev_id) 282{ 283 struct mg_host *host = dev_id; 284 void (*handler)(struct mg_host *) = host->mg_do_intr; 285 286 spin_lock(&host->lock); 287 288 host->mg_do_intr = NULL; 289 del_timer(&host->timer); 290 if (!handler) 291 handler = mg_unexpected_intr; 292 handler(host); 293 294 spin_unlock(&host->lock); 295 296 return IRQ_HANDLED; 297} 298 299/* local copy of ata_id_string() */ 300static void mg_id_string(const u16 *id, unsigned char *s, 301 unsigned int ofs, unsigned int len) 302{ 303 unsigned int c; 304 305 BUG_ON(len & 1); 306 307 while (len > 0) { 308 c = id[ofs] >> 8; 309 *s = c; 310 s++; 311 312 c = id[ofs] & 0xff; 313 *s = c; 314 s++; 315 316 ofs++; 317 len -= 2; 318 } 319} 320 321/* local copy of ata_id_c_string() */ 322static void mg_id_c_string(const u16 *id, unsigned char *s, 323 unsigned int ofs, unsigned int len) 324{ 325 unsigned char *p; 326 327 mg_id_string(id, s, ofs, len - 1); 328 329 p = s + strnlen(s, len - 1); 330 while (p > s && p[-1] == ' ') 331 p--; 332 *p = '\0'; 333} 334 335static int mg_get_disk_id(struct mg_host *host) 336{ 337 u32 i; 338 s32 err; 339 const u16 *id = host->id; 340 struct mg_drv_data *prv_data = host->dev->platform_data; 341 char fwrev[ATA_ID_FW_REV_LEN + 1]; 342 char model[ATA_ID_PROD_LEN + 1]; 343 char serial[ATA_ID_SERNO_LEN + 1]; 344 345 if (!prv_data->use_polling) 346 outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 347 348 outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND); 349 err = mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_RD_DRQ); 350 if (err) 351 return err; 352 353 for (i = 0; i < (MG_SECTOR_SIZE >> 1); i++) 354 host->id[i] = le16_to_cpu(inw((unsigned long)host->dev_base + 355 MG_BUFF_OFFSET + i * 2)); 356 357 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); 358 err = mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD); 359 if (err) 360 return err; 361 362 if ((id[ATA_ID_FIELD_VALID] & 1) == 0) 363 return MG_ERR_TRANSLATION; 364 365 host->n_sectors = ata_id_u32(id, ATA_ID_LBA_CAPACITY); 366 host->cyls = id[ATA_ID_CYLS]; 367 host->heads = id[ATA_ID_HEADS]; 368 host->sectors = id[ATA_ID_SECTORS]; 369 370 if (MG_RES_SEC && host->heads && host->sectors) { 371 /* modify cyls, n_sectors */ 372 host->cyls = (host->n_sectors - MG_RES_SEC) / 373 host->heads / host->sectors; 374 host->nres_sectors = host->n_sectors - host->cyls * 375 host->heads * host->sectors; 376 host->n_sectors -= host->nres_sectors; 377 } 378 379 mg_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev)); 380 mg_id_c_string(id, model, ATA_ID_PROD, sizeof(model)); 381 mg_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); 382 printk(KERN_INFO "mg_disk: model: %s\n", model); 383 printk(KERN_INFO "mg_disk: firm: %.8s\n", fwrev); 384 printk(KERN_INFO "mg_disk: serial: %s\n", serial); 385 printk(KERN_INFO "mg_disk: %d + reserved %d sectors\n", 386 host->n_sectors, host->nres_sectors); 387 388 if (!prv_data->use_polling) 389 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 390 391 return err; 392} 393 394 395static int mg_disk_init(struct mg_host *host) 396{ 397 struct mg_drv_data *prv_data = host->dev->platform_data; 398 s32 err; 399 u8 init_status; 400 401 /* hdd rst low */ 402 gpio_set_value(host->rst, 0); 403 err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY); 404 if (err) 405 return err; 406 407 /* hdd rst high */ 408 gpio_set_value(host->rst, 1); 409 err = mg_wait(host, MG_STAT_READY, MG_TMAX_HDRST_TO_RDY); 410 if (err) 411 return err; 412 413 /* soft reset on */ 414 outb(ATA_SRST | (prv_data->use_polling ? ATA_NIEN : 0), 415 (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 416 err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY); 417 if (err) 418 return err; 419 420 /* soft reset off */ 421 outb(prv_data->use_polling ? ATA_NIEN : 0, 422 (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 423 err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY); 424 if (err) 425 return err; 426 427 init_status = inb((unsigned long)host->dev_base + MG_REG_STATUS) & 0xf; 428 429 if (init_status == 0xf) 430 return MG_ERR_INIT_STAT; 431 432 return err; 433} 434 435static void mg_bad_rw_intr(struct mg_host *host) 436{ 437 if (host->req) 438 if (++host->req->errors >= MG_MAX_ERRORS || 439 host->error == MG_ERR_TIMEOUT) 440 mg_end_request_cur(host, -EIO); 441} 442 443static unsigned int mg_out(struct mg_host *host, 444 unsigned int sect_num, 445 unsigned int sect_cnt, 446 unsigned int cmd, 447 void (*intr_addr)(struct mg_host *)) 448{ 449 struct mg_drv_data *prv_data = host->dev->platform_data; 450 451 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) 452 return host->error; 453 454 if (!prv_data->use_polling) { 455 host->mg_do_intr = intr_addr; 456 mod_timer(&host->timer, jiffies + 3 * HZ); 457 } 458 if (MG_RES_SEC) 459 sect_num += MG_RES_SEC; 460 outb((u8)sect_cnt, (unsigned long)host->dev_base + MG_REG_SECT_CNT); 461 outb((u8)sect_num, (unsigned long)host->dev_base + MG_REG_SECT_NUM); 462 outb((u8)(sect_num >> 8), (unsigned long)host->dev_base + 463 MG_REG_CYL_LOW); 464 outb((u8)(sect_num >> 16), (unsigned long)host->dev_base + 465 MG_REG_CYL_HIGH); 466 outb((u8)((sect_num >> 24) | ATA_LBA | ATA_DEVICE_OBS), 467 (unsigned long)host->dev_base + MG_REG_DRV_HEAD); 468 outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND); 469 return MG_ERR_NONE; 470} 471 472static void mg_read(struct request *req) 473{ 474 u32 j; 475 struct mg_host *host = req->rq_disk->private_data; 476 477 if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req), 478 MG_CMD_RD, NULL) != MG_ERR_NONE) 479 mg_bad_rw_intr(host); 480 481 MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", 482 blk_rq_sectors(req), blk_rq_pos(req), req->buffer); 483 484 do { 485 u16 *buff = (u16 *)req->buffer; 486 487 if (mg_wait(host, ATA_DRQ, 488 MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) { 489 mg_bad_rw_intr(host); 490 return; 491 } 492 for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) 493 *buff++ = inw((unsigned long)host->dev_base + 494 MG_BUFF_OFFSET + (j << 1)); 495 496 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + 497 MG_REG_COMMAND); 498 } while (mg_end_request(host, 0, MG_SECTOR_SIZE)); 499} 500 501static void mg_write(struct request *req) 502{ 503 u32 j; 504 struct mg_host *host = req->rq_disk->private_data; 505 506 if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req), 507 MG_CMD_WR, NULL) != MG_ERR_NONE) { 508 mg_bad_rw_intr(host); 509 return; 510 } 511 512 MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", 513 blk_rq_sectors(req), blk_rq_pos(req), req->buffer); 514 515 do { 516 u16 *buff = (u16 *)req->buffer; 517 518 if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { 519 mg_bad_rw_intr(host); 520 return; 521 } 522 for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) 523 outw(*buff++, (unsigned long)host->dev_base + 524 MG_BUFF_OFFSET + (j << 1)); 525 526 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + 527 MG_REG_COMMAND); 528 } while (mg_end_request(host, 0, MG_SECTOR_SIZE)); 529} 530 531static void mg_read_intr(struct mg_host *host) 532{ 533 struct request *req = host->req; 534 u32 i; 535 u16 *buff; 536 537 /* check status */ 538 do { 539 i = inb((unsigned long)host->dev_base + MG_REG_STATUS); 540 if (i & ATA_BUSY) 541 break; 542 if (!MG_READY_OK(i)) 543 break; 544 if (i & ATA_DRQ) 545 goto ok_to_read; 546 } while (0); 547 mg_dump_status("mg_read_intr", i, host); 548 mg_bad_rw_intr(host); 549 mg_request(host->breq); 550 return; 551 552ok_to_read: 553 /* get current segment of request */ 554 buff = (u16 *)req->buffer; 555 556 /* read 1 sector */ 557 for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) 558 *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + 559 (i << 1)); 560 561 MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n", 562 blk_rq_pos(req), blk_rq_sectors(req) - 1, req->buffer); 563 564 /* send read confirm */ 565 outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); 566 567 if (mg_end_request(host, 0, MG_SECTOR_SIZE)) { 568 /* set handler if read remains */ 569 host->mg_do_intr = mg_read_intr; 570 mod_timer(&host->timer, jiffies + 3 * HZ); 571 } else /* goto next request */ 572 mg_request(host->breq); 573} 574 575static void mg_write_intr(struct mg_host *host) 576{ 577 struct request *req = host->req; 578 u32 i, j; 579 u16 *buff; 580 bool rem; 581 582 /* check status */ 583 do { 584 i = inb((unsigned long)host->dev_base + MG_REG_STATUS); 585 if (i & ATA_BUSY) 586 break; 587 if (!MG_READY_OK(i)) 588 break; 589 if ((blk_rq_sectors(req) <= 1) || (i & ATA_DRQ)) 590 goto ok_to_write; 591 } while (0); 592 mg_dump_status("mg_write_intr", i, host); 593 mg_bad_rw_intr(host); 594 mg_request(host->breq); 595 return; 596 597ok_to_write: 598 if ((rem = mg_end_request(host, 0, MG_SECTOR_SIZE))) { 599 /* write 1 sector and set handler if remains */ 600 buff = (u16 *)req->buffer; 601 for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) { 602 outw(*buff, (unsigned long)host->dev_base + 603 MG_BUFF_OFFSET + (j << 1)); 604 buff++; 605 } 606 MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n", 607 blk_rq_pos(req), blk_rq_sectors(req), req->buffer); 608 host->mg_do_intr = mg_write_intr; 609 mod_timer(&host->timer, jiffies + 3 * HZ); 610 } 611 612 /* send write confirm */ 613 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); 614 615 if (!rem) 616 mg_request(host->breq); 617} 618 619void mg_times_out(unsigned long data) 620{ 621 struct mg_host *host = (struct mg_host *)data; 622 char *name; 623 624 spin_lock_irq(&host->lock); 625 626 if (!host->req) 627 goto out_unlock; 628 629 host->mg_do_intr = NULL; 630 631 name = host->req->rq_disk->disk_name; 632 printk(KERN_DEBUG "%s: timeout\n", name); 633 634 host->error = MG_ERR_TIMEOUT; 635 mg_bad_rw_intr(host); 636 637out_unlock: 638 mg_request(host->breq); 639 spin_unlock_irq(&host->lock); 640} 641 642static void mg_request_poll(struct request_queue *q) 643{ 644 struct mg_host *host = q->queuedata; 645 646 while (1) { 647 if (!host->req) { 648 host->req = blk_fetch_request(q); 649 if (!host->req) 650 break; 651 } 652 653 if (unlikely(!blk_fs_request(host->req))) { 654 mg_end_request_cur(host, -EIO); 655 continue; 656 } 657 658 if (rq_data_dir(host->req) == READ) 659 mg_read(host->req); 660 else 661 mg_write(host->req); 662 } 663} 664 665static unsigned int mg_issue_req(struct request *req, 666 struct mg_host *host, 667 unsigned int sect_num, 668 unsigned int sect_cnt) 669{ 670 u16 *buff; 671 u32 i; 672 673 switch (rq_data_dir(req)) { 674 case READ: 675 if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr) 676 != MG_ERR_NONE) { 677 mg_bad_rw_intr(host); 678 return host->error; 679 } 680 break; 681 case WRITE: 682 /* TODO : handler */ 683 outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 684 if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr) 685 != MG_ERR_NONE) { 686 mg_bad_rw_intr(host); 687 return host->error; 688 } 689 del_timer(&host->timer); 690 mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ); 691 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 692 if (host->error) { 693 mg_bad_rw_intr(host); 694 return host->error; 695 } 696 buff = (u16 *)req->buffer; 697 for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) { 698 outw(*buff, (unsigned long)host->dev_base + 699 MG_BUFF_OFFSET + (i << 1)); 700 buff++; 701 } 702 mod_timer(&host->timer, jiffies + 3 * HZ); 703 outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + 704 MG_REG_COMMAND); 705 break; 706 } 707 return MG_ERR_NONE; 708} 709 710/* This function also called from IRQ context */ 711static void mg_request(struct request_queue *q) 712{ 713 struct mg_host *host = q->queuedata; 714 struct request *req; 715 u32 sect_num, sect_cnt; 716 717 while (1) { 718 if (!host->req) { 719 host->req = blk_fetch_request(q); 720 if (!host->req) 721 break; 722 } 723 req = host->req; 724 725 /* check unwanted request call */ 726 if (host->mg_do_intr) 727 return; 728 729 del_timer(&host->timer); 730 731 sect_num = blk_rq_pos(req); 732 /* deal whole segments */ 733 sect_cnt = blk_rq_sectors(req); 734 735 /* sanity check */ 736 if (sect_num >= get_capacity(req->rq_disk) || 737 ((sect_num + sect_cnt) > 738 get_capacity(req->rq_disk))) { 739 printk(KERN_WARNING 740 "%s: bad access: sector=%d, count=%d\n", 741 req->rq_disk->disk_name, 742 sect_num, sect_cnt); 743 mg_end_request_cur(host, -EIO); 744 continue; 745 } 746 747 if (unlikely(!blk_fs_request(req))) { 748 mg_end_request_cur(host, -EIO); 749 continue; 750 } 751 752 if (!mg_issue_req(req, host, sect_num, sect_cnt)) 753 return; 754 } 755} 756 757static int mg_getgeo(struct block_device *bdev, struct hd_geometry *geo) 758{ 759 struct mg_host *host = bdev->bd_disk->private_data; 760 761 geo->cylinders = (unsigned short)host->cyls; 762 geo->heads = (unsigned char)host->heads; 763 geo->sectors = (unsigned char)host->sectors; 764 return 0; 765} 766 767static struct block_device_operations mg_disk_ops = { 768 .getgeo = mg_getgeo 769}; 770 771static int mg_suspend(struct platform_device *plat_dev, pm_message_t state) 772{ 773 struct mg_drv_data *prv_data = plat_dev->dev.platform_data; 774 struct mg_host *host = prv_data->host; 775 776 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) 777 return -EIO; 778 779 if (!prv_data->use_polling) 780 outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 781 782 outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND); 783 /* wait until mflash deep sleep */ 784 msleep(1); 785 786 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) { 787 if (!prv_data->use_polling) 788 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 789 return -EIO; 790 } 791 792 return 0; 793} 794 795static int mg_resume(struct platform_device *plat_dev) 796{ 797 struct mg_drv_data *prv_data = plat_dev->dev.platform_data; 798 struct mg_host *host = prv_data->host; 799 800 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) 801 return -EIO; 802 803 outb(MG_CMD_WAKEUP, (unsigned long)host->dev_base + MG_REG_COMMAND); 804 /* wait until mflash wakeup */ 805 msleep(1); 806 807 if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) 808 return -EIO; 809 810 if (!prv_data->use_polling) 811 outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); 812 813 return 0; 814} 815 816static int mg_probe(struct platform_device *plat_dev) 817{ 818 struct mg_host *host; 819 struct resource *rsc; 820 struct mg_drv_data *prv_data = plat_dev->dev.platform_data; 821 int err = 0; 822 823 if (!prv_data) { 824 printk(KERN_ERR "%s:%d fail (no driver_data)\n", 825 __func__, __LINE__); 826 err = -EINVAL; 827 goto probe_err; 828 } 829 830 /* alloc mg_host */ 831 host = kzalloc(sizeof(struct mg_host), GFP_KERNEL); 832 if (!host) { 833 printk(KERN_ERR "%s:%d fail (no memory for mg_host)\n", 834 __func__, __LINE__); 835 err = -ENOMEM; 836 goto probe_err; 837 } 838 host->major = MG_DISK_MAJ; 839 840 /* link each other */ 841 prv_data->host = host; 842 host->dev = &plat_dev->dev; 843 844 /* io remap */ 845 rsc = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); 846 if (!rsc) { 847 printk(KERN_ERR "%s:%d platform_get_resource fail\n", 848 __func__, __LINE__); 849 err = -EINVAL; 850 goto probe_err_2; 851 } 852 host->dev_base = ioremap(rsc->start , rsc->end + 1); 853 if (!host->dev_base) { 854 printk(KERN_ERR "%s:%d ioremap fail\n", 855 __func__, __LINE__); 856 err = -EIO; 857 goto probe_err_2; 858 } 859 MG_DBG("dev_base = 0x%x\n", (u32)host->dev_base); 860 861 /* get reset pin */ 862 rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO, 863 MG_RST_PIN); 864 if (!rsc) { 865 printk(KERN_ERR "%s:%d get reset pin fail\n", 866 __func__, __LINE__); 867 err = -EIO; 868 goto probe_err_3; 869 } 870 host->rst = rsc->start; 871 872 /* init rst pin */ 873 err = gpio_request(host->rst, MG_RST_PIN); 874 if (err) 875 goto probe_err_3; 876 gpio_direction_output(host->rst, 1); 877 878 /* reset out pin */ 879 if (!(prv_data->dev_attr & MG_DEV_MASK)) 880 goto probe_err_3a; 881 882 if (prv_data->dev_attr != MG_BOOT_DEV) { 883 rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO, 884 MG_RSTOUT_PIN); 885 if (!rsc) { 886 printk(KERN_ERR "%s:%d get reset-out pin fail\n", 887 __func__, __LINE__); 888 err = -EIO; 889 goto probe_err_3a; 890 } 891 host->rstout = rsc->start; 892 err = gpio_request(host->rstout, MG_RSTOUT_PIN); 893 if (err) 894 goto probe_err_3a; 895 gpio_direction_input(host->rstout); 896 } 897 898 /* disk reset */ 899 if (prv_data->dev_attr == MG_STORAGE_DEV) { 900 /* If POR seq. not yet finised, wait */ 901 err = mg_wait_rstout(host->rstout, MG_TMAX_RSTOUT); 902 if (err) 903 goto probe_err_3b; 904 err = mg_disk_init(host); 905 if (err) { 906 printk(KERN_ERR "%s:%d fail (err code : %d)\n", 907 __func__, __LINE__, err); 908 err = -EIO; 909 goto probe_err_3b; 910 } 911 } 912 913 /* get irq resource */ 914 if (!prv_data->use_polling) { 915 host->irq = platform_get_irq(plat_dev, 0); 916 if (host->irq == -ENXIO) { 917 err = host->irq; 918 goto probe_err_3b; 919 } 920 err = request_irq(host->irq, mg_irq, 921 IRQF_DISABLED | IRQF_TRIGGER_RISING, 922 MG_DEV_NAME, host); 923 if (err) { 924 printk(KERN_ERR "%s:%d fail (request_irq err=%d)\n", 925 __func__, __LINE__, err); 926 goto probe_err_3b; 927 } 928 929 } 930 931 /* get disk id */ 932 err = mg_get_disk_id(host); 933 if (err) { 934 printk(KERN_ERR "%s:%d fail (err code : %d)\n", 935 __func__, __LINE__, err); 936 err = -EIO; 937 goto probe_err_4; 938 } 939 940 err = register_blkdev(host->major, MG_DISK_NAME); 941 if (err < 0) { 942 printk(KERN_ERR "%s:%d register_blkdev fail (err code : %d)\n", 943 __func__, __LINE__, err); 944 goto probe_err_4; 945 } 946 if (!host->major) 947 host->major = err; 948 949 spin_lock_init(&host->lock); 950 951 if (prv_data->use_polling) 952 host->breq = blk_init_queue(mg_request_poll, &host->lock); 953 else 954 host->breq = blk_init_queue(mg_request, &host->lock); 955 956 if (!host->breq) { 957 err = -ENOMEM; 958 printk(KERN_ERR "%s:%d (blk_init_queue) fail\n", 959 __func__, __LINE__); 960 goto probe_err_5; 961 } 962 host->breq->queuedata = host; 963 964 /* mflash is random device, thanx for the noop */ 965 elevator_exit(host->breq->elevator); 966 err = elevator_init(host->breq, "noop"); 967 if (err) { 968 printk(KERN_ERR "%s:%d (elevator_init) fail\n", 969 __func__, __LINE__); 970 goto probe_err_6; 971 } 972 blk_queue_max_sectors(host->breq, MG_MAX_SECTS); 973 blk_queue_logical_block_size(host->breq, MG_SECTOR_SIZE); 974 975 init_timer(&host->timer); 976 host->timer.function = mg_times_out; 977 host->timer.data = (unsigned long)host; 978 979 host->gd = alloc_disk(MG_DISK_MAX_PART); 980 if (!host->gd) { 981 printk(KERN_ERR "%s:%d (alloc_disk) fail\n", 982 __func__, __LINE__); 983 err = -ENOMEM; 984 goto probe_err_7; 985 } 986 host->gd->major = host->major; 987 host->gd->first_minor = 0; 988 host->gd->fops = &mg_disk_ops; 989 host->gd->queue = host->breq; 990 host->gd->private_data = host; 991 sprintf(host->gd->disk_name, MG_DISK_NAME"a"); 992 993 set_capacity(host->gd, host->n_sectors); 994 995 add_disk(host->gd); 996 997 return err; 998 999probe_err_7: 1000 del_timer_sync(&host->timer); 1001probe_err_6: 1002 blk_cleanup_queue(host->breq); 1003probe_err_5: 1004 unregister_blkdev(MG_DISK_MAJ, MG_DISK_NAME); 1005probe_err_4: 1006 if (!prv_data->use_polling) 1007 free_irq(host->irq, host); 1008probe_err_3b: 1009 gpio_free(host->rstout); 1010probe_err_3a: 1011 gpio_free(host->rst); 1012probe_err_3: 1013 iounmap(host->dev_base); 1014probe_err_2: 1015 kfree(host); 1016probe_err: 1017 return err; 1018} 1019 1020static int mg_remove(struct platform_device *plat_dev) 1021{ 1022 struct mg_drv_data *prv_data = plat_dev->dev.platform_data; 1023 struct mg_host *host = prv_data->host; 1024 int err = 0; 1025 1026 /* delete timer */ 1027 del_timer_sync(&host->timer); 1028 1029 /* remove disk */ 1030 if (host->gd) { 1031 del_gendisk(host->gd); 1032 put_disk(host->gd); 1033 } 1034 /* remove queue */ 1035 if (host->breq) 1036 blk_cleanup_queue(host->breq); 1037 1038 /* unregister blk device */ 1039 unregister_blkdev(host->major, MG_DISK_NAME); 1040 1041 /* free irq */ 1042 if (!prv_data->use_polling) 1043 free_irq(host->irq, host); 1044 1045 /* free reset-out pin */ 1046 if (prv_data->dev_attr != MG_BOOT_DEV) 1047 gpio_free(host->rstout); 1048 1049 /* free rst pin */ 1050 if (host->rst) 1051 gpio_free(host->rst); 1052 1053 /* unmap io */ 1054 if (host->dev_base) 1055 iounmap(host->dev_base); 1056 1057 /* free mg_host */ 1058 kfree(host); 1059 1060 return err; 1061} 1062 1063static struct platform_driver mg_disk_driver = { 1064 .probe = mg_probe, 1065 .remove = mg_remove, 1066 .suspend = mg_suspend, 1067 .resume = mg_resume, 1068 .driver = { 1069 .name = MG_DEV_NAME, 1070 .owner = THIS_MODULE, 1071 } 1072}; 1073 1074/**************************************************************************** 1075 * 1076 * Module stuff 1077 * 1078 ****************************************************************************/ 1079 1080static int __init mg_init(void) 1081{ 1082 printk(KERN_INFO "mGine mflash driver, (c) 2008 mGine Co.\n"); 1083 return platform_driver_register(&mg_disk_driver); 1084} 1085 1086static void __exit mg_exit(void) 1087{ 1088 printk(KERN_INFO "mflash driver : bye bye\n"); 1089 platform_driver_unregister(&mg_disk_driver); 1090} 1091 1092module_init(mg_init); 1093module_exit(mg_exit); 1094 1095MODULE_LICENSE("GPL"); 1096MODULE_AUTHOR("unsik Kim <donari75@gmail.com>"); 1097MODULE_DESCRIPTION("mGine m[g]flash device driver");