|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2013 Free Software Foundation ! 3: * ! 4: * This program is free software ; you can redistribute it and/or modify ! 5: * it under the terms of the GNU General Public License as published by ! 6: * the Free Software Foundation ; either version 2 of the License, or ! 7: * (at your option) any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, ! 10: * but WITHOUT ANY WARRANTY ; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 12: * GNU General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with the program ; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: #include <ahci.h> ! 20: #include <kern/assert.h> ! 21: #include <linux/kernel.h> ! 22: #include <linux/types.h> ! 23: #include <linux/pci.h> ! 24: #include <linux/fs.h> ! 25: #include <linux/bios32.h> ! 26: #include <linux/major.h> ! 27: #include <linux/hdreg.h> ! 28: #include <linux/genhd.h> ! 29: #include <asm/io.h> ! 30: ! 31: #define MAJOR_NR SCSI_DISK_MAJOR ! 32: #include <linux/blk.h> ! 33: ! 34: /* Standard AHCI BAR for mmio */ ! 35: #define AHCI_PCI_BAR 5 ! 36: ! 37: /* minor: 2 bits for device number, 6 bits for partition number. */ ! 38: ! 39: #define MAX_PORTS 4 ! 40: #define PARTN_BITS 6 ! 41: #define PARTN_MASK ((1<<PARTN_BITS)-1) ! 42: ! 43: /* We need to use one DMA scatter element per physical page. ! 44: * ll_rw_block creates at most 8 buffer heads */ ! 45: /* See MAX_BUF */ ! 46: #define PRDTL_SIZE 8 ! 47: ! 48: #define WAIT_MAX (1*HZ) /* Wait at most 1s for requests completion */ ! 49: ! 50: /* AHCI standard structures */ ! 51: ! 52: struct ahci_prdt { ! 53: u32 dba; /* Data base address */ ! 54: u32 dbau; /* upper 32bit */ ! 55: u32 rsv0; /* Reserved */ ! 56: ! 57: u32 dbc; /* Byte count bits 0-21, ! 58: * bit31 interrupt on completion. */ ! 59: }; ! 60: ! 61: struct ahci_cmd_tbl { ! 62: u8 cfis[64]; ! 63: u8 acmd[16]; ! 64: u8 rsv[48]; ! 65: ! 66: struct ahci_prdt prdtl[PRDTL_SIZE]; ! 67: }; ! 68: ! 69: struct ahci_command { ! 70: u32 opts; /* Command options */ ! 71: ! 72: u32 prdbc; /* Physical Region Descriptor byte count */ ! 73: ! 74: u32 ctba; /* Command Table Descriptor Base Address */ ! 75: u32 ctbau; /* upper 32bit */ ! 76: ! 77: u32 rsv1[4]; /* Reserved */ ! 78: }; ! 79: ! 80: struct ahci_fis_dma { ! 81: u8 fis_type; ! 82: u8 flags; ! 83: u8 rsved[2]; ! 84: u64 id; ! 85: u32 rsvd; ! 86: u32 offset; ! 87: u32 count; ! 88: u32 resvd; ! 89: }; ! 90: ! 91: struct ahci_fis_pio { ! 92: u8 fis_type; ! 93: u8 flags; ! 94: u8 status; ! 95: u8 error; ! 96: ! 97: u8 lba0; ! 98: u8 lba1; ! 99: u8 lba2; ! 100: u8 device; ! 101: ! 102: u8 lba3; ! 103: u8 lba4; ! 104: u8 lba5; ! 105: u8 rsv2; ! 106: ! 107: u8 countl; ! 108: u8 counth; ! 109: u8 rsv3; ! 110: u8 e_status; ! 111: ! 112: u16 tc; /* Transfer Count */ ! 113: u8 rsv4[2]; ! 114: }; ! 115: ! 116: struct ahci_fis_d2h { ! 117: u8 fis_type; ! 118: u8 flags; ! 119: u8 status; ! 120: u8 error; ! 121: ! 122: u8 lba0; ! 123: u8 lba1; ! 124: u8 lba2; ! 125: u8 device; ! 126: ! 127: u8 lba3; ! 128: u8 lba4; ! 129: u8 lba5; ! 130: u8 rsv2; ! 131: ! 132: u8 countl; ! 133: u8 counth; ! 134: u8 rsv3[2]; ! 135: ! 136: u8 rsv4[4]; ! 137: }; ! 138: ! 139: struct ahci_fis_dev { ! 140: u8 rsvd[8]; ! 141: }; ! 142: ! 143: struct ahci_fis_h2d { ! 144: u8 fis_type; ! 145: u8 flags; ! 146: u8 command; ! 147: u8 featurel; ! 148: ! 149: u8 lba0; ! 150: u8 lba1; ! 151: u8 lba2; ! 152: u8 device; ! 153: ! 154: u8 lba3; ! 155: u8 lba4; ! 156: u8 lba5; ! 157: u8 featureh; ! 158: ! 159: u8 countl; ! 160: u8 counth; ! 161: u8 icc; ! 162: u8 control; ! 163: ! 164: u8 rsv1[4]; ! 165: }; ! 166: ! 167: struct ahci_fis_data { ! 168: u8 fis_type; ! 169: u8 flags; ! 170: u8 rsv1[2]; ! 171: u32 data1[]; ! 172: }; ! 173: ! 174: struct ahci_fis { ! 175: struct ahci_fis_dma dma_fis; ! 176: u8 pad0[4]; ! 177: ! 178: struct ahci_fis_pio pio_fis; ! 179: u8 pad1[12]; ! 180: ! 181: struct ahci_fis_d2h d2h_fis; ! 182: u8 pad2[4]; ! 183: ! 184: struct ahci_fis_dev dev_fis; ! 185: ! 186: u8 ufis[64]; ! 187: ! 188: u8 rsv[0x100 - 0xa0]; ! 189: }; ! 190: ! 191: struct ahci_port { ! 192: u32 clb; /* Command List Base address */ ! 193: u32 clbu; /* upper 32bit */ ! 194: u32 fb; /* FIS Base */ ! 195: u32 fbu; /* upper 32bit */ ! 196: u32 is; /* Interrupt Status */ ! 197: u32 ie; /* Interrupt Enable */ ! 198: u32 cmd; /* Command and Status */ ! 199: u32 rsv0; /* Reserved */ ! 200: u32 tfd; /* Task File Data */ ! 201: u32 sig; /* Signature */ ! 202: u32 ssts; /* SATA Status */ ! 203: u32 sctl; /* SATA Control */ ! 204: u32 serr; /* SATA Error */ ! 205: u32 sact; /* SATA Active */ ! 206: u32 ci; /* Command Issue */ ! 207: u32 sntf; /* SATA Notification */ ! 208: u32 fbs; /* FIS-based switch control */ ! 209: u8 rsv1[0x70 - 0x44]; /* Reserved */ ! 210: u8 vendor[0x80 - 0x70]; /* Vendor-specific */ ! 211: }; ! 212: ! 213: struct ahci_host { ! 214: u32 cap; /* Host capabilities */ ! 215: u32 ghc; /* Global Host Control */ ! 216: u32 is; /* Interrupt Status */ ! 217: u32 pi; /* Port Implemented */ ! 218: u32 v; /* Version */ ! 219: u32 ccc_ctl; /* Command Completion Coalescing control */ ! 220: u32 ccc_pts; /* Command Completion Coalescing ports */ ! 221: u32 em_loc; /* Enclosure Management location */ ! 222: u32 em_ctrl; /* Enclosure Management control */ ! 223: u32 cap2; /* Host capabilities extended */ ! 224: u32 bohc; /* BIOS/OS Handoff Control and status */ ! 225: u8 rsv[0xa0 - 0x2c]; /* Reserved */ ! 226: u8 vendor[0x100 - 0xa0]; /* Vendor-specific */ ! 227: struct ahci_port ports[]; /* Up to 32 ports */ ! 228: }; ! 229: ! 230: /* Our own data */ ! 231: ! 232: static struct port { ! 233: /* memory-mapped regions */ ! 234: const volatile struct ahci_host *ahci_host; ! 235: const volatile struct ahci_port *ahci_port; ! 236: ! 237: /* host-memory buffers */ ! 238: struct ahci_command *command; ! 239: struct ahci_fis *fis; ! 240: struct ahci_cmd_tbl *prdtl; ! 241: ! 242: unsigned long long capacity; /* Nr of sectors */ ! 243: u32 status; /* interrupt status */ ! 244: unsigned cls; /* Command list maximum size. ! 245: We currently only use 1. */ ! 246: struct wait_queue *q; /* IRQ wait queue */ ! 247: struct hd_struct *part; /* drive partition table */ ! 248: unsigned lba48; /* Whether LBA48 is supported */ ! 249: unsigned identify; /* Whether we are just identifying ! 250: at boot */ ! 251: struct gendisk *gd; ! 252: } ports[MAX_PORTS]; ! 253: ! 254: ! 255: /* do_request() gets called by the block layer to push a request to the disk. ! 256: We just push one, and when an interrupt tells it's over, we call do_request() ! 257: ourself again to push the next request, etc. */ ! 258: ! 259: /* Request completed, either successfully or with an error */ ! 260: static void ahci_end_request(int uptodate) ! 261: { ! 262: struct request *rq = CURRENT; ! 263: struct buffer_head *bh; ! 264: ! 265: rq->errors = 0; ! 266: if (!uptodate) { ! 267: printk("end_request: I/O error, dev %s, sector %lu\n", ! 268: kdevname(rq->rq_dev), rq->sector); ! 269: assert(0); ! 270: } ! 271: ! 272: for (bh = rq->bh; bh; ) ! 273: { ! 274: struct buffer_head *next = bh->b_reqnext; ! 275: bh->b_reqnext = NULL; ! 276: mark_buffer_uptodate (bh, uptodate); ! 277: unlock_buffer (bh); ! 278: bh = next; ! 279: } ! 280: ! 281: CURRENT = rq->next; ! 282: if (rq->sem != NULL) ! 283: up(rq->sem); ! 284: rq->rq_status = RQ_INACTIVE; ! 285: wake_up(&wait_for_request); ! 286: } ! 287: ! 288: /* Push the request to the controler port */ ! 289: static void ahci_do_port_request(struct port *port, unsigned sector, struct request *rq) ! 290: { ! 291: struct ahci_command *command = port->command; ! 292: struct ahci_cmd_tbl *prdtl = port->prdtl; ! 293: struct ahci_fis_h2d *fis_h2d; ! 294: unsigned slot = 0; ! 295: struct buffer_head *bh; ! 296: unsigned i; ! 297: ! 298: rq->rq_status = RQ_SCSI_BUSY; ! 299: ! 300: /* Shouldn't ever happen: the block glue is limited at 8 blocks */ ! 301: assert(rq->nr_sectors < 0x10000); ! 302: ! 303: fis_h2d = (void*) &prdtl[slot].cfis; ! 304: fis_h2d->fis_type = FIS_TYPE_REG_H2D; ! 305: fis_h2d->flags = 128; ! 306: if (port->lba48) ! 307: if (rq->cmd == READ) ! 308: fis_h2d->command = WIN_READDMA_EXT; ! 309: else ! 310: fis_h2d->command = WIN_WRITEDMA_EXT; ! 311: else ! 312: if (rq->cmd == READ) ! 313: fis_h2d->command = WIN_READDMA; ! 314: else ! 315: fis_h2d->command = WIN_WRITEDMA; ! 316: ! 317: fis_h2d->device = 1<<6; /* LBA */ ! 318: ! 319: fis_h2d->lba0 = sector; ! 320: fis_h2d->lba1 = sector >> 8; ! 321: fis_h2d->lba2 = sector >> 16; ! 322: ! 323: fis_h2d->lba3 = sector >> 24; ! 324: fis_h2d->lba4 = 0; ! 325: fis_h2d->lba5 = 0; ! 326: ! 327: fis_h2d->countl = rq->nr_sectors; ! 328: fis_h2d->counth = rq->nr_sectors >> 8; ! 329: ! 330: command[slot].opts = sizeof(*fis_h2d) / sizeof(u32); ! 331: ! 332: if (rq->cmd == WRITE) ! 333: command[slot].opts |= AHCI_CMD_WRITE; ! 334: ! 335: for (i = 0, bh = rq->bh; bh; i++, bh = bh->b_reqnext) ! 336: { ! 337: assert(i < PRDTL_SIZE); ! 338: assert((((unsigned long) bh->b_data) & ~PAGE_MASK) == ! 339: (((unsigned long) bh->b_data + bh->b_size - 1) & ~PAGE_MASK)); ! 340: prdtl[slot].prdtl[i].dbau = 0; ! 341: prdtl[slot].prdtl[i].dba = vmtophys(bh->b_data); ! 342: prdtl[slot].prdtl[i].dbc = bh->b_size - 1; ! 343: } ! 344: ! 345: command[slot].opts |= i << 16; ! 346: ! 347: /* Make sure main memory buffers are up to date */ ! 348: mb(); ! 349: ! 350: /* Issue command */ ! 351: writel(1 << slot, &port->ahci_port->ci); ! 352: ! 353: /* TODO: IRQ timeout handler */ ! 354: } ! 355: ! 356: /* Called by block core to push a request */ ! 357: /* TODO: ideally, would have one request queue per port */ ! 358: /* TODO: ideally, would use tags to process several requests at a time */ ! 359: static void ahci_do_request() /* invoked with cli() */ ! 360: { ! 361: struct request *rq; ! 362: unsigned minor, unit; ! 363: unsigned long block, blockend; ! 364: struct port *port; ! 365: ! 366: rq = CURRENT; ! 367: if (!rq) ! 368: return; ! 369: ! 370: if (rq->rq_status != RQ_ACTIVE) ! 371: /* Current one is already ongoing, let the interrupt handler ! 372: * push the new one when the current one is finished. */ ! 373: return; ! 374: ! 375: if (MAJOR(rq->rq_dev) != MAJOR_NR) { ! 376: printk("bad ahci major %u\n", MAJOR(rq->rq_dev)); ! 377: goto kill_rq; ! 378: } ! 379: ! 380: minor = MINOR(rq->rq_dev); ! 381: unit = minor >> PARTN_BITS; ! 382: if (unit > MAX_PORTS) { ! 383: printk("bad ahci unit %u\n", unit); ! 384: goto kill_rq; ! 385: } ! 386: ! 387: port = &ports[unit]; ! 388: ! 389: /* Compute start sector */ ! 390: block = rq->sector; ! 391: block += port->part[minor & PARTN_MASK].start_sect; ! 392: ! 393: /* And check end */ ! 394: blockend = block + rq->nr_sectors; ! 395: if (blockend < block) { ! 396: printk("bad blockend %lu vs %lu\n", blockend, block); ! 397: goto kill_rq; ! 398: } ! 399: if (blockend > port->capacity) { ! 400: printk("offset for %u was %lu\n", minor, port->part[minor & PARTN_MASK].start_sect); ! 401: printk("bad access: block %lu, count= %lu\n", blockend, (unsigned long) port->capacity); ! 402: goto kill_rq; ! 403: } ! 404: ! 405: /* Push this to the port */ ! 406: ahci_do_port_request(port, block, rq); ! 407: return; ! 408: ! 409: kill_rq: ! 410: ahci_end_request(0); ! 411: } ! 412: ! 413: /* The given port got an interrupt, terminate the current request if any */ ! 414: static void ahci_port_interrupt(struct port *port, u32 status) ! 415: { ! 416: unsigned slot = 0; ! 417: ! 418: if (readl(&port->ahci_port->ci) & (1 << slot)) { ! 419: /* Command still pending */ ! 420: return; ! 421: } ! 422: ! 423: if (port->identify) { ! 424: port->status = status; ! 425: wake_up(&port->q); ! 426: return; ! 427: } ! 428: ! 429: if (!CURRENT || CURRENT->rq_status != RQ_SCSI_BUSY) { ! 430: /* No request currently running */ ! 431: return; ! 432: } ! 433: ! 434: if (status & (PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR | PORT_IRQ_IF_NONFATAL)) { ! 435: printk("ahci error %x %x\n", status, readl(&port->ahci_port->tfd)); ! 436: ahci_end_request(0); ! 437: return; ! 438: } ! 439: ! 440: ahci_end_request(1); ! 441: } ! 442: ! 443: /* Start of IRQ handler. Iterate over all ports for this host */ ! 444: static void ahci_interrupt (int irq, void *host, struct pt_regs *regs) ! 445: { ! 446: struct port *port; ! 447: struct ahci_host *ahci_host = host; ! 448: u32 irq_mask; ! 449: u32 status; ! 450: ! 451: irq_mask = readl(&ahci_host->is); ! 452: ! 453: if (!irq_mask) ! 454: return; ! 455: ! 456: for (port = &ports[0]; port < &ports[MAX_PORTS]; port++) { ! 457: if (port->ahci_host == ahci_host && (irq_mask & (1 << (port->ahci_port - ahci_host->ports)))) { ! 458: status = readl(&port->ahci_port->is); ! 459: /* Clear interrupt before possibly triggering others */ ! 460: writel(status, &port->ahci_port->is); ! 461: ahci_port_interrupt (port, status); ! 462: } ! 463: } ! 464: ! 465: if (CURRENT) ! 466: /* Still some requests, queue another one */ ! 467: ahci_do_request(); ! 468: ! 469: /* Clear host after clearing ports */ ! 470: writel(irq_mask, &ahci_host->is); ! 471: ! 472: /* unlock */ ! 473: } ! 474: ! 475: static int ahci_ioctl (struct inode *inode, struct file *file, ! 476: unsigned int cmd, unsigned long arg) ! 477: { ! 478: int major, unit; ! 479: ! 480: if (!inode || !inode->i_rdev) ! 481: return -EINVAL; ! 482: ! 483: major = MAJOR(inode->i_rdev); ! 484: if (major != MAJOR_NR) ! 485: return -ENOTTY; ! 486: ! 487: unit = DEVICE_NR(inode->i_rdev); ! 488: if (unit >= MAX_PORTS) ! 489: return -EINVAL; ! 490: ! 491: switch (cmd) { ! 492: case BLKRRPART: ! 493: if (!suser()) return -EACCES; ! 494: if (!ports[unit].gd) ! 495: return -EINVAL; ! 496: resetup_one_dev(ports[unit].gd, unit); ! 497: return 0; ! 498: default: ! 499: return -EPERM; ! 500: } ! 501: } ! 502: ! 503: static int ahci_open (struct inode *inode, struct file *file) ! 504: { ! 505: int target; ! 506: ! 507: if (MAJOR(inode->i_rdev) != MAJOR_NR) ! 508: return -ENXIO; ! 509: ! 510: target = MINOR(inode->i_rdev) >> PARTN_BITS; ! 511: if (target >= MAX_PORTS) ! 512: return -ENXIO; ! 513: ! 514: if (!ports[target].ahci_port) ! 515: return -ENXIO; ! 516: ! 517: return 0; ! 518: } ! 519: ! 520: static void ahci_release (struct inode *inode, struct file *file) ! 521: { ! 522: } ! 523: ! 524: static int ahci_fsync (struct inode *inode, struct file *file) ! 525: { ! 526: printk("fsync\n"); ! 527: return -ENOSYS; ! 528: } ! 529: ! 530: static struct file_operations ahci_fops = { ! 531: .lseek = NULL, ! 532: .read = block_read, ! 533: .write = block_write, ! 534: .readdir = NULL, ! 535: .select = NULL, ! 536: .ioctl = ahci_ioctl, ! 537: .mmap = NULL, ! 538: .open = ahci_open, ! 539: .release = ahci_release, ! 540: .fsync = ahci_fsync, ! 541: .fasync = NULL, ! 542: .check_media_change = NULL, ! 543: .revalidate = NULL, ! 544: }; ! 545: ! 546: /* Disk timed out while processing identify, interrupt ahci_probe_port */ ! 547: static void identify_timeout(unsigned long data) ! 548: { ! 549: struct port *port = (void*) data; ! 550: ! 551: wake_up(&port->q); ! 552: } ! 553: ! 554: static struct timer_list identify_timer = { .function = identify_timeout }; ! 555: ! 556: /* Probe one AHCI port */ ! 557: static void ahci_probe_port(const volatile struct ahci_host *ahci_host, const volatile struct ahci_port *ahci_port) ! 558: { ! 559: struct port *port; ! 560: void *mem; ! 561: struct hd_driveid id; ! 562: unsigned cls = ((readl(&ahci_host->cap) >> 8) & 0x1f) + 1; ! 563: struct ahci_command *command; ! 564: struct ahci_fis *fis; ! 565: struct ahci_cmd_tbl *prdtl; ! 566: struct ahci_fis_h2d *fis_h2d; ! 567: vm_size_t size = ! 568: cls * sizeof(*command) ! 569: + sizeof(*fis) ! 570: + cls * sizeof(*prdtl); ! 571: unsigned i; ! 572: unsigned slot; ! 573: unsigned long first_part; ! 574: unsigned long long timeout; ! 575: unsigned long flags; ! 576: ! 577: for (i = 0; i < MAX_PORTS; i++) { ! 578: if (!ports[i].ahci_port) ! 579: break; ! 580: } ! 581: if (i == MAX_PORTS) ! 582: return; ! 583: port = &ports[i]; ! 584: ! 585: /* Has to be 1K-aligned */ ! 586: mem = vmalloc (size); ! 587: if (!mem) ! 588: return; ! 589: assert (!(((unsigned long) mem) & (1024-1))); ! 590: memset (mem, 0, size); ! 591: ! 592: port->ahci_host = ahci_host; ! 593: port->ahci_port = ahci_port; ! 594: port->cls = cls; ! 595: ! 596: port->command = command = mem; ! 597: port->fis = fis = (void*) command + cls * sizeof(*command); ! 598: port->prdtl = prdtl = (void*) fis + sizeof(*fis); ! 599: ! 600: /* Stop commands */ ! 601: writel(readl(&ahci_port->cmd) & ~PORT_CMD_START, &ahci_port->cmd); ! 602: timeout = jiffies + WAIT_MAX; ! 603: while (readl(&ahci_port->cmd) & PORT_CMD_LIST_ON) ! 604: if (jiffies > timeout) { ! 605: printk("sd%u: timeout waiting for list completion\n", port-ports); ! 606: port->ahci_host = NULL; ! 607: port->ahci_port = NULL; ! 608: return; ! 609: } ! 610: ! 611: writel(readl(&ahci_port->cmd) & ~PORT_CMD_FIS_RX, &ahci_port->cmd); ! 612: timeout = jiffies + WAIT_MAX; ! 613: while (readl(&ahci_port->cmd) & PORT_CMD_FIS_ON) ! 614: if (jiffies > timeout) { ! 615: printk("sd%u: timeout waiting for FIS completion\n", port-ports); ! 616: port->ahci_host = NULL; ! 617: port->ahci_port = NULL; ! 618: return; ! 619: } ! 620: ! 621: /* We don't support 64bit */ ! 622: /* Point controller to our buffers */ ! 623: writel(0, &ahci_port->clbu); ! 624: writel(vmtophys((void*) command), &ahci_port->clb); ! 625: writel(0, &ahci_port->fbu); ! 626: writel(vmtophys((void*) fis), &ahci_port->fb); ! 627: ! 628: /* Clear any previous interrupts */ ! 629: writel(readl(&ahci_port->is), &ahci_port->is); ! 630: writel(1 << (ahci_port - ahci_host->ports), &ahci_host->is); ! 631: ! 632: /* And activate them */ ! 633: writel(DEF_PORT_IRQ, &ahci_port->ie); ! 634: writel(readl(&ahci_host->ghc) | HOST_IRQ_EN, &ahci_host->ghc); ! 635: ! 636: for (i = 0; i < cls; i++) ! 637: { ! 638: command[i].ctbau = 0; ! 639: command[i].ctba = vmtophys((void*) &prdtl[i]); ! 640: } ! 641: ! 642: /* Start commands */ ! 643: timeout = jiffies + WAIT_MAX; ! 644: while (readl(&ahci_port->cmd) & PORT_CMD_LIST_ON) ! 645: if (jiffies > timeout) { ! 646: printk("sd%u: timeout waiting for list completion\n", port-ports); ! 647: port->ahci_host = NULL; ! 648: port->ahci_port = NULL; ! 649: return; ! 650: } ! 651: ! 652: writel(readl(&ahci_port->cmd) | PORT_CMD_FIS_RX | PORT_CMD_START, &ahci_port->cmd); ! 653: ! 654: /* Identify device */ ! 655: /* TODO: make this a request */ ! 656: slot = 0; ! 657: ! 658: fis_h2d = (void*) &prdtl[slot].cfis; ! 659: fis_h2d->fis_type = FIS_TYPE_REG_H2D; ! 660: fis_h2d->flags = 128; ! 661: fis_h2d->command = WIN_IDENTIFY; ! 662: fis_h2d->device = 0; ! 663: ! 664: /* Fetch the 512 identify data */ ! 665: memset(&id, 0, sizeof(id)); ! 666: ! 667: command[slot].opts = sizeof(*fis_h2d) / sizeof(u32); ! 668: ! 669: first_part = PAGE_ALIGN((unsigned long) &id) - (unsigned long) &id; ! 670: ! 671: if (first_part && first_part < sizeof(id)) { ! 672: /* split over two pages */ ! 673: ! 674: command[slot].opts |= (2 << 16); ! 675: ! 676: prdtl[slot].prdtl[0].dbau = 0; ! 677: prdtl[slot].prdtl[0].dba = vmtophys((void*) &id); ! 678: prdtl[slot].prdtl[0].dbc = first_part - 1; ! 679: prdtl[slot].prdtl[1].dbau = 0; ! 680: prdtl[slot].prdtl[1].dba = vmtophys((void*) &id + first_part); ! 681: prdtl[slot].prdtl[1].dbc = sizeof(id) - first_part - 1; ! 682: } ! 683: else ! 684: { ! 685: command[slot].opts |= (1 << 16); ! 686: ! 687: prdtl[slot].prdtl[0].dbau = 0; ! 688: prdtl[slot].prdtl[0].dba = vmtophys((void*) &id); ! 689: prdtl[slot].prdtl[0].dbc = sizeof(id) - 1; ! 690: } ! 691: ! 692: timeout = jiffies + WAIT_MAX; ! 693: while (readl(&ahci_port->tfd) & (BUSY_STAT | DRQ_STAT)) ! 694: if (jiffies > timeout) { ! 695: printk("sd%u: timeout waiting for ready\n", port-ports); ! 696: port->ahci_host = NULL; ! 697: port->ahci_port = NULL; ! 698: return; ! 699: } ! 700: ! 701: save_flags(flags); ! 702: cli(); ! 703: ! 704: port->identify = 1; ! 705: port->status = 0; ! 706: ! 707: /* Issue command */ ! 708: mb(); ! 709: writel(1 << slot, &ahci_port->ci); ! 710: ! 711: timeout = jiffies + WAIT_MAX; ! 712: identify_timer.expires = timeout; ! 713: identify_timer.data = (unsigned long) port; ! 714: add_timer(&identify_timer); ! 715: while (!port->status) { ! 716: if (jiffies >= timeout) { ! 717: printk("sd%u: timeout waiting for ready\n", port-ports); ! 718: port->ahci_host = NULL; ! 719: port->ahci_port = NULL; ! 720: del_timer(&identify_timer); ! 721: return; ! 722: } ! 723: sleep_on(&port->q); ! 724: } ! 725: del_timer(&identify_timer); ! 726: restore_flags(flags); ! 727: ! 728: if (readl(&ahci_port->is) & PORT_IRQ_TF_ERR) ! 729: { ! 730: printk("sd%u: identify error\n", port-ports); ! 731: port->capacity = 0; ! 732: port->lba48 = 0; ! 733: } else { ! 734: ide_fixstring(id.model, sizeof(id.model), 1); ! 735: ide_fixstring(id.fw_rev, sizeof(id.fw_rev), 1); ! 736: ide_fixstring(id.serial_no, sizeof(id.serial_no), 1); ! 737: if (id.command_set_2 & (1U<<10)) ! 738: { ! 739: port->lba48 = 1; ! 740: port->capacity = id.lba_capacity_2; ! 741: if (port->capacity >= (1ULL << 32)) ! 742: { ! 743: port->capacity = (1ULL << 32) - 1; ! 744: printk("Warning: truncating disk size to 2TiB\n"); ! 745: } ! 746: } ! 747: else ! 748: { ! 749: port->lba48 = 0; ! 750: port->capacity = id.lba_capacity; ! 751: if (port->capacity > (1ULL << 24)) ! 752: { ! 753: port->capacity = (1ULL << 24); ! 754: printk("Warning: truncating disk size to 128GiB\n"); ! 755: } ! 756: } ! 757: if (port->capacity/2048 >= 10240) ! 758: printk("sd%u: %s, %uGB w/%dkB Cache\n", port - ports, id.model, (unsigned) (port->capacity/(2048*1024)), id.buf_size/2); ! 759: else ! 760: printk("sd%u: %s, %uMB w/%dkB Cache\n", port - ports, id.model, (unsigned) (port->capacity/2048), id.buf_size/2); ! 761: } ! 762: port->identify = 0; ! 763: } ! 764: ! 765: /* Probe one AHCI PCI device */ ! 766: static void ahci_probe_dev(unsigned char bus, unsigned char device) ! 767: { ! 768: unsigned char hdrtype; ! 769: unsigned char dev, fun; ! 770: const volatile struct ahci_host *ahci_host; ! 771: const volatile struct ahci_port *ahci_port; ! 772: unsigned nports, n, i; ! 773: unsigned port_map; ! 774: unsigned bar; ! 775: unsigned char irq; ! 776: ! 777: dev = PCI_SLOT(device); ! 778: fun = PCI_FUNC(device); ! 779: ! 780: /* Get configuration */ ! 781: if (pcibios_read_config_byte(bus, device, PCI_HEADER_TYPE, &hdrtype) != PCIBIOS_SUCCESSFUL) { ! 782: printk("ahci: %02u:%02u.%u: Can not read configuration", bus, dev, fun); ! 783: return; ! 784: } ! 785: ! 786: if (hdrtype != 0) { ! 787: printk("ahci: %02u:%02u.%u: Unknown hdrtype %d\n", bus, dev, fun, hdrtype); ! 788: return; ! 789: } ! 790: ! 791: if (pcibios_read_config_dword(bus, device, PCI_BASE_ADDRESS_5, &bar) != PCIBIOS_SUCCESSFUL) { ! 792: printk("ahci: %02u:%02u.%u: Can not read BAR 5", bus, dev, fun); ! 793: return; ! 794: } ! 795: if (bar & 0x01) { ! 796: printk("ahci: %02u:%02u.%u: BAR 5 is I/O?!", bus, dev, fun); ! 797: return; ! 798: } ! 799: bar &= ~0x0f; ! 800: ! 801: if (pcibios_read_config_byte(bus, device, PCI_INTERRUPT_LINE, &irq) != PCIBIOS_SUCCESSFUL) { ! 802: printk("ahci: %02u:%02u.%u: Can not read IRQ", bus, dev, fun); ! 803: return; ! 804: } ! 805: ! 806: printk("AHCI SATA %02u:%02u.%u BAR 0x%x IRQ %u\n", bus, dev, fun, bar, irq); ! 807: ! 808: /* Map mmio */ ! 809: ahci_host = vremap(bar, 0x2000); ! 810: ! 811: /* Request IRQ */ ! 812: if (request_irq(irq, &ahci_interrupt, SA_SHIRQ, "ahci", (void*) ahci_host)) { ! 813: printk("ahci: %02u:%02u.%u: Can not get irq %u\n", bus, dev, fun, irq); ! 814: return; ! 815: } ! 816: ! 817: nports = (readl(&ahci_host->cap) & 0x1f) + 1; ! 818: port_map = readl(&ahci_host->pi); ! 819: ! 820: for (n = 0, i = 0; i < AHCI_MAX_PORTS; i++) ! 821: if (port_map & (1U << i)) ! 822: n++; ! 823: ! 824: if (nports != n) { ! 825: printk("ahci: %02u:%02u.%u: Odd number of ports, assuming %d is correct\n", bus, dev, fun, nports); ! 826: port_map = 0; ! 827: } ! 828: if (!port_map) { ! 829: port_map = (1U << nports) - 1; ! 830: } ! 831: ! 832: for (i = 0; i < AHCI_MAX_PORTS; i++) { ! 833: u32 ssts; ! 834: ! 835: if (!(port_map & (1U << i))) ! 836: continue; ! 837: ! 838: ahci_port = &ahci_host->ports[i]; ! 839: ! 840: ssts = readl(&ahci_port->ssts); ! 841: if ((ssts & 0xf) != 0x3) ! 842: /* Device not present */ ! 843: continue; ! 844: if (((ssts >> 8) & 0xf) != 0x1) ! 845: /* Device down */ ! 846: continue; ! 847: ! 848: /* OK! Probe this port */ ! 849: ahci_probe_port(ahci_host, ahci_port); ! 850: } ! 851: } ! 852: ! 853: /* genhd callback to set size of disks */ ! 854: static void ahci_geninit(struct gendisk *gd) ! 855: { ! 856: unsigned unit; ! 857: struct port *port; ! 858: ! 859: for (unit = 0; unit < gd->nr_real; unit++) { ! 860: port = &ports[unit]; ! 861: port->part[0].nr_sects = port->capacity; ! 862: } ! 863: } ! 864: ! 865: /* Probe all AHCI PCI devices */ ! 866: void ahci_probe_pci(void) ! 867: { ! 868: unsigned char bus, device; ! 869: unsigned short index; ! 870: int ret; ! 871: unsigned nports, unit, nminors; ! 872: struct port *port; ! 873: struct gendisk *gd, **gdp; ! 874: int *bs; ! 875: ! 876: for (index = 0; ! 877: (ret = pcibios_find_class(PCI_CLASS_STORAGE_SATA_AHCI, index, &bus, &device)) == PCIBIOS_SUCCESSFUL; ! 878: index++) ! 879: { ! 880: /* Note: this prevents from also having a SCSI controler. ! 881: * It shouldn't harm too much until we have proper hardware ! 882: * enumeration. ! 883: */ ! 884: if (register_blkdev(MAJOR_NR, "sd", &ahci_fops) < 0) ! 885: printk("could not register ahci\n"); ! 886: ahci_probe_dev(bus, device); ! 887: } ! 888: ! 889: for (nports = 0, port = &ports[0]; port < &ports[MAX_PORTS]; port++) ! 890: if (port->ahci_port) ! 891: nports++; ! 892: ! 893: nminors = nports * (1<<PARTN_BITS); ! 894: ! 895: gd = kmalloc(sizeof(*gd), GFP_KERNEL); ! 896: gd->sizes = kmalloc(nminors * sizeof(*gd->sizes), GFP_KERNEL); ! 897: gd->part = kmalloc(nminors * sizeof(*gd->part), GFP_KERNEL); ! 898: bs = kmalloc(nminors * sizeof(*bs), GFP_KERNEL); ! 899: ! 900: blksize_size[MAJOR_NR] = bs; ! 901: for (unit = 0; unit < nminors; unit++) ! 902: /* We prefer to transfer whole pages */ ! 903: *bs++ = PAGE_SIZE; ! 904: ! 905: memset(gd->part, 0, nminors * sizeof(*gd->part)); ! 906: ! 907: for (unit = 0; unit < nports; unit++) { ! 908: ports[unit].gd = gd; ! 909: ports[unit].part = &gd->part[unit << PARTN_BITS]; ! 910: } ! 911: ! 912: gd->major = MAJOR_NR; ! 913: gd->major_name = "sd"; ! 914: gd->minor_shift = PARTN_BITS; ! 915: gd->max_p = 1<<PARTN_BITS; ! 916: gd->max_nr = nports; ! 917: gd->nr_real = nports; ! 918: gd->init = ahci_geninit; ! 919: gd->next = NULL; ! 920: ! 921: for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) ! 922: ; ! 923: *gdp = gd; ! 924: ! 925: blk_dev[MAJOR_NR].request_fn = ahci_do_request; ! 926: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.