|
|
1.1 ! root 1: /* ! 2: * OpenBIOS polled ide driver ! 3: * ! 4: * Copyright (C) 2004 Jens Axboe <[email protected]> ! 5: * Copyright (C) 2005 Stefan Reinauer <[email protected]> ! 6: * ! 7: * Credit goes to Hale Landis for his excellent ata demo software ! 8: * OF node handling and some fixes by Stefan Reinauer ! 9: * ! 10: * This program is free software; you can redistribute it and/or ! 11: * modify it under the terms of the GNU General Public License ! 12: * version 2 ! 13: * ! 14: */ ! 15: ! 16: #include "config.h" ! 17: #include "libopenbios/bindings.h" ! 18: #include "kernel/kernel.h" ! 19: #include "libc/byteorder.h" ! 20: #include "libc/vsprintf.h" ! 21: ! 22: #include "drivers/drivers.h" ! 23: #include "ide.h" ! 24: #include "hdreg.h" ! 25: #include "timer.h" ! 26: ! 27: #ifdef CONFIG_DEBUG_IDE ! 28: #define IDE_DPRINTF(fmt, args...) \ ! 29: do { printk("IDE - %s: " fmt, __func__ , ##args); } while (0) ! 30: #else ! 31: #define IDE_DPRINTF(fmt, args...) do { } while (0) ! 32: #endif ! 33: ! 34: /* DECLARE data structures for the nodes. */ ! 35: DECLARE_UNNAMED_NODE( ob_ide, INSTALL_OPEN, sizeof(struct ide_drive*) ); ! 36: DECLARE_UNNAMED_NODE( ob_ide_ctrl, INSTALL_OPEN, sizeof(int)); ! 37: ! 38: /* ! 39: * define to 2 for the standard 2 channels only ! 40: */ ! 41: #ifndef CONFIG_IDE_NUM_CHANNELS ! 42: #define IDE_NUM_CHANNELS 4 ! 43: #else ! 44: #define IDE_NUM_CHANNELS CONFIG_IDE_NUM_CHANNELS ! 45: #endif ! 46: #define IDE_MAX_CHANNELS 4 ! 47: ! 48: #ifndef CONFIG_IDE_FIRST_UNIT ! 49: #define FIRST_UNIT 0 ! 50: #else ! 51: #define FIRST_UNIT CONFIG_IDE_FIRST_UNIT ! 52: #endif ! 53: ! 54: #ifndef CONFIG_IDE_DEV_TYPE ! 55: #define DEV_TYPE "ide" ! 56: #else ! 57: #define DEV_TYPE CONFIG_IDE_DEV_TYPE ! 58: #endif ! 59: ! 60: #ifndef CONFIG_IDE_DEV_NAME ! 61: #define DEV_NAME "ide%d" ! 62: #else ! 63: #define DEV_NAME CONFIG_IDE_DEV_NAME ! 64: #endif ! 65: ! 66: static int current_channel = FIRST_UNIT; ! 67: ! 68: static struct ide_channel *channels = NULL; ! 69: ! 70: static inline void ide_add_channel(struct ide_channel *chan) ! 71: { ! 72: chan->next = channels; ! 73: channels = chan; ! 74: } ! 75: ! 76: static struct ide_channel *ide_seek_channel(const char *name) ! 77: { ! 78: struct ide_channel *current; ! 79: ! 80: current = channels; ! 81: while (current) { ! 82: if (!strcmp(current->name, name)) ! 83: return current; ! 84: current = current->next; ! 85: } ! 86: return NULL; ! 87: } ! 88: ! 89: /* ! 90: * don't be pedantic ! 91: */ ! 92: #undef ATA_PEDANTIC ! 93: ! 94: static void dump_drive(struct ide_drive *drive) ! 95: { ! 96: #ifdef CONFIG_DEBUG_IDE ! 97: printk("IDE DRIVE @%lx:\n", (unsigned long)drive); ! 98: printk("unit: %d\n",drive->unit); ! 99: printk("present: %d\n",drive->present); ! 100: printk("type: %d\n",drive->type); ! 101: printk("media: %d\n",drive->media); ! 102: printk("model: %s\n",drive->model); ! 103: printk("nr: %d\n",drive->nr); ! 104: printk("cyl: %d\n",drive->cyl); ! 105: printk("head: %d\n",drive->head); ! 106: printk("sect: %d\n",drive->sect); ! 107: printk("bs: %d\n",drive->bs); ! 108: #endif ! 109: } ! 110: ! 111: /* ! 112: * old style io port operations ! 113: */ ! 114: static unsigned char ! 115: ob_ide_inb(struct ide_channel *chan, unsigned int port) ! 116: { ! 117: return inb(chan->io_regs[port]); ! 118: } ! 119: ! 120: static void ! 121: ob_ide_outb(struct ide_channel *chan, unsigned char data, unsigned int port) ! 122: { ! 123: outb(data, chan->io_regs[port]); ! 124: } ! 125: ! 126: static void ! 127: ob_ide_insw(struct ide_channel *chan, ! 128: unsigned int port, unsigned char *addr, unsigned int count) ! 129: { ! 130: insw(chan->io_regs[port], addr, count); ! 131: } ! 132: ! 133: static void ! 134: ob_ide_outsw(struct ide_channel *chan, ! 135: unsigned int port, unsigned char *addr, unsigned int count) ! 136: { ! 137: outsw(chan->io_regs[port], addr, count); ! 138: } ! 139: ! 140: static inline unsigned char ! 141: ob_ide_pio_readb(struct ide_drive *drive, unsigned int offset) ! 142: { ! 143: struct ide_channel *chan = drive->channel; ! 144: ! 145: return chan->obide_inb(chan, offset); ! 146: } ! 147: ! 148: static inline void ! 149: ob_ide_pio_writeb(struct ide_drive *drive, unsigned int offset, ! 150: unsigned char data) ! 151: { ! 152: struct ide_channel *chan = drive->channel; ! 153: ! 154: chan->obide_outb(chan, data, offset); ! 155: } ! 156: ! 157: static inline void ! 158: ob_ide_pio_insw(struct ide_drive *drive, unsigned int offset, ! 159: unsigned char *addr, unsigned int len) ! 160: { ! 161: struct ide_channel *chan = drive->channel; ! 162: ! 163: if (len & 1) { ! 164: IDE_DPRINTF("%d: command not word aligned\n", drive->nr); ! 165: return; ! 166: } ! 167: ! 168: chan->obide_insw(chan, offset, addr, len / 2); ! 169: } ! 170: ! 171: static inline void ! 172: ob_ide_pio_outsw(struct ide_drive *drive, unsigned int offset, ! 173: unsigned char *addr, unsigned int len) ! 174: { ! 175: struct ide_channel *chan = drive->channel; ! 176: ! 177: if (len & 1) { ! 178: IDE_DPRINTF("%d: command not word aligned\n", drive->nr); ! 179: return; ! 180: } ! 181: ! 182: chan->obide_outsw(chan, offset, addr, len / 2); ! 183: } ! 184: ! 185: static void ! 186: ob_ide_400ns_delay(struct ide_drive *drive) ! 187: { ! 188: (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); ! 189: (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); ! 190: (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); ! 191: (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); ! 192: ! 193: udelay(1); ! 194: } ! 195: ! 196: static void ! 197: ob_ide_error(struct ide_drive *drive, unsigned char stat, const char *msg) ! 198: { ! 199: #ifdef CONFIG_DEBUG_IDE ! 200: struct ide_channel *chan = drive->channel; ! 201: unsigned char err; ! 202: #endif ! 203: ! 204: if (!stat) ! 205: stat = ob_ide_pio_readb(drive, IDEREG_STATUS); ! 206: ! 207: IDE_DPRINTF("ob_ide_error drive<%d>: %s:\n", drive->nr, msg); ! 208: IDE_DPRINTF(" cmd=%x, stat=%x", chan->ata_cmd.command, stat); ! 209: ! 210: if ((stat & (BUSY_STAT | ERR_STAT)) == ERR_STAT) { ! 211: #ifdef CONFIG_DEBUG_IDE ! 212: err = ! 213: #endif ! 214: ob_ide_pio_readb(drive, IDEREG_ERROR); ! 215: IDE_DPRINTF(", err=%x", err); ! 216: } ! 217: IDE_DPRINTF("\n"); ! 218: ! 219: #ifdef CONFIG_DEBUG_IDE ! 220: /* ! 221: * see if sense is valid and dump that ! 222: */ ! 223: if (chan->ata_cmd.command == WIN_PACKET) { ! 224: struct atapi_command *cmd = &chan->atapi_cmd; ! 225: unsigned char old_cdb = cmd->cdb[0]; ! 226: ! 227: if (cmd->cdb[0] == ATAPI_REQ_SENSE) { ! 228: old_cdb = cmd->old_cdb; ! 229: ! 230: IDE_DPRINTF(" atapi opcode=%02x", old_cdb); ! 231: } else { ! 232: int i; ! 233: ! 234: IDE_DPRINTF(" cdb: "); ! 235: for (i = 0; i < sizeof(cmd->cdb); i++) ! 236: IDE_DPRINTF("%02x ", cmd->cdb[i]); ! 237: } ! 238: if (cmd->sense_valid) ! 239: IDE_DPRINTF(", sense: %02x/%02x/%02x", ! 240: cmd->sense.sense_key, cmd->sense.asc, ! 241: cmd->sense.ascq); ! 242: else ! 243: IDE_DPRINTF(", no sense"); ! 244: IDE_DPRINTF("\n"); ! 245: } ! 246: #endif ! 247: } ! 248: ! 249: /* ! 250: * wait for 'stat' to be set. returns 1 if failed, 0 if succesful ! 251: */ ! 252: static int ! 253: ob_ide_wait_stat(struct ide_drive *drive, unsigned char ok_stat, ! 254: unsigned char bad_stat, unsigned char *ret_stat) ! 255: { ! 256: unsigned char stat; ! 257: int i; ! 258: ! 259: ob_ide_400ns_delay(drive); ! 260: ! 261: for (i = 0; i < 5000; i++) { ! 262: stat = ob_ide_pio_readb(drive, IDEREG_STATUS); ! 263: if (!(stat & BUSY_STAT)) ! 264: break; ! 265: ! 266: udelay(1000); ! 267: } ! 268: ! 269: if (ret_stat) ! 270: *ret_stat = stat; ! 271: ! 272: if (stat & bad_stat) ! 273: return 1; ! 274: ! 275: if ((stat & ok_stat) || !ok_stat) ! 276: return 0; ! 277: ! 278: return 1; ! 279: } ! 280: ! 281: static int ! 282: ob_ide_select_drive(struct ide_drive *drive) ! 283: { ! 284: struct ide_channel *chan = drive->channel; ! 285: unsigned char control = IDEHEAD_DEV0; ! 286: ! 287: if (ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL)) { ! 288: IDE_DPRINTF("select_drive: timed out\n"); ! 289: return 1; ! 290: } ! 291: ! 292: /* ! 293: * don't select drive if already active. Note: we always ! 294: * wait for BUSY clear ! 295: */ ! 296: if (drive->unit == chan->selected) ! 297: return 0; ! 298: ! 299: if (drive->unit) ! 300: control = IDEHEAD_DEV1; ! 301: ! 302: ob_ide_pio_writeb(drive, IDEREG_CURRENT, control); ! 303: ob_ide_400ns_delay(drive); ! 304: ! 305: if (ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL)) { ! 306: IDE_DPRINTF("select_drive: timed out\n"); ! 307: return 1; ! 308: } ! 309: ! 310: chan->selected = drive->unit; ! 311: return 0; ! 312: } ! 313: ! 314: static void ! 315: ob_ide_write_tasklet(struct ide_drive *drive, struct ata_command *cmd) ! 316: { ! 317: ob_ide_pio_writeb(drive, IDEREG_FEATURE, cmd->task[1]); ! 318: ob_ide_pio_writeb(drive, IDEREG_NSECTOR, cmd->task[3]); ! 319: ob_ide_pio_writeb(drive, IDEREG_SECTOR, cmd->task[7]); ! 320: ob_ide_pio_writeb(drive, IDEREG_LCYL, cmd->task[8]); ! 321: ob_ide_pio_writeb(drive, IDEREG_HCYL, cmd->task[9]); ! 322: ! 323: ob_ide_pio_writeb(drive, IDEREG_FEATURE, cmd->task[0]); ! 324: ob_ide_pio_writeb(drive, IDEREG_NSECTOR, cmd->task[2]); ! 325: ob_ide_pio_writeb(drive, IDEREG_SECTOR, cmd->task[4]); ! 326: ob_ide_pio_writeb(drive, IDEREG_LCYL, cmd->task[5]); ! 327: ob_ide_pio_writeb(drive, IDEREG_HCYL, cmd->task[6]); ! 328: ! 329: if (drive->unit) ! 330: cmd->device_head |= IDEHEAD_DEV1; ! 331: ! 332: ob_ide_pio_writeb(drive, IDEREG_CURRENT, cmd->device_head); ! 333: ! 334: ob_ide_pio_writeb(drive, IDEREG_COMMAND, cmd->command); ! 335: ob_ide_400ns_delay(drive); ! 336: } ! 337: ! 338: static void ! 339: ob_ide_write_registers(struct ide_drive *drive, struct ata_command *cmd) ! 340: { ! 341: /* ! 342: * we are _always_ polled ! 343: */ ! 344: ob_ide_pio_writeb(drive, IDEREG_CONTROL, cmd->control | IDECON_NIEN); ! 345: ! 346: ob_ide_pio_writeb(drive, IDEREG_FEATURE, cmd->feature); ! 347: ob_ide_pio_writeb(drive, IDEREG_NSECTOR, cmd->nsector); ! 348: ob_ide_pio_writeb(drive, IDEREG_SECTOR, cmd->sector); ! 349: ob_ide_pio_writeb(drive, IDEREG_LCYL, cmd->lcyl); ! 350: ob_ide_pio_writeb(drive, IDEREG_HCYL, cmd->hcyl); ! 351: ! 352: if (drive->unit) ! 353: cmd->device_head |= IDEHEAD_DEV1; ! 354: ! 355: ob_ide_pio_writeb(drive, IDEREG_CURRENT, cmd->device_head); ! 356: ! 357: ob_ide_pio_writeb(drive, IDEREG_COMMAND, cmd->command); ! 358: ob_ide_400ns_delay(drive); ! 359: } ! 360: ! 361: /* ! 362: * execute command with "pio non data" protocol ! 363: */ ! 364: #if 0 ! 365: static int ! 366: ob_ide_pio_non_data(struct ide_drive *drive, struct ata_command *cmd) ! 367: { ! 368: if (ob_ide_select_drive(drive)) ! 369: return 1; ! 370: ! 371: ob_ide_write_registers(drive, cmd); ! 372: ! 373: if (ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL)) ! 374: return 1; ! 375: ! 376: return 0; ! 377: } ! 378: #endif ! 379: ! 380: /* ! 381: * execute given command with a pio data-in phase. ! 382: */ ! 383: static int ! 384: ob_ide_pio_data_in(struct ide_drive *drive, struct ata_command *cmd) ! 385: { ! 386: unsigned char stat; ! 387: unsigned int bytes, timeout; ! 388: ! 389: if (ob_ide_select_drive(drive)) ! 390: return 1; ! 391: ! 392: /* ! 393: * ATA must set ready and seek stat, ATAPI need only clear busy ! 394: */ ! 395: timeout = 0; ! 396: do { ! 397: stat = ob_ide_pio_readb(drive, IDEREG_STATUS); ! 398: ! 399: if (drive->type == ide_type_ata) { ! 400: /* ! 401: * this is BIOS code, don't be too pedantic ! 402: */ ! 403: #ifdef ATA_PEDANTIC ! 404: if ((stat & (BUSY_STAT | READY_STAT | SEEK_STAT)) == ! 405: (READY_STAT | SEEK_STAT)) ! 406: break; ! 407: #else ! 408: if ((stat & (BUSY_STAT | READY_STAT)) == READY_STAT) ! 409: break; ! 410: #endif ! 411: } else { ! 412: if (!(stat & BUSY_STAT)) ! 413: break; ! 414: } ! 415: ob_ide_400ns_delay(drive); ! 416: } while (timeout++ < 1000); ! 417: ! 418: if (timeout >= 1000) { ! 419: ob_ide_error(drive, stat, "drive timed out"); ! 420: cmd->stat = stat; ! 421: return 1; ! 422: } ! 423: ! 424: ob_ide_write_registers(drive, cmd); ! 425: ! 426: /* ! 427: * now read the data ! 428: */ ! 429: bytes = cmd->buflen; ! 430: do { ! 431: unsigned count = cmd->buflen; ! 432: ! 433: if (count > drive->bs) ! 434: count = drive->bs; ! 435: ! 436: /* delay 100ms for ATAPI? */ ! 437: ! 438: /* ! 439: * wait for BUSY clear ! 440: */ ! 441: if (ob_ide_wait_stat(drive, 0, BUSY_STAT | ERR_STAT, &stat)) { ! 442: ob_ide_error(drive, stat, "timed out waiting for BUSY clear"); ! 443: cmd->stat = stat; ! 444: break; ! 445: } ! 446: ! 447: /* ! 448: * transfer the data ! 449: */ ! 450: if ((stat & (BUSY_STAT | DRQ_STAT)) == DRQ_STAT) { ! 451: ob_ide_pio_insw(drive, IDEREG_DATA, cmd->buffer, count); ! 452: cmd->bytes -= count; ! 453: cmd->buffer += count; ! 454: bytes -= count; ! 455: ! 456: ob_ide_400ns_delay(drive); ! 457: } ! 458: ! 459: if (stat & (BUSY_STAT | WRERR_STAT | ERR_STAT)) { ! 460: cmd->stat = stat; ! 461: break; ! 462: } ! 463: ! 464: if (!(stat & DRQ_STAT)) { ! 465: cmd->stat = stat; ! 466: break; ! 467: } ! 468: } while (bytes); ! 469: ! 470: if (bytes) ! 471: IDE_DPRINTF("bytes=%d, stat=%x\n", bytes, stat); ! 472: ! 473: return bytes ? 1 : 0; ! 474: } ! 475: ! 476: /* ! 477: * execute ata command with pio packet protocol ! 478: */ ! 479: static int ! 480: ob_ide_pio_packet(struct ide_drive *drive, struct atapi_command *cmd) ! 481: { ! 482: unsigned char stat, reason, lcyl, hcyl; ! 483: struct ata_command *acmd = &drive->channel->ata_cmd; ! 484: unsigned char *buffer; ! 485: unsigned int bytes; ! 486: ! 487: if (ob_ide_select_drive(drive)) ! 488: return 1; ! 489: ! 490: if (cmd->buflen && cmd->data_direction == atapi_ddir_none) ! 491: IDE_DPRINTF("non-zero buflen but no data direction\n"); ! 492: ! 493: memset(acmd, 0, sizeof(*acmd)); ! 494: acmd->lcyl = cmd->buflen & 0xff; ! 495: acmd->hcyl = (cmd->buflen >> 8) & 0xff; ! 496: acmd->command = WIN_PACKET; ! 497: ob_ide_write_registers(drive, acmd); ! 498: ! 499: /* ! 500: * BUSY must be set, _or_ DRQ | ERR ! 501: */ ! 502: stat = ob_ide_pio_readb(drive, IDEREG_ASTATUS); ! 503: if ((stat & BUSY_STAT) == 0) { ! 504: if (!(stat & (DRQ_STAT | ERR_STAT))) { ! 505: ob_ide_error(drive, stat, "bad stat in atapi cmd"); ! 506: cmd->stat = stat; ! 507: return 1; ! 508: } ! 509: } ! 510: ! 511: if (ob_ide_wait_stat(drive, 0, BUSY_STAT | ERR_STAT, &stat)) { ! 512: ob_ide_error(drive, stat, "timeout, ATAPI BUSY clear"); ! 513: cmd->stat = stat; ! 514: return 1; ! 515: } ! 516: ! 517: if ((stat & (BUSY_STAT | DRQ_STAT | ERR_STAT)) != DRQ_STAT) { ! 518: /* ! 519: * if command isn't request sense, then we have a problem. if ! 520: * we are doing a sense, ERR_STAT == CHECK_CONDITION ! 521: */ ! 522: if (cmd->cdb[0] != ATAPI_REQ_SENSE) { ! 523: IDE_DPRINTF("odd, drive didn't want to transfer %x\n", ! 524: stat); ! 525: return 1; ! 526: } ! 527: } ! 528: ! 529: /* ! 530: * transfer cdb ! 531: */ ! 532: ob_ide_pio_outsw(drive, IDEREG_DATA, cmd->cdb,sizeof(cmd->cdb)); ! 533: ob_ide_400ns_delay(drive); ! 534: ! 535: /* ! 536: * ok, cdb was sent to drive, now do data transfer (if any) ! 537: */ ! 538: bytes = cmd->buflen; ! 539: buffer = cmd->buffer; ! 540: do { ! 541: unsigned int bc; ! 542: ! 543: if (ob_ide_wait_stat(drive, 0, BUSY_STAT | ERR_STAT, &stat)) { ! 544: ob_ide_error(drive, stat, "busy not clear after cdb"); ! 545: cmd->stat = stat; ! 546: break; ! 547: } ! 548: ! 549: /* ! 550: * transfer complete! ! 551: */ ! 552: if ((stat & (BUSY_STAT | DRQ_STAT)) == 0) ! 553: break; ! 554: ! 555: if ((stat & (BUSY_STAT | DRQ_STAT)) != DRQ_STAT) ! 556: break; ! 557: ! 558: reason = ob_ide_pio_readb(drive, IDEREG_NSECTOR); ! 559: lcyl = ob_ide_pio_readb(drive, IDEREG_LCYL); ! 560: hcyl = ob_ide_pio_readb(drive, IDEREG_HCYL); ! 561: ! 562: /* ! 563: * check if the drive wants to transfer data in the same ! 564: * direction as we do... ! 565: */ ! 566: if ((reason & IREASON_CD) && cmd->data_direction != atapi_ddir_read) { ! 567: ob_ide_error(drive, stat, "atapi, bad transfer ddir"); ! 568: break; ! 569: } ! 570: ! 571: bc = (hcyl << 8) | lcyl; ! 572: if (!bc) ! 573: break; ! 574: ! 575: if (bc > bytes) ! 576: bc = bytes; ! 577: ! 578: if (cmd->data_direction == atapi_ddir_read) ! 579: ob_ide_pio_insw(drive, IDEREG_DATA, buffer, bc); ! 580: else ! 581: ob_ide_pio_outsw(drive, IDEREG_DATA, buffer, bc); ! 582: ! 583: bytes -= bc; ! 584: buffer += bc; ! 585: ! 586: ob_ide_400ns_delay(drive); ! 587: } while (bytes); ! 588: ! 589: if (cmd->data_direction != atapi_ddir_none) ! 590: (void) ob_ide_wait_stat(drive, 0, BUSY_STAT, &stat); ! 591: ! 592: if (bytes) ! 593: IDE_DPRINTF("cdb failed, bytes=%d, stat=%x\n", bytes, stat); ! 594: ! 595: return (stat & ERR_STAT) || bytes; ! 596: } ! 597: ! 598: /* ! 599: * execute a packet command, with retries if appropriate ! 600: */ ! 601: static int ! 602: ob_ide_atapi_packet(struct ide_drive *drive, struct atapi_command *cmd) ! 603: { ! 604: int retries = 5, ret; ! 605: ! 606: if (drive->type != ide_type_atapi) ! 607: return 1; ! 608: if (cmd->buflen > 0xffff) ! 609: return 1; ! 610: ! 611: /* ! 612: * retry loop ! 613: */ ! 614: do { ! 615: ret = ob_ide_pio_packet(drive, cmd); ! 616: if (!ret) ! 617: break; ! 618: ! 619: /* ! 620: * request sense failed, bummer ! 621: */ ! 622: if (cmd->cdb[0] == ATAPI_REQ_SENSE) ! 623: break; ! 624: ! 625: if (ob_ide_atapi_request_sense(drive)) ! 626: break; ! 627: ! 628: /* ! 629: * we know sense is valid. retry if the drive isn't ready, ! 630: * otherwise don't bother. ! 631: */ ! 632: if (cmd->sense.sense_key != ATAPI_SENSE_NOT_READY) ! 633: break; ! 634: /* ! 635: * ... except 'medium not present' ! 636: */ ! 637: if (cmd->sense.asc == 0x3a) ! 638: break; ! 639: ! 640: udelay(1000000); ! 641: } while (retries--); ! 642: ! 643: if (ret) ! 644: ob_ide_error(drive, 0, "atapi command"); ! 645: ! 646: return ret; ! 647: } ! 648: ! 649: static int ! 650: ob_ide_atapi_request_sense(struct ide_drive *drive) ! 651: { ! 652: struct atapi_command *cmd = &drive->channel->atapi_cmd; ! 653: unsigned char old_cdb; ! 654: ! 655: /* ! 656: * save old cdb for debug error ! 657: */ ! 658: old_cdb = cmd->cdb[0]; ! 659: ! 660: memset(cmd, 0, sizeof(*cmd)); ! 661: cmd->cdb[0] = ATAPI_REQ_SENSE; ! 662: cmd->cdb[4] = 18; ! 663: cmd->buffer = (unsigned char *) &cmd->sense; ! 664: cmd->buflen = 18; ! 665: cmd->data_direction = atapi_ddir_read; ! 666: cmd->old_cdb = old_cdb; ! 667: ! 668: if (ob_ide_atapi_packet(drive, cmd)) ! 669: return 1; ! 670: ! 671: cmd->sense_valid = 1; ! 672: return 0; ! 673: } ! 674: ! 675: /* ! 676: * make sure drive is ready and media loaded ! 677: */ ! 678: static int ! 679: ob_ide_atapi_drive_ready(struct ide_drive *drive) ! 680: { ! 681: struct atapi_command *cmd = &drive->channel->atapi_cmd; ! 682: struct atapi_capacity cap; ! 683: ! 684: IDE_DPRINTF("ob_ide_atapi_drive_ready\n"); ! 685: ! 686: /* ! 687: * Test Unit Ready is like a ping ! 688: */ ! 689: memset(cmd, 0, sizeof(*cmd)); ! 690: cmd->cdb[0] = ATAPI_TUR; ! 691: ! 692: if (ob_ide_atapi_packet(drive, cmd)) { ! 693: IDE_DPRINTF("%d: TUR failed\n", drive->nr); ! 694: return 1; ! 695: } ! 696: ! 697: /* ! 698: * don't force load of tray (bit 2 in byte 4 of cdb), it's ! 699: * annoying and we don't want to deal with errors from drives ! 700: * that cannot do it ! 701: */ ! 702: memset(cmd, 0, sizeof(*cmd)); ! 703: cmd->cdb[0] = ATAPI_START_STOP_UNIT; ! 704: cmd->cdb[4] = 0x01; ! 705: ! 706: if (ob_ide_atapi_packet(drive, cmd)) { ! 707: IDE_DPRINTF("%d: START_STOP unit failed\n", drive->nr); ! 708: return 1; ! 709: } ! 710: ! 711: /* ! 712: * finally, get capacity and block size ! 713: */ ! 714: memset(cmd, 0, sizeof(*cmd)); ! 715: memset(&cap, 0, sizeof(cap)); ! 716: ! 717: cmd->cdb[0] = ATAPI_READ_CAPACITY; ! 718: cmd->buffer = (unsigned char *) ∩ ! 719: cmd->buflen = sizeof(cap); ! 720: cmd->data_direction = atapi_ddir_read; ! 721: ! 722: if (ob_ide_atapi_packet(drive, cmd)) { ! 723: drive->sectors = 0x1fffff; ! 724: drive->bs = 2048; ! 725: return 1; ! 726: } ! 727: ! 728: drive->sectors = __be32_to_cpu(cap.lba) + 1; ! 729: drive->bs = __be32_to_cpu(cap.block_size); ! 730: return 0; ! 731: } ! 732: ! 733: /* ! 734: * read from an atapi device, using READ_10 ! 735: */ ! 736: static int ! 737: ob_ide_read_atapi(struct ide_drive *drive, unsigned long long block, ! 738: unsigned char *buf, unsigned int sectors) ! 739: { ! 740: struct atapi_command *cmd = &drive->channel->atapi_cmd; ! 741: ! 742: if (ob_ide_atapi_drive_ready(drive)) ! 743: return 1; ! 744: ! 745: memset(cmd, 0, sizeof(*cmd)); ! 746: ! 747: /* ! 748: * READ_10 should work on generally any atapi device ! 749: */ ! 750: cmd->cdb[0] = ATAPI_READ_10; ! 751: cmd->cdb[2] = (block >> 24) & 0xff; ! 752: cmd->cdb[3] = (block >> 16) & 0xff; ! 753: cmd->cdb[4] = (block >> 8) & 0xff; ! 754: cmd->cdb[5] = block & 0xff; ! 755: cmd->cdb[7] = (sectors >> 8) & 0xff; ! 756: cmd->cdb[8] = sectors & 0xff; ! 757: ! 758: cmd->buffer = buf; ! 759: cmd->buflen = sectors * 2048; ! 760: cmd->data_direction = atapi_ddir_read; ! 761: ! 762: return ob_ide_atapi_packet(drive, cmd); ! 763: } ! 764: ! 765: static int ! 766: ob_ide_read_ata_chs(struct ide_drive *drive, unsigned long long block, ! 767: unsigned char *buf, unsigned int sectors) ! 768: { ! 769: struct ata_command *cmd = &drive->channel->ata_cmd; ! 770: unsigned int track = (block / drive->sect); ! 771: unsigned int sect = (block % drive->sect) + 1; ! 772: unsigned int head = (track % drive->head); ! 773: unsigned int cyl = (track / drive->head); ! 774: ! 775: /* ! 776: * fill in chs command to read from disk at given location ! 777: */ ! 778: cmd->buffer = buf; ! 779: cmd->buflen = sectors * 512; ! 780: ! 781: cmd->nsector = sectors & 0xff; ! 782: cmd->sector = sect; ! 783: cmd->lcyl = cyl; ! 784: cmd->hcyl = cyl >> 8; ! 785: cmd->device_head = head; ! 786: ! 787: cmd->command = WIN_READ; ! 788: ! 789: return ob_ide_pio_data_in(drive, cmd); ! 790: } ! 791: ! 792: static int ! 793: ob_ide_read_ata_lba28(struct ide_drive *drive, unsigned long long block, ! 794: unsigned char *buf, unsigned int sectors) ! 795: { ! 796: struct ata_command *cmd = &drive->channel->ata_cmd; ! 797: ! 798: memset(cmd, 0, sizeof(*cmd)); ! 799: ! 800: /* ! 801: * fill in 28-bit lba command to read from disk at given location ! 802: */ ! 803: cmd->buffer = buf; ! 804: cmd->buflen = sectors * 512; ! 805: ! 806: cmd->nsector = sectors; ! 807: cmd->sector = block; ! 808: cmd->lcyl = block >>= 8; ! 809: cmd->hcyl = block >>= 8; ! 810: cmd->device_head = ((block >> 8) & 0x0f); ! 811: cmd->device_head |= (1 << 6); ! 812: ! 813: cmd->command = WIN_READ; ! 814: ! 815: return ob_ide_pio_data_in(drive, cmd); ! 816: } ! 817: ! 818: static int ! 819: ob_ide_read_ata_lba48(struct ide_drive *drive, unsigned long long block, ! 820: unsigned char *buf, unsigned int sectors) ! 821: { ! 822: struct ata_command *cmd = &drive->channel->ata_cmd; ! 823: ! 824: memset(cmd, 0, sizeof(*cmd)); ! 825: ! 826: cmd->buffer = buf; ! 827: cmd->buflen = sectors * 512; ! 828: ! 829: /* ! 830: * we are using tasklet addressing here ! 831: */ ! 832: cmd->task[2] = sectors; ! 833: cmd->task[3] = sectors >> 8; ! 834: cmd->task[4] = block; ! 835: cmd->task[5] = block >> 8; ! 836: cmd->task[6] = block >> 16; ! 837: cmd->task[7] = block >> 24; ! 838: cmd->task[8] = (u64) block >> 32; ! 839: cmd->task[9] = (u64) block >> 40; ! 840: ! 841: cmd->command = WIN_READ_EXT; ! 842: ! 843: ob_ide_write_tasklet(drive, cmd); ! 844: ! 845: return ob_ide_pio_data_in(drive, cmd); ! 846: } ! 847: /* ! 848: * read 'sectors' sectors from ata device ! 849: */ ! 850: static int ! 851: ob_ide_read_ata(struct ide_drive *drive, unsigned long long block, ! 852: unsigned char *buf, unsigned int sectors) ! 853: { ! 854: unsigned long long end_block = block + sectors; ! 855: const int need_lba48 = (end_block > (1ULL << 28)) || (sectors > 255); ! 856: ! 857: if (end_block > drive->sectors) ! 858: return 1; ! 859: if (need_lba48 && drive->addressing != ide_lba48) ! 860: return 1; ! 861: ! 862: /* ! 863: * use lba48 if we have to, otherwise use the faster lba28 ! 864: */ ! 865: if (need_lba48) ! 866: return ob_ide_read_ata_lba48(drive, block, buf, sectors); ! 867: else if (drive->addressing != ide_chs) ! 868: return ob_ide_read_ata_lba28(drive, block, buf, sectors); ! 869: ! 870: return ob_ide_read_ata_chs(drive, block, buf, sectors); ! 871: } ! 872: ! 873: static int ! 874: ob_ide_read_sectors(struct ide_drive *drive, unsigned long long block, ! 875: unsigned char *buf, unsigned int sectors) ! 876: { ! 877: if (!sectors) ! 878: return 1; ! 879: if (block + sectors > drive->sectors) ! 880: return 1; ! 881: ! 882: IDE_DPRINTF("ob_ide_read_sectors: block=%lu sectors=%u\n", ! 883: (unsigned long) block, sectors); ! 884: ! 885: if (drive->type == ide_type_ata) ! 886: return ob_ide_read_ata(drive, block, buf, sectors); ! 887: else ! 888: return ob_ide_read_atapi(drive, block, buf, sectors); ! 889: } ! 890: ! 891: /* ! 892: * byte swap the string if necessay, and strip leading/trailing blanks ! 893: */ ! 894: static void ! 895: ob_ide_fixup_string(unsigned char *s, unsigned int len) ! 896: { ! 897: unsigned char *p = s, *end = &s[len & ~1]; ! 898: ! 899: /* ! 900: * if big endian arch, byte swap the string ! 901: */ ! 902: #ifdef CONFIG_BIG_ENDIAN ! 903: for (p = end ; p != s;) { ! 904: unsigned short *pp = (unsigned short *) (p -= 2); ! 905: *pp = __le16_to_cpu(*pp); ! 906: } ! 907: #endif ! 908: ! 909: while (s != end && *s == ' ') ! 910: ++s; ! 911: while (s != end && *s) ! 912: if (*s++ != ' ' || (s != end && *s && *s != ' ')) ! 913: *p++ = *(s-1); ! 914: while (p != end) ! 915: *p++ = '\0'; ! 916: } ! 917: ! 918: /* ! 919: * it's big endian, we need to swap (if on little endian) the items we use ! 920: */ ! 921: static int ! 922: ob_ide_fixup_id(struct hd_driveid *id) ! 923: { ! 924: ob_ide_fixup_string(id->model, 40); ! 925: id->config = __le16_to_cpu(id->config); ! 926: id->lba_capacity = __le32_to_cpu(id->lba_capacity); ! 927: id->cyls = __le16_to_cpu(id->cyls); ! 928: id->heads = __le16_to_cpu(id->heads); ! 929: id->sectors = __le16_to_cpu(id->sectors); ! 930: id->command_set_2 = __le16_to_cpu(id->command_set_2); ! 931: id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2); ! 932: ! 933: return 0; ! 934: } ! 935: ! 936: static int ! 937: ob_ide_identify_drive(struct ide_drive *drive) ! 938: { ! 939: struct ata_command *cmd = &drive->channel->ata_cmd; ! 940: struct hd_driveid id; ! 941: ! 942: memset(cmd, 0, sizeof(*cmd)); ! 943: cmd->buffer = (unsigned char *) &id; ! 944: cmd->buflen = 512; ! 945: ! 946: if (drive->type == ide_type_ata) ! 947: cmd->command = WIN_IDENTIFY; ! 948: else if (drive->type == ide_type_atapi) ! 949: cmd->command = WIN_IDENTIFY_PACKET; ! 950: else { ! 951: IDE_DPRINTF("%s: called with bad device type %d\n", ! 952: __FUNCTION__, drive->type); ! 953: return 1; ! 954: } ! 955: ! 956: if (ob_ide_pio_data_in(drive, cmd)) ! 957: return 1; ! 958: ! 959: ob_ide_fixup_id(&id); ! 960: ! 961: if (drive->type == ide_type_atapi) { ! 962: drive->media = (id.config >> 8) & 0x1f; ! 963: drive->sectors = 0x7fffffff; ! 964: drive->bs = 2048; ! 965: drive->max_sectors = 31; ! 966: } else { ! 967: drive->media = ide_media_disk; ! 968: drive->sectors = id.lba_capacity; ! 969: drive->bs = 512; ! 970: drive->max_sectors = 255; ! 971: ! 972: #ifdef CONFIG_IDE_LBA48 ! 973: if ((id.command_set_2 & 0x0400) && (id.cfs_enable_2 & 0x0400)) { ! 974: drive->addressing = ide_lba48; ! 975: drive->max_sectors = 65535; ! 976: } else ! 977: #endif ! 978: if (id.capability & 2) ! 979: drive->addressing = ide_lba28; ! 980: else { ! 981: drive->addressing = ide_chs; ! 982: } ! 983: ! 984: /* only set these in chs mode? */ ! 985: drive->cyl = id.cyls; ! 986: drive->head = id.heads; ! 987: drive->sect = id.sectors; ! 988: } ! 989: ! 990: strncpy(drive->model, (char*)id.model, sizeof(id.model)); ! 991: drive->model[40] = '\0'; ! 992: return 0; ! 993: } ! 994: ! 995: /* ! 996: * identify type of devices on channel. must have already been probed. ! 997: */ ! 998: static void ! 999: ob_ide_identify_drives(struct ide_channel *chan) ! 1000: { ! 1001: struct ide_drive *drive; ! 1002: int i; ! 1003: ! 1004: for (i = 0; i < 2; i++) { ! 1005: drive = &chan->drives[i]; ! 1006: ! 1007: if (!drive->present) ! 1008: continue; ! 1009: ! 1010: ob_ide_identify_drive(drive); ! 1011: } ! 1012: } ! 1013: ! 1014: /* ! 1015: * software reset (ATA-4, section 8.3) ! 1016: */ ! 1017: static void ! 1018: ob_ide_software_reset(struct ide_drive *drive) ! 1019: { ! 1020: struct ide_channel *chan = drive->channel; ! 1021: ! 1022: ob_ide_pio_writeb(drive, IDEREG_CONTROL, IDECON_NIEN | IDECON_SRST); ! 1023: ob_ide_400ns_delay(drive); ! 1024: ob_ide_pio_writeb(drive, IDEREG_CONTROL, IDECON_NIEN); ! 1025: ob_ide_400ns_delay(drive); ! 1026: ! 1027: /* ! 1028: * if master is present, wait for BUSY clear ! 1029: */ ! 1030: if (chan->drives[0].present) ! 1031: ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL); ! 1032: ! 1033: /* ! 1034: * if slave is present, wait until it allows register access ! 1035: */ ! 1036: if (chan->drives[1].present) { ! 1037: unsigned char sectorn, sectorc; ! 1038: int timeout = 1000; ! 1039: ! 1040: do { ! 1041: /* ! 1042: * select it ! 1043: */ ! 1044: ob_ide_pio_writeb(drive, IDEREG_CURRENT, IDEHEAD_DEV1); ! 1045: ob_ide_400ns_delay(drive); ! 1046: ! 1047: sectorn = ob_ide_pio_readb(drive, IDEREG_SECTOR); ! 1048: sectorc = ob_ide_pio_readb(drive, IDEREG_NSECTOR); ! 1049: ! 1050: if (sectorc == 0x01 && sectorn == 0x01) ! 1051: break; ! 1052: ! 1053: } while (--timeout); ! 1054: } ! 1055: ! 1056: /* ! 1057: * reset done, reselect original device ! 1058: */ ! 1059: drive->channel->selected = -1; ! 1060: ob_ide_select_drive(drive); ! 1061: } ! 1062: ! 1063: /* ! 1064: * this serves as both a device check, and also to verify that the drives ! 1065: * we initially "found" are really there ! 1066: */ ! 1067: static void ! 1068: ob_ide_device_type_check(struct ide_drive *drive) ! 1069: { ! 1070: unsigned char sc, sn, cl, ch, st; ! 1071: ! 1072: if (ob_ide_select_drive(drive)) ! 1073: return; ! 1074: ! 1075: sc = ob_ide_pio_readb(drive, IDEREG_NSECTOR); ! 1076: sn = ob_ide_pio_readb(drive, IDEREG_SECTOR); ! 1077: ! 1078: if (sc == 0x01 && sn == 0x01) { ! 1079: /* ! 1080: * read device signature ! 1081: */ ! 1082: cl = ob_ide_pio_readb(drive, IDEREG_LCYL); ! 1083: ch = ob_ide_pio_readb(drive, IDEREG_HCYL); ! 1084: st = ob_ide_pio_readb(drive, IDEREG_STATUS); ! 1085: if (cl == 0x14 && ch == 0xeb) ! 1086: drive->type = ide_type_atapi; ! 1087: else if (cl == 0x00 && ch == 0x00 && st != 0x00) ! 1088: drive->type = ide_type_ata; ! 1089: else ! 1090: drive->present = 0; ! 1091: } else ! 1092: drive->present = 0; ! 1093: } ! 1094: ! 1095: /* ! 1096: * pure magic ! 1097: */ ! 1098: static void ! 1099: ob_ide_device_check(struct ide_drive *drive) ! 1100: { ! 1101: unsigned char sc, sn; ! 1102: ! 1103: /* ! 1104: * non-existing io port should return 0xff, don't probe this ! 1105: * channel at all then ! 1106: */ ! 1107: if (ob_ide_pio_readb(drive, IDEREG_STATUS) == 0xff) { ! 1108: drive->channel->present = 0; ! 1109: return; ! 1110: } ! 1111: ! 1112: if (ob_ide_select_drive(drive)) ! 1113: return; ! 1114: ! 1115: ob_ide_pio_writeb(drive, IDEREG_NSECTOR, 0x55); ! 1116: ob_ide_pio_writeb(drive, IDEREG_SECTOR, 0xaa); ! 1117: ob_ide_pio_writeb(drive, IDEREG_NSECTOR, 0xaa); ! 1118: ob_ide_pio_writeb(drive, IDEREG_SECTOR, 0x55); ! 1119: ob_ide_pio_writeb(drive, IDEREG_NSECTOR, 0x55); ! 1120: ob_ide_pio_writeb(drive, IDEREG_SECTOR, 0xaa); ! 1121: ! 1122: sc = ob_ide_pio_readb(drive, IDEREG_NSECTOR); ! 1123: sn = ob_ide_pio_readb(drive, IDEREG_SECTOR); ! 1124: ! 1125: /* ! 1126: * we _think_ the device is there, we will make sure later ! 1127: */ ! 1128: if (sc == 0x55 && sn == 0xaa) { ! 1129: drive->present = 1; ! 1130: drive->type = ide_type_unknown; ! 1131: } ! 1132: } ! 1133: ! 1134: /* ! 1135: * probe the legacy ide ports and find attached devices. ! 1136: */ ! 1137: static void ! 1138: ob_ide_probe(struct ide_channel *chan) ! 1139: { ! 1140: struct ide_drive *drive; ! 1141: int i; ! 1142: ! 1143: for (i = 0; i < 2; i++) { ! 1144: drive = &chan->drives[i]; ! 1145: ! 1146: ob_ide_device_check(drive); ! 1147: ! 1148: /* ! 1149: * no point in continuing ! 1150: */ ! 1151: if (!chan->present) ! 1152: break; ! 1153: ! 1154: if (!drive->present) ! 1155: continue; ! 1156: ! 1157: /* ! 1158: * select and reset device ! 1159: */ ! 1160: if (ob_ide_select_drive(drive)) ! 1161: continue; ! 1162: ! 1163: ob_ide_software_reset(drive); ! 1164: ! 1165: ob_ide_device_type_check(drive); ! 1166: } ! 1167: } ! 1168: ! 1169: /* ! 1170: * The following functions are interfacing with OpenBIOS. They ! 1171: * are device node methods. Thus they have to do proper stack handling. ! 1172: * ! 1173: */ ! 1174: ! 1175: /* ! 1176: * 255 sectors for ata lba28, 65535 for lba48, and 31 sectors for atapi ! 1177: */ ! 1178: static void ! 1179: ob_ide_max_transfer(int *idx) ! 1180: { ! 1181: struct ide_drive *drive = *(struct ide_drive **)idx; ! 1182: ! 1183: IDE_DPRINTF("max_transfer %x\n", drive->max_sectors * drive->bs); ! 1184: ! 1185: PUSH(drive->max_sectors * drive->bs); ! 1186: } ! 1187: ! 1188: static void ! 1189: ob_ide_read_blocks(int *idx) ! 1190: { ! 1191: cell n = POP(), cnt=n; ! 1192: ucell blk = POP(); ! 1193: unsigned char *dest = (unsigned char *)cell2pointer(POP()); ! 1194: struct ide_drive *drive = *(struct ide_drive **)idx; ! 1195: ! 1196: IDE_DPRINTF("ob_ide_read_blocks %lx block=%ld n=%ld\n", ! 1197: (unsigned long)dest, (unsigned long)blk, (long)n); ! 1198: ! 1199: while (n) { ! 1200: int len = n; ! 1201: if (len > drive->max_sectors) ! 1202: len = drive->max_sectors; ! 1203: ! 1204: if (ob_ide_read_sectors(drive, blk, dest, len)) { ! 1205: IDE_DPRINTF("ob_ide_read_blocks: error\n"); ! 1206: RET(0); ! 1207: } ! 1208: ! 1209: dest += len * drive->bs; ! 1210: n -= len; ! 1211: blk += len; ! 1212: } ! 1213: ! 1214: PUSH(cnt); ! 1215: } ! 1216: ! 1217: static void ! 1218: ob_ide_block_size(int *idx) ! 1219: { ! 1220: struct ide_drive *drive = *(struct ide_drive **)idx; ! 1221: ! 1222: IDE_DPRINTF("ob_ide_block_size: block size %x\n", drive->bs); ! 1223: ! 1224: PUSH(drive->bs); ! 1225: } ! 1226: ! 1227: static void ! 1228: ob_ide_initialize(int *idx) ! 1229: { ! 1230: int props[3]; ! 1231: phandle_t ph=get_cur_dev(); ! 1232: ! 1233: push_str("block"); ! 1234: fword("device-type"); ! 1235: ! 1236: // Set dummy reg properties ! 1237: ! 1238: set_int_property(ph, "#address-cells", 1); ! 1239: set_int_property(ph, "#size-cells", 0); ! 1240: ! 1241: props[0] = __cpu_to_be32(0); props[1] = __cpu_to_be32(0); props[2] = __cpu_to_be32(0); ! 1242: set_property(ph, "reg", (char *)&props, 3*sizeof(int)); ! 1243: ! 1244: fword("is-deblocker"); ! 1245: } ! 1246: ! 1247: static void ! 1248: ob_ide_open(int *idx) ! 1249: { ! 1250: int ret=1, len; ! 1251: phandle_t ph; ! 1252: struct ide_drive *drive; ! 1253: struct ide_channel *chan; ! 1254: char *idename; ! 1255: int unit; ! 1256: ! 1257: fword("my-unit"); ! 1258: unit = POP(); ! 1259: ! 1260: fword("my-parent"); ! 1261: fword("ihandle>phandle"); ! 1262: ph=(phandle_t)POP(); ! 1263: idename=get_property(ph, "name", &len); ! 1264: ! 1265: chan = ide_seek_channel(idename); ! 1266: drive = &chan->drives[unit]; ! 1267: *(struct ide_drive **)idx = drive; ! 1268: ! 1269: IDE_DPRINTF("opening channel %d unit %d\n", idx[1], idx[0]); ! 1270: dump_drive(drive); ! 1271: ! 1272: if (drive->type != ide_type_ata) ! 1273: ret= !ob_ide_atapi_drive_ready(drive); ! 1274: ! 1275: selfword("open-deblocker"); ! 1276: ! 1277: /* interpose disk-label */ ! 1278: ph = find_dev("/packages/disk-label"); ! 1279: fword("my-args"); ! 1280: PUSH_ph( ph ); ! 1281: fword("interpose"); ! 1282: ! 1283: RET ( -ret ); ! 1284: } ! 1285: ! 1286: static void ! 1287: ob_ide_close(struct ide_drive *drive) ! 1288: { ! 1289: selfword("close-deblocker"); ! 1290: } ! 1291: ! 1292: NODE_METHODS(ob_ide) = { ! 1293: { NULL, ob_ide_initialize }, ! 1294: { "open", ob_ide_open }, ! 1295: { "close", ob_ide_close }, ! 1296: { "read-blocks", ob_ide_read_blocks }, ! 1297: { "block-size", ob_ide_block_size }, ! 1298: { "max-transfer", ob_ide_max_transfer }, ! 1299: }; ! 1300: ! 1301: static void ! 1302: ob_ide_ctrl_initialize(int *idx) ! 1303: { ! 1304: phandle_t ph=get_cur_dev(); ! 1305: ! 1306: /* set device type */ ! 1307: push_str(DEV_TYPE); ! 1308: fword("device-type"); ! 1309: ! 1310: set_int_property(ph, "#address-cells", 1); ! 1311: set_int_property(ph, "#size-cells", 0); ! 1312: } ! 1313: ! 1314: static void ! 1315: ob_ide_ctrl_decodeunit(int *idx) ! 1316: { ! 1317: fword("parse-hex"); ! 1318: } ! 1319: ! 1320: NODE_METHODS(ob_ide_ctrl) = { ! 1321: { NULL, ob_ide_ctrl_initialize }, ! 1322: { "decode-unit", ob_ide_ctrl_decodeunit }, ! 1323: }; ! 1324: ! 1325: static void set_cd_alias(const char *path) ! 1326: { ! 1327: phandle_t aliases; ! 1328: ! 1329: aliases = find_dev("/aliases"); ! 1330: ! 1331: if (get_property(aliases, "cd", NULL)) ! 1332: return; ! 1333: ! 1334: set_property(aliases, "cd", path, strlen(path) + 1); ! 1335: set_property(aliases, "cdrom", path, strlen(path) + 1); ! 1336: } ! 1337: ! 1338: static void set_hd_alias(const char *path) ! 1339: { ! 1340: phandle_t aliases; ! 1341: ! 1342: aliases = find_dev("/aliases"); ! 1343: ! 1344: if (get_property(aliases, "hd", NULL)) ! 1345: return; ! 1346: ! 1347: set_property(aliases, "hd", path, strlen(path) + 1); ! 1348: set_property(aliases, "disk", path, strlen(path) + 1); ! 1349: } ! 1350: ! 1351: static void set_ide_alias(const char *path) ! 1352: { ! 1353: phandle_t aliases; ! 1354: static int ide_counter = 0; ! 1355: char idestr[8]; ! 1356: ! 1357: aliases = find_dev("/aliases"); ! 1358: ! 1359: snprintf(idestr, sizeof(idestr), "ide%d", ide_counter++); ! 1360: set_property(aliases, idestr, path, strlen(path) + 1); ! 1361: } ! 1362: ! 1363: int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0, ! 1364: uint32_t io_port1, uint32_t ctl_port1) ! 1365: { ! 1366: int i, j; ! 1367: char nodebuff[128]; ! 1368: phandle_t dnode; ! 1369: struct ide_channel *chan; ! 1370: int io_ports[IDE_MAX_CHANNELS]; ! 1371: int ctl_ports[IDE_MAX_CHANNELS]; ! 1372: u32 props[6]; ! 1373: ! 1374: io_ports[0] = io_port0; ! 1375: ctl_ports[0] = ctl_port0 + 2; ! 1376: io_ports[1] = io_port1; ! 1377: ctl_ports[1] = ctl_port1 + 2; ! 1378: ! 1379: for (i = 0; i < IDE_NUM_CHANNELS; i++, current_channel++) { ! 1380: ! 1381: chan = malloc(sizeof(struct ide_channel)); ! 1382: ! 1383: snprintf(chan->name, sizeof(chan->name), ! 1384: DEV_NAME, current_channel); ! 1385: ! 1386: chan->mmio = 0; ! 1387: ! 1388: for (j = 0; j < 8; j++) ! 1389: chan->io_regs[j] = io_ports[i] + j; ! 1390: ! 1391: chan->io_regs[8] = ctl_ports[i]; ! 1392: chan->io_regs[9] = ctl_ports[i] + 1; ! 1393: ! 1394: chan->obide_inb = ob_ide_inb; ! 1395: chan->obide_insw = ob_ide_insw; ! 1396: chan->obide_outb = ob_ide_outb; ! 1397: chan->obide_outsw = ob_ide_outsw; ! 1398: ! 1399: chan->selected = -1; ! 1400: ! 1401: /* ! 1402: * assume it's there, if not io port dead check will clear ! 1403: */ ! 1404: chan->present = 1; ! 1405: ! 1406: for (j = 0; j < 2; j++) { ! 1407: chan->drives[j].present = 0; ! 1408: chan->drives[j].unit = j; ! 1409: chan->drives[j].channel = chan; ! 1410: /* init with a decent value */ ! 1411: chan->drives[j].bs = 512; ! 1412: ! 1413: chan->drives[j].nr = i * 2 + j; ! 1414: } ! 1415: ! 1416: ide_add_channel(chan); ! 1417: ! 1418: ob_ide_probe(chan); ! 1419: ! 1420: if (!chan->present) ! 1421: continue; ! 1422: ! 1423: ob_ide_identify_drives(chan); ! 1424: ! 1425: snprintf(nodebuff, sizeof(nodebuff), "%s/" DEV_NAME, path, ! 1426: current_channel); ! 1427: REGISTER_NAMED_NODE(ob_ide_ctrl, nodebuff); ! 1428: ! 1429: dnode = find_dev(nodebuff); ! 1430: ! 1431: #if !defined(CONFIG_PPC) && !defined(CONFIG_SPARC64) ! 1432: props[0]=14; props[1]=0; ! 1433: set_property(dnode, "interrupts", ! 1434: (char *)&props, 2*sizeof(props[0])); ! 1435: #endif ! 1436: ! 1437: props[0] = __cpu_to_be32(chan->io_regs[0]); ! 1438: props[1] = __cpu_to_be32(1); props[2] = __cpu_to_be32(8); ! 1439: props[3] = __cpu_to_be32(chan->io_regs[8]); ! 1440: props[4] = __cpu_to_be32(1); props[5] = __cpu_to_be32(2); ! 1441: set_property(dnode, "reg", (char *)&props, 6*sizeof(props[0])); ! 1442: ! 1443: IDE_DPRINTF(DEV_NAME": [io ports 0x%x-0x%x,0x%x]\n", ! 1444: current_channel, chan->io_regs[0], ! 1445: chan->io_regs[0] + 7, chan->io_regs[8]); ! 1446: ! 1447: for (j = 0; j < 2; j++) { ! 1448: struct ide_drive *drive = &chan->drives[j]; ! 1449: const char *media = "UNKNOWN"; ! 1450: ! 1451: if (!drive->present) ! 1452: continue; ! 1453: ! 1454: IDE_DPRINTF(" drive%d [ATA%s ", j, ! 1455: drive->type == ide_type_atapi ? "PI" : ""); ! 1456: switch (drive->media) { ! 1457: case ide_media_floppy: ! 1458: media = "floppy"; ! 1459: break; ! 1460: case ide_media_cdrom: ! 1461: media = "cdrom"; ! 1462: break; ! 1463: case ide_media_optical: ! 1464: media = "mo"; ! 1465: break; ! 1466: case ide_media_disk: ! 1467: media = "disk"; ! 1468: break; ! 1469: } ! 1470: IDE_DPRINTF("%s]: %s\n", media, drive->model); ! 1471: snprintf(nodebuff, sizeof(nodebuff), ! 1472: "%s/" DEV_NAME "/%s", path, current_channel, ! 1473: media); ! 1474: REGISTER_NAMED_NODE(ob_ide, nodebuff); ! 1475: dnode=find_dev(nodebuff); ! 1476: set_int_property(dnode, "reg", j); ! 1477: ! 1478: /* create aliases */ ! 1479: ! 1480: set_ide_alias(nodebuff); ! 1481: if (drive->media == ide_media_cdrom) ! 1482: set_cd_alias(nodebuff); ! 1483: if (drive->media == ide_media_disk) ! 1484: set_hd_alias(nodebuff); ! 1485: } ! 1486: } ! 1487: ! 1488: return 0; ! 1489: } ! 1490: ! 1491: #if defined(CONFIG_DRIVER_MACIO) ! 1492: static unsigned char ! 1493: macio_ide_inb(struct ide_channel *chan, unsigned int port) ! 1494: { ! 1495: return in_8((unsigned char*)(chan->mmio + (port << 4))); ! 1496: } ! 1497: ! 1498: static void ! 1499: macio_ide_outb(struct ide_channel *chan, unsigned char data, unsigned int port) ! 1500: { ! 1501: out_8((unsigned char*)(chan->mmio + (port << 4)), data); ! 1502: } ! 1503: ! 1504: static void ! 1505: macio_ide_insw(struct ide_channel *chan, ! 1506: unsigned int port, unsigned char *addr, unsigned int count) ! 1507: { ! 1508: _insw((uint16_t*)(chan->mmio + (port << 4)), addr, count); ! 1509: } ! 1510: ! 1511: static void ! 1512: macio_ide_outsw(struct ide_channel *chan, ! 1513: unsigned int port, unsigned char *addr, unsigned int count) ! 1514: { ! 1515: _outsw((uint16_t*)(chan->mmio + (port << 4)), addr, count); ! 1516: } ! 1517: ! 1518: #define MACIO_IDE_OFFSET 0x00020000 ! 1519: #define MACIO_IDE_SIZE 0x00001000 ! 1520: ! 1521: int macio_ide_init(const char *path, uint32_t addr, int nb_channels) ! 1522: { ! 1523: int i, j; ! 1524: char nodebuff[128]; ! 1525: phandle_t dnode; ! 1526: u32 props[8]; ! 1527: struct ide_channel *chan; ! 1528: ! 1529: for (i = 0; i < nb_channels; i++, current_channel++) { ! 1530: ! 1531: chan = malloc(sizeof(struct ide_channel)); ! 1532: ! 1533: snprintf(chan->name, sizeof(chan->name), ! 1534: DEV_NAME, current_channel); ! 1535: ! 1536: chan->mmio = addr + MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE; ! 1537: ! 1538: chan->obide_inb = macio_ide_inb; ! 1539: chan->obide_insw = macio_ide_insw; ! 1540: chan->obide_outb = macio_ide_outb; ! 1541: chan->obide_outsw = macio_ide_outsw; ! 1542: ! 1543: chan->selected = -1; ! 1544: ! 1545: /* ! 1546: * assume it's there, if not io port dead check will clear ! 1547: */ ! 1548: chan->present = 1; ! 1549: ! 1550: for (j = 0; j < 2; j++) { ! 1551: chan->drives[j].present = 0; ! 1552: chan->drives[j].unit = j; ! 1553: chan->drives[j].channel = chan; ! 1554: /* init with a decent value */ ! 1555: chan->drives[j].bs = 512; ! 1556: ! 1557: chan->drives[j].nr = i * 2 + j; ! 1558: } ! 1559: ! 1560: ob_ide_probe(chan); ! 1561: ! 1562: if (!chan->present) { ! 1563: free(chan); ! 1564: continue; ! 1565: } ! 1566: ! 1567: ide_add_channel(chan); ! 1568: ! 1569: ob_ide_identify_drives(chan); ! 1570: ! 1571: snprintf(nodebuff, sizeof(nodebuff), "%s/" DEV_NAME, path, ! 1572: current_channel); ! 1573: REGISTER_NAMED_NODE(ob_ide_ctrl, nodebuff); ! 1574: ! 1575: dnode = find_dev(nodebuff); ! 1576: ! 1577: set_property(dnode, "compatible", "heathrow-ata", 13); ! 1578: ! 1579: props[0] = 0x00000526; ! 1580: props[1] = 0x00000085; ! 1581: props[2] = 0x00000025; ! 1582: props[3] = 0x00000025; ! 1583: props[4] = 0x00000025; ! 1584: props[5] = 0x00000000; ! 1585: props[6] = 0x00000000; ! 1586: props[7] = 0x00000000; ! 1587: OLDWORLD(set_property(dnode, "AAPL,pio-timing", ! 1588: (char *)&props, 8*sizeof(props[0]))); ! 1589: ! 1590: /* The first interrupt entry is the ide interrupt, the second ! 1591: the dbdma interrupt */ ! 1592: switch (i) { ! 1593: case 0: ! 1594: props[0] = 0x0000000d; ! 1595: props[2] = 0x00000002; ! 1596: break; ! 1597: case 1: ! 1598: props[0] = 0x0000000e; ! 1599: props[2] = 0x00000003; ! 1600: break; ! 1601: case 2: ! 1602: props[0] = 0x0000000f; ! 1603: props[2] = 0x00000004; ! 1604: break; ! 1605: default: ! 1606: props[0] = 0x00000000; ! 1607: props[2] = 0x00000000; ! 1608: break; ! 1609: } ! 1610: props[1] = 0x00000000; /* XXX level triggered on real hw */ ! 1611: props[3] = 0x00000000; ! 1612: set_property(dnode, "interrupts", ! 1613: (char *)&props, 4*sizeof(props[0])); ! 1614: set_int_property(dnode, "#interrupt-cells", 2); ! 1615: OLDWORLD(set_property(dnode, "AAPL,interrupts", ! 1616: (char *)&props, 2*sizeof(props[0]))); ! 1617: ! 1618: props[0] = MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE; ! 1619: props[1] = MACIO_IDE_SIZE; ! 1620: props[2] = 0x00008b00 + i * 0x0200; ! 1621: props[3] = 0x0200; ! 1622: set_property(dnode, "reg", (char *)&props, 4*sizeof(props[0])); ! 1623: ! 1624: props[0] = addr + MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE; ! 1625: props[1] = addr + 0x00008b00 + i * 0x0200; ! 1626: OLDWORLD(set_property(dnode, "AAPL,address", ! 1627: (char *)&props, 2*sizeof(props[0]))); ! 1628: ! 1629: props[0] = 0; ! 1630: OLDWORLD(set_property(dnode, "AAPL,bus-id", (char*)props, ! 1631: 1 * sizeof(props[0]))); ! 1632: IDE_DPRINTF(DEV_NAME": [io ports 0x%lx]\n", ! 1633: current_channel, chan->mmio); ! 1634: ! 1635: for (j = 0; j < 2; j++) { ! 1636: struct ide_drive *drive = &chan->drives[j]; ! 1637: const char *media = "UNKNOWN"; ! 1638: ! 1639: if (!drive->present) ! 1640: continue; ! 1641: ! 1642: IDE_DPRINTF(" drive%d [ATA%s ", j, ! 1643: drive->type == ide_type_atapi ? "PI" : ""); ! 1644: switch (drive->media) { ! 1645: case ide_media_floppy: ! 1646: media = "floppy"; ! 1647: break; ! 1648: case ide_media_cdrom: ! 1649: media = "cdrom"; ! 1650: break; ! 1651: case ide_media_optical: ! 1652: media = "mo"; ! 1653: break; ! 1654: case ide_media_disk: ! 1655: media = "disk"; ! 1656: break; ! 1657: } ! 1658: IDE_DPRINTF("%s]: %s\n", media, drive->model); ! 1659: snprintf(nodebuff, sizeof(nodebuff), ! 1660: "%s/" DEV_NAME "/%s", path, current_channel, ! 1661: media); ! 1662: REGISTER_NAMED_NODE(ob_ide, nodebuff); ! 1663: dnode = find_dev(nodebuff); ! 1664: set_int_property(dnode, "reg", j); ! 1665: ! 1666: /* create aliases */ ! 1667: ! 1668: set_ide_alias(nodebuff); ! 1669: if (drive->media == ide_media_cdrom) ! 1670: set_cd_alias(nodebuff); ! 1671: if (drive->media == ide_media_disk) ! 1672: set_hd_alias(nodebuff); ! 1673: } ! 1674: } ! 1675: ! 1676: return 0; ! 1677: } ! 1678: #endif /* CONFIG_DRIVER_MACIO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.