Annotation of qemu/roms/openbios/drivers/ide.c, revision 1.1

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 *) &cap;
        !           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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.