Annotation of qemu/roms/seabios/src/ata.c, revision 1.1.1.2

1.1       root        1: // Low level ATA disk access
                      2: //
                      3: // Copyright (C) 2008,2009  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2002  MandrakeSoft S.A.
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "types.h" // u8
                      9: #include "ioport.h" // inb
                     10: #include "util.h" // dprintf
                     11: #include "cmos.h" // inb_cmos
                     12: #include "pic.h" // enable_hwirq
                     13: #include "biosvar.h" // GET_EBDA
                     14: #include "pci.h" // foreachpci
                     15: #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER
                     16: #include "pci_regs.h" // PCI_INTERRUPT_LINE
                     17: #include "boot.h" // add_bcv_hd
                     18: #include "disk.h" // struct ata_s
                     19: #include "ata.h" // ATA_CB_STAT
                     20: 
                     21: #define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
                     22: 
                     23: struct ata_channel_s ATA_channels[CONFIG_MAX_ATA_INTERFACES] VAR16VISIBLE;
                     24: 
                     25: 
                     26: /****************************************************************
                     27:  * Helper functions
                     28:  ****************************************************************/
                     29: 
                     30: // Wait for the specified ide state
                     31: static inline int
                     32: await_ide(u8 mask, u8 flags, u16 base, u16 timeout)
                     33: {
                     34:     u64 end = calc_future_tsc(timeout);
                     35:     for (;;) {
                     36:         u8 status = inb(base+ATA_CB_STAT);
                     37:         if ((status & mask) == flags)
                     38:             return status;
                     39:         if (check_time(end)) {
                     40:             dprintf(1, "IDE time out\n");
                     41:             return -1;
                     42:         }
                     43:         yield();
                     44:     }
                     45: }
                     46: 
                     47: // Wait for the device to be not-busy.
                     48: static int
                     49: await_not_bsy(u16 base)
                     50: {
                     51:     return await_ide(ATA_CB_STAT_BSY, 0, base, IDE_TIMEOUT);
                     52: }
                     53: 
                     54: // Wait for the device to be ready.
                     55: static int
                     56: await_rdy(u16 base)
                     57: {
                     58:     return await_ide(ATA_CB_STAT_RDY, ATA_CB_STAT_RDY, base, IDE_TIMEOUT);
                     59: }
                     60: 
                     61: // Wait for ide state - pauses for one ata cycle first.
                     62: static inline int
                     63: pause_await_not_bsy(u16 iobase1, u16 iobase2)
                     64: {
                     65:     // Wait one PIO transfer cycle.
                     66:     inb(iobase2 + ATA_CB_ASTAT);
                     67: 
                     68:     return await_not_bsy(iobase1);
                     69: }
                     70: 
                     71: // Wait for ide state - pause for 400ns first.
                     72: static inline int
                     73: ndelay_await_not_bsy(u16 iobase1)
                     74: {
                     75:     ndelay(400);
                     76:     return await_not_bsy(iobase1);
                     77: }
                     78: 
                     79: // Reset a drive
                     80: static void
                     81: ata_reset(struct drive_s *drive_g)
                     82: {
                     83:     u8 ataid = GET_GLOBAL(drive_g->cntl_id);
                     84:     u8 channel = ataid / 2;
                     85:     u8 slave = ataid % 2;
                     86:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
                     87:     u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
                     88: 
                     89:     dprintf(6, "ata_reset drive=%p\n", drive_g);
                     90:     // Pulse SRST
                     91:     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST, iobase2+ATA_CB_DC);
                     92:     udelay(5);
                     93:     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
                     94:     msleep(2);
                     95: 
                     96:     // wait for device to become not busy.
                     97:     int status = await_not_bsy(iobase1);
                     98:     if (status < 0)
                     99:         goto done;
                    100:     if (slave) {
                    101:         // Change device.
                    102:         u64 end = calc_future_tsc(IDE_TIMEOUT);
                    103:         for (;;) {
                    104:             outb(ATA_CB_DH_DEV1, iobase1 + ATA_CB_DH);
                    105:             status = ndelay_await_not_bsy(iobase1);
                    106:             if (status < 0)
                    107:                 goto done;
                    108:             if (inb(iobase1 + ATA_CB_DH) == ATA_CB_DH_DEV1)
                    109:                 break;
                    110:             // Change drive request failed to take effect - retry.
                    111:             if (check_time(end)) {
                    112:                 dprintf(1, "ata_reset slave time out\n");
                    113:                 goto done;
                    114:             }
                    115:         }
                    116:     } else {
                    117:         // QEMU doesn't reset dh on reset, so set it explicitly.
                    118:         outb(ATA_CB_DH_DEV0, iobase1 + ATA_CB_DH);
                    119:     }
                    120: 
                    121:     // On a user-reset request, wait for RDY if it is an ATA device.
                    122:     u8 type=GET_GLOBAL(drive_g->type);
                    123:     if (type == DTYPE_ATA)
                    124:         status = await_rdy(iobase1);
                    125: 
                    126: done:
                    127:     // Enable interrupts
                    128:     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
                    129: 
                    130:     dprintf(6, "ata_reset exit status=%x\n", status);
                    131: }
                    132: 
1.1.1.2 ! root      133: // Check for drive RDY for 16bit interface command.
1.1       root      134: static int
                    135: isready(struct drive_s *drive_g)
                    136: {
                    137:     // Read the status from controller
                    138:     u8 ataid = GET_GLOBAL(drive_g->cntl_id);
                    139:     u8 channel = ataid / 2;
                    140:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
                    141:     u8 status = inb(iobase1 + ATA_CB_STAT);
                    142:     if ((status & (ATA_CB_STAT_BSY|ATA_CB_STAT_RDY)) == ATA_CB_STAT_RDY)
                    143:         return DISK_RET_SUCCESS;
                    144:     return DISK_RET_ENOTREADY;
                    145: }
                    146: 
1.1.1.2 ! root      147: // Default 16bit command demuxer for ATA and ATAPI devices.
1.1       root      148: static int
                    149: process_ata_misc_op(struct disk_op_s *op)
                    150: {
                    151:     if (!CONFIG_ATA)
                    152:         return 0;
                    153: 
                    154:     switch (op->command) {
                    155:     case CMD_RESET:
                    156:         ata_reset(op->drive_g);
                    157:         return DISK_RET_SUCCESS;
                    158:     case CMD_ISREADY:
                    159:         return isready(op->drive_g);
                    160:     case CMD_FORMAT:
                    161:     case CMD_VERIFY:
                    162:     case CMD_SEEK:
                    163:         return DISK_RET_SUCCESS;
                    164:     default:
                    165:         op->count = 0;
                    166:         return DISK_RET_EPARAM;
                    167:     }
                    168: }
                    169: 
                    170: 
                    171: /****************************************************************
                    172:  * ATA send command
                    173:  ****************************************************************/
                    174: 
                    175: struct ata_pio_command {
                    176:     u8 feature;
                    177:     u8 sector_count;
                    178:     u8 lba_low;
                    179:     u8 lba_mid;
                    180:     u8 lba_high;
                    181:     u8 device;
                    182:     u8 command;
                    183: 
1.1.1.2 ! root      184:     u8 feature2;
1.1       root      185:     u8 sector_count2;
                    186:     u8 lba_low2;
                    187:     u8 lba_mid2;
                    188:     u8 lba_high2;
                    189: };
                    190: 
                    191: // Send an ata command to the drive.
                    192: static int
                    193: send_cmd(struct drive_s *drive_g, struct ata_pio_command *cmd)
                    194: {
                    195:     u8 ataid = GET_GLOBAL(drive_g->cntl_id);
                    196:     u8 channel = ataid / 2;
                    197:     u8 slave = ataid % 2;
                    198:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
                    199: 
                    200:     // Select device
                    201:     int status = await_not_bsy(iobase1);
                    202:     if (status < 0)
                    203:         return status;
                    204:     u8 newdh = ((cmd->device & ~ATA_CB_DH_DEV1)
                    205:                 | (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0));
                    206:     u8 olddh = inb(iobase1 + ATA_CB_DH);
                    207:     outb(newdh, iobase1 + ATA_CB_DH);
                    208:     if ((olddh ^ newdh) & (1<<4)) {
                    209:         // Was a device change - wait for device to become not busy.
                    210:         status = ndelay_await_not_bsy(iobase1);
                    211:         if (status < 0)
                    212:             return status;
                    213:     }
                    214: 
1.1.1.2 ! root      215:     // Check for ATA_CMD_(READ|WRITE)_(SECTORS|DMA)_EXT commands.
        !           216:     if ((cmd->command & ~0x11) == ATA_CMD_READ_SECTORS_EXT) {
        !           217:         outb(cmd->feature2, iobase1 + ATA_CB_FR);
1.1       root      218:         outb(cmd->sector_count2, iobase1 + ATA_CB_SC);
                    219:         outb(cmd->lba_low2, iobase1 + ATA_CB_SN);
                    220:         outb(cmd->lba_mid2, iobase1 + ATA_CB_CL);
                    221:         outb(cmd->lba_high2, iobase1 + ATA_CB_CH);
                    222:     }
                    223:     outb(cmd->feature, iobase1 + ATA_CB_FR);
                    224:     outb(cmd->sector_count, iobase1 + ATA_CB_SC);
                    225:     outb(cmd->lba_low, iobase1 + ATA_CB_SN);
                    226:     outb(cmd->lba_mid, iobase1 + ATA_CB_CL);
                    227:     outb(cmd->lba_high, iobase1 + ATA_CB_CH);
                    228:     outb(cmd->command, iobase1 + ATA_CB_CMD);
                    229: 
1.1.1.2 ! root      230:     return 0;
        !           231: }
        !           232: 
        !           233: // Wait for data after calling 'send_cmd'.
        !           234: static int
        !           235: ata_wait_data(u16 iobase1)
        !           236: {
        !           237:     int status = ndelay_await_not_bsy(iobase1);
1.1       root      238:     if (status < 0)
                    239:         return status;
                    240: 
                    241:     if (status & ATA_CB_STAT_ERR) {
                    242:         dprintf(6, "send_cmd : read error (status=%02x err=%02x)\n"
                    243:                 , status, inb(iobase1 + ATA_CB_ERR));
                    244:         return -4;
                    245:     }
                    246:     if (!(status & ATA_CB_STAT_DRQ)) {
                    247:         dprintf(6, "send_cmd : DRQ not set (status %02x)\n", status);
                    248:         return -5;
                    249:     }
                    250: 
                    251:     return 0;
                    252: }
                    253: 
1.1.1.2 ! root      254: // Send an ata command that does not transfer any further data.
        !           255: int
        !           256: ata_cmd_nondata(struct drive_s *drive_g, struct ata_pio_command *cmd)
        !           257: {
        !           258:     u8 ataid = GET_GLOBAL(drive_g->cntl_id);
        !           259:     u8 channel = ataid / 2;
        !           260:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
        !           261:     u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
        !           262: 
        !           263:     // Disable interrupts
        !           264:     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
        !           265: 
        !           266:     int ret = send_cmd(drive_g, cmd);
        !           267:     if (ret)
        !           268:         goto fail;
        !           269:     ret = ndelay_await_not_bsy(iobase1);
        !           270:     if (ret < 0)
        !           271:         goto fail;
        !           272: 
        !           273:     if (ret & ATA_CB_STAT_ERR) {
        !           274:         dprintf(6, "nondata cmd : read error (status=%02x err=%02x)\n"
        !           275:                 , ret, inb(iobase1 + ATA_CB_ERR));
        !           276:         ret = -4;
        !           277:         goto fail;
        !           278:     }
        !           279:     if (ret & ATA_CB_STAT_DRQ) {
        !           280:         dprintf(6, "nondata cmd : DRQ set (status %02x)\n", ret);
        !           281:         ret = -5;
        !           282:         goto fail;
        !           283:     }
        !           284: 
        !           285: fail:
        !           286:     // Enable interrupts
        !           287:     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
        !           288: 
        !           289:     return ret;
        !           290: }
        !           291: 
1.1       root      292: 
                    293: /****************************************************************
1.1.1.2 ! root      294:  * ATA PIO transfers
1.1       root      295:  ****************************************************************/
                    296: 
                    297: // Transfer 'op->count' blocks (of 'blocksize' bytes) to/from drive
                    298: // 'op->drive_g'.
                    299: static int
1.1.1.2 ! root      300: ata_pio_transfer(struct disk_op_s *op, int iswrite, int blocksize)
1.1       root      301: {
1.1.1.2 ! root      302:     dprintf(16, "ata_pio_transfer id=%p write=%d count=%d bs=%d buf=%p\n"
1.1       root      303:             , op->drive_g, iswrite, op->count, blocksize, op->buf_fl);
                    304: 
                    305:     u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
                    306:     u8 channel = ataid / 2;
                    307:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
                    308:     u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
                    309:     int count = op->count;
                    310:     void *buf_fl = op->buf_fl;
                    311:     int status;
                    312:     for (;;) {
                    313:         if (iswrite) {
                    314:             // Write data to controller
                    315:             dprintf(16, "Write sector id=%p dest=%p\n", op->drive_g, buf_fl);
                    316:             if (CONFIG_ATA_PIO32)
                    317:                 outsl_fl(iobase1, buf_fl, blocksize / 4);
                    318:             else
                    319:                 outsw_fl(iobase1, buf_fl, blocksize / 2);
                    320:         } else {
                    321:             // Read data from controller
                    322:             dprintf(16, "Read sector id=%p dest=%p\n", op->drive_g, buf_fl);
                    323:             if (CONFIG_ATA_PIO32)
                    324:                 insl_fl(iobase1, buf_fl, blocksize / 4);
                    325:             else
                    326:                 insw_fl(iobase1, buf_fl, blocksize / 2);
                    327:         }
                    328:         buf_fl += blocksize;
                    329: 
                    330:         status = pause_await_not_bsy(iobase1, iobase2);
                    331:         if (status < 0) {
                    332:             // Error
                    333:             op->count -= count;
                    334:             return status;
                    335:         }
                    336: 
                    337:         count--;
                    338:         if (!count)
                    339:             break;
                    340:         status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR);
                    341:         if (status != ATA_CB_STAT_DRQ) {
1.1.1.2 ! root      342:             dprintf(6, "ata_pio_transfer : more sectors left (status %02x)\n"
1.1       root      343:                     , status);
                    344:             op->count -= count;
                    345:             return -6;
                    346:         }
                    347:     }
                    348: 
                    349:     status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ
                    350:                | ATA_CB_STAT_ERR);
                    351:     if (!iswrite)
                    352:         status &= ~ATA_CB_STAT_DF;
                    353:     if (status != 0) {
1.1.1.2 ! root      354:         dprintf(6, "ata_pio_transfer : no sectors left (status %02x)\n", status);
1.1       root      355:         return -7;
                    356:     }
                    357: 
                    358:     return 0;
                    359: }
                    360: 
                    361: 
                    362: /****************************************************************
1.1.1.2 ! root      363:  * ATA DMA transfers
        !           364:  ****************************************************************/
        !           365: 
        !           366: #define BM_CMD    0
        !           367: #define  BM_CMD_MEMWRITE  0x08
        !           368: #define  BM_CMD_START     0x01
        !           369: #define BM_STATUS 2
        !           370: #define  BM_STATUS_IRQ    0x04
        !           371: #define  BM_STATUS_ERROR  0x02
        !           372: #define  BM_STATUS_ACTIVE 0x01
        !           373: #define BM_TABLE  4
        !           374: 
        !           375: struct sff_dma_prd {
        !           376:     u32 buf_fl;
        !           377:     u32 count;
        !           378: };
        !           379: 
        !           380: // Check if DMA available and setup transfer if so.
        !           381: static int
        !           382: ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize)
        !           383: {
        !           384:     u32 dest = (u32)op->buf_fl;
        !           385:     if (dest & 1)
        !           386:         // Need minimum alignment of 1.
        !           387:         return -1;
        !           388:     u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
        !           389:     u8 channel = ataid / 2;
        !           390:     u16 iomaster = GET_GLOBAL(ATA_channels[channel].iomaster);
        !           391:     if (! iomaster)
        !           392:         return -1;
        !           393:     u32 bytes = op->count * blocksize;
        !           394:     if (! bytes)
        !           395:         return -1;
        !           396: 
        !           397:     // Build PRD dma structure.
        !           398:     struct sff_dma_prd *dma = MAKE_FLATPTR(
        !           399:         get_ebda_seg()
        !           400:         , (void*)offsetof(struct extended_bios_data_area_s, extra_stack));
        !           401:     struct sff_dma_prd *origdma = dma;
        !           402:     while (bytes) {
        !           403:         if (dma >= &origdma[16])
        !           404:             // Too many descriptors..
        !           405:             return -1;
        !           406:         u32 count = bytes;
        !           407:         if (count > 0x10000)
        !           408:             count = 0x10000;
        !           409:         u32 max = 0x10000 - (dest & 0xffff);
        !           410:         if (count > max)
        !           411:             count = max;
        !           412: 
        !           413:         SET_FLATPTR(dma->buf_fl, dest);
        !           414:         bytes -= count;
        !           415:         if (!bytes)
        !           416:             // Last descriptor.
        !           417:             count |= 1<<31;
        !           418:         dprintf(16, "dma@%p: %08x %08x\n", dma, dest, count);
        !           419:         dest += count;
        !           420:         SET_FLATPTR(dma->count, count);
        !           421:         dma++;
        !           422:     }
        !           423: 
        !           424:     // Program bus-master controller.
        !           425:     outl((u32)origdma, iomaster + BM_TABLE);
        !           426:     u8 oldcmd = inb(iomaster + BM_CMD) & ~(BM_CMD_MEMWRITE|BM_CMD_START);
        !           427:     outb(oldcmd | (iswrite ? 0x00 : BM_CMD_MEMWRITE), iomaster + BM_CMD);
        !           428:     outb(BM_STATUS_ERROR|BM_STATUS_IRQ, iomaster + BM_STATUS);
        !           429: 
        !           430:     return 0;
        !           431: }
        !           432: 
        !           433: // Transfer data using DMA.
        !           434: static int
        !           435: ata_dma_transfer(struct disk_op_s *op)
        !           436: {
        !           437:     dprintf(16, "ata_dma_transfer id=%p buf=%p\n"
        !           438:             , op->drive_g, op->buf_fl);
        !           439: 
        !           440:     u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
        !           441:     u8 channel = ataid / 2;
        !           442:     u16 iomaster = GET_GLOBAL(ATA_channels[channel].iomaster);
        !           443: 
        !           444:     // Start bus-master controller.
        !           445:     u8 oldcmd = inb(iomaster + BM_CMD);
        !           446:     outb(oldcmd | BM_CMD_START, iomaster + BM_CMD);
        !           447: 
        !           448:     u64 end = calc_future_tsc(IDE_TIMEOUT);
        !           449:     u8 status;
        !           450:     for (;;) {
        !           451:         status = inb(iomaster + BM_STATUS);
        !           452:         if (status & BM_STATUS_IRQ)
        !           453:             break;
        !           454:         // Transfer in progress
        !           455:         if (check_time(end)) {
        !           456:             // Timeout.
        !           457:             dprintf(1, "IDE DMA timeout\n");
        !           458:             break;
        !           459:         }
        !           460:         yield();
        !           461:     }
        !           462:     outb(oldcmd & ~BM_CMD_START, iomaster + BM_CMD);
        !           463: 
        !           464:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
        !           465:     u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
        !           466:     int idestatus = pause_await_not_bsy(iobase1, iobase2);
        !           467: 
        !           468:     if ((status & (BM_STATUS_IRQ|BM_STATUS_ACTIVE)) == BM_STATUS_IRQ
        !           469:         && idestatus >= 0x00
        !           470:         && (idestatus & (ATA_CB_STAT_BSY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ
        !           471:                          | ATA_CB_STAT_ERR)) == 0x00)
        !           472:         // Success.
        !           473:         return 0;
        !           474: 
        !           475:     dprintf(6, "IDE DMA error (dma=%x ide=%x/%x/%x)\n", status, idestatus
        !           476:             , inb(iobase2 + ATA_CB_ASTAT), inb(iobase1 + ATA_CB_ERR));
        !           477:     op->count = 0;
        !           478:     return -1;
        !           479: }
        !           480: 
        !           481: 
        !           482: /****************************************************************
1.1       root      483:  * ATA hard drive functions
                    484:  ****************************************************************/
                    485: 
1.1.1.2 ! root      486: // Transfer data to harddrive using PIO protocol.
1.1       root      487: static int
1.1.1.2 ! root      488: ata_pio_cmd_data(struct disk_op_s *op, int iswrite, struct ata_pio_command *cmd)
1.1       root      489: {
                    490:     u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
                    491:     u8 channel = ataid / 2;
1.1.1.2 ! root      492:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
1.1       root      493:     u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
1.1.1.2 ! root      494: 
        !           495:     // Disable interrupts
        !           496:     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
        !           497: 
        !           498:     int ret = send_cmd(op->drive_g, cmd);
        !           499:     if (ret)
        !           500:         goto fail;
        !           501:     ret = ata_wait_data(iobase1);
        !           502:     if (ret)
        !           503:         goto fail;
        !           504:     ret = ata_pio_transfer(op, iswrite, DISK_SECTOR_SIZE);
        !           505: 
        !           506: fail:
        !           507:     // Enable interrupts
        !           508:     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
        !           509:     return ret;
        !           510: }
        !           511: 
        !           512: // Transfer data to harddrive using DMA protocol.
        !           513: static int
        !           514: ata_dma_cmd_data(struct disk_op_s *op, struct ata_pio_command *cmd)
        !           515: {
        !           516:     int ret = send_cmd(op->drive_g, cmd);
        !           517:     if (ret)
        !           518:         return ret;
        !           519:     return ata_dma_transfer(op);
        !           520: }
        !           521: 
        !           522: // Read/write count blocks from a harddrive.
        !           523: static int
        !           524: ata_readwrite(struct disk_op_s *op, int iswrite)
        !           525: {
1.1       root      526:     u64 lba = op->lba;
                    527: 
1.1.1.2 ! root      528:     int usepio = ata_try_dma(op, iswrite, DISK_SECTOR_SIZE);
        !           529: 
1.1       root      530:     struct ata_pio_command cmd;
                    531:     memset(&cmd, 0, sizeof(cmd));
                    532: 
                    533:     if (op->count >= (1<<8) || lba + op->count >= (1<<28)) {
                    534:         cmd.sector_count2 = op->count >> 8;
                    535:         cmd.lba_low2 = lba >> 24;
                    536:         cmd.lba_mid2 = lba >> 32;
                    537:         cmd.lba_high2 = lba >> 40;
                    538:         lba &= 0xffffff;
1.1.1.2 ! root      539: 
        !           540:         if (usepio)
        !           541:             cmd.command = (iswrite ? ATA_CMD_WRITE_SECTORS_EXT
        !           542:                            : ATA_CMD_READ_SECTORS_EXT);
        !           543:         else
        !           544:             cmd.command = (iswrite ? ATA_CMD_WRITE_DMA_EXT
        !           545:                            : ATA_CMD_READ_DMA_EXT);
        !           546:     } else {
        !           547:         if (usepio)
        !           548:             cmd.command = (iswrite ? ATA_CMD_WRITE_SECTORS
        !           549:                            : ATA_CMD_READ_SECTORS);
        !           550:         else
        !           551:             cmd.command = (iswrite ? ATA_CMD_WRITE_DMA
        !           552:                            : ATA_CMD_READ_DMA);
1.1       root      553:     }
                    554: 
                    555:     cmd.sector_count = op->count;
                    556:     cmd.lba_low = lba;
                    557:     cmd.lba_mid = lba >> 8;
                    558:     cmd.lba_high = lba >> 16;
                    559:     cmd.device = ((lba >> 24) & 0xf) | ATA_CB_DH_LBA;
                    560: 
1.1.1.2 ! root      561:     int ret;
        !           562:     if (usepio)
        !           563:         ret = ata_pio_cmd_data(op, iswrite, &cmd);
        !           564:     else
        !           565:         ret = ata_dma_cmd_data(op, &cmd);
1.1       root      566:     if (ret)
1.1.1.2 ! root      567:         return DISK_RET_EBADTRACK;
        !           568:     return DISK_RET_SUCCESS;
1.1       root      569: }
                    570: 
1.1.1.2 ! root      571: // 16bit command demuxer for ATA harddrives.
1.1       root      572: int
                    573: process_ata_op(struct disk_op_s *op)
                    574: {
                    575:     if (!CONFIG_ATA)
                    576:         return 0;
                    577: 
                    578:     switch (op->command) {
                    579:     case CMD_READ:
1.1.1.2 ! root      580:         return ata_readwrite(op, 0);
1.1       root      581:     case CMD_WRITE:
1.1.1.2 ! root      582:         return ata_readwrite(op, 1);
1.1       root      583:     default:
                    584:         return process_ata_misc_op(op);
                    585:     }
                    586: }
                    587: 
                    588: 
                    589: /****************************************************************
                    590:  * ATAPI functions
                    591:  ****************************************************************/
                    592: 
                    593: // Low-level atapi command transmit function.
                    594: static int
                    595: atapi_cmd_data(struct disk_op_s *op, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
                    596: {
                    597:     u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
                    598:     u8 channel = ataid / 2;
                    599:     u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
                    600:     u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
                    601: 
                    602:     struct ata_pio_command cmd;
1.1.1.2 ! root      603:     memset(&cmd, 0, sizeof(cmd));
1.1       root      604:     cmd.lba_mid = blocksize;
                    605:     cmd.lba_high = blocksize >> 8;
                    606:     cmd.command = ATA_CMD_PACKET;
                    607: 
                    608:     // Disable interrupts
                    609:     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
                    610: 
                    611:     int ret = send_cmd(op->drive_g, &cmd);
                    612:     if (ret)
                    613:         goto fail;
1.1.1.2 ! root      614:     ret = ata_wait_data(iobase1);
        !           615:     if (ret)
        !           616:         goto fail;
1.1       root      617: 
                    618:     // Send command to device
                    619:     outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cmdbuf), cmdlen / 2);
                    620: 
                    621:     int status = pause_await_not_bsy(iobase1, iobase2);
                    622:     if (status < 0) {
                    623:         ret = status;
                    624:         goto fail;
                    625:     }
                    626: 
                    627:     if (status & ATA_CB_STAT_ERR) {
                    628:         u8 err = inb(iobase1 + ATA_CB_ERR);
                    629:         // skip "Not Ready"
                    630:         if (err != 0x20)
                    631:             dprintf(6, "send_atapi_cmd : read error (status=%02x err=%02x)\n"
                    632:                     , status, err);
                    633:         ret = -2;
                    634:         goto fail;
                    635:     }
                    636:     if (!(status & ATA_CB_STAT_DRQ)) {
                    637:         dprintf(6, "send_atapi_cmd : DRQ not set (status %02x)\n", status);
                    638:         ret = -3;
                    639:         goto fail;
                    640:     }
                    641: 
1.1.1.2 ! root      642:     ret = ata_pio_transfer(op, 0, blocksize);
1.1       root      643: 
                    644: fail:
                    645:     // Enable interrupts
                    646:     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
                    647:     return ret;
                    648: }
                    649: 
                    650: // Read sectors from the cdrom.
                    651: int
                    652: cdrom_read(struct disk_op_s *op)
                    653: {
                    654:     u8 atacmd[12];
                    655:     memset(atacmd, 0, sizeof(atacmd));
                    656:     atacmd[0]=0x28;                         // READ command
                    657:     atacmd[7]=(op->count & 0xff00) >> 8;    // Sectors
                    658:     atacmd[8]=(op->count & 0x00ff);
                    659:     atacmd[2]=(op->lba & 0xff000000) >> 24; // LBA
                    660:     atacmd[3]=(op->lba & 0x00ff0000) >> 16;
                    661:     atacmd[4]=(op->lba & 0x0000ff00) >> 8;
                    662:     atacmd[5]=(op->lba & 0x000000ff);
                    663: 
                    664:     return atapi_cmd_data(op, atacmd, sizeof(atacmd), CDROM_SECTOR_SIZE);
                    665: }
                    666: 
1.1.1.2 ! root      667: // 16bit command demuxer for ATAPI cdroms.
1.1       root      668: int
                    669: process_atapi_op(struct disk_op_s *op)
                    670: {
                    671:     int ret;
                    672:     switch (op->command) {
                    673:     case CMD_READ:
                    674:         ret = cdrom_read(op);
1.1.1.2 ! root      675:         if (ret)
        !           676:             return DISK_RET_EBADTRACK;
        !           677:         return DISK_RET_SUCCESS;
1.1       root      678:     case CMD_FORMAT:
                    679:     case CMD_WRITE:
                    680:         return DISK_RET_EWRITEPROTECT;
                    681:     default:
                    682:         return process_ata_misc_op(op);
                    683:     }
                    684: }
                    685: 
                    686: // Send a simple atapi command to a drive.
                    687: int
                    688: ata_cmd_packet(struct drive_s *drive_g, u8 *cmdbuf, u8 cmdlen
                    689:                , u32 length, void *buf_fl)
                    690: {
                    691:     struct disk_op_s dop;
                    692:     memset(&dop, 0, sizeof(dop));
                    693:     dop.drive_g = drive_g;
                    694:     dop.count = 1;
                    695:     dop.buf_fl = buf_fl;
                    696: 
                    697:     return atapi_cmd_data(&dop, cmdbuf, cmdlen, length);
                    698: }
                    699: 
                    700: 
                    701: /****************************************************************
                    702:  * ATA detect and init
                    703:  ****************************************************************/
                    704: 
1.1.1.2 ! root      705: // Send an identify device or identify device packet command.
        !           706: static int
        !           707: send_ata_identity(struct drive_s *drive_g, u16 *buffer, int command)
        !           708: {
        !           709:     memset(buffer, 0, DISK_SECTOR_SIZE);
        !           710: 
        !           711:     struct disk_op_s dop;
        !           712:     memset(&dop, 0, sizeof(dop));
        !           713:     dop.drive_g = drive_g;
        !           714:     dop.count = 1;
        !           715:     dop.lba = 1;
        !           716:     dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer);
        !           717: 
        !           718:     struct ata_pio_command cmd;
        !           719:     memset(&cmd, 0, sizeof(cmd));
        !           720:     cmd.command = command;
        !           721: 
        !           722:     return ata_pio_cmd_data(&dop, 0, &cmd);
        !           723: }
        !           724: 
1.1       root      725: // Extract the ATA/ATAPI version info.
                    726: static int
                    727: extract_version(u16 *buffer)
                    728: {
                    729:     // Extract ATA/ATAPI version.
                    730:     u16 ataversion = buffer[80];
                    731:     u8 version;
                    732:     for (version=15; version>0; version--)
                    733:         if (ataversion & (1<<version))
                    734:             break;
                    735:     return version;
                    736: }
                    737: 
                    738: // Extract common information from IDENTIFY commands.
                    739: static void
                    740: extract_identify(struct drive_s *drive_g, u16 *buffer)
                    741: {
                    742:     dprintf(3, "Identify w0=%x w2=%x\n", buffer[0], buffer[2]);
                    743: 
                    744:     // Read model name
                    745:     char *model = drive_g->model;
                    746:     int maxsize = ARRAY_SIZE(drive_g->model);
                    747:     int i;
                    748:     for (i=0; i<maxsize/2; i++) {
                    749:         u16 v = buffer[27+i];
                    750:         model[i*2] = v >> 8;
                    751:         model[i*2+1] = v & 0xff;
                    752:     }
                    753:     model[maxsize-1] = 0x00;
                    754: 
                    755:     // Trim trailing spaces from model name.
                    756:     for (i=maxsize-2; i>0 && model[i] == 0x20; i--)
                    757:         model[i] = 0x00;
                    758: 
                    759:     // Common flags.
                    760:     SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
                    761:     SET_GLOBAL(drive_g->cntl_info, extract_version(buffer));
                    762: }
                    763: 
1.1.1.2 ! root      764: // Print out a description of the given atapi drive.
1.1       root      765: void
                    766: describe_atapi(struct drive_s *drive_g)
                    767: {
                    768:     u8 ataid = drive_g->cntl_id;
                    769:     u8 channel = ataid / 2;
                    770:     u8 slave = ataid % 2;
                    771:     u8 version = drive_g->cntl_info;
                    772:     int iscd = drive_g->floppy_type;
                    773:     printf("ata%d-%d: %s ATAPI-%d %s", channel, slave
                    774:            , drive_g->model, version
                    775:            , (iscd ? "CD-Rom/DVD-Rom" : "Device"));
                    776: }
                    777: 
1.1.1.2 ! root      778: // Detect if the given drive is an atapi - initialize it if so.
1.1       root      779: static struct drive_s *
                    780: init_drive_atapi(struct drive_s *dummy, u16 *buffer)
                    781: {
                    782:     // Send an IDENTIFY_DEVICE_PACKET command to device
1.1.1.2 ! root      783:     int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_PACKET_DEVICE);
1.1       root      784:     if (ret)
                    785:         return NULL;
                    786: 
                    787:     // Success - setup as ATAPI.
                    788:     struct drive_s *drive_g = allocDrive();
                    789:     if (! drive_g)
                    790:         return NULL;
                    791:     SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
                    792:     extract_identify(drive_g, buffer);
                    793:     SET_GLOBAL(drive_g->type, DTYPE_ATAPI);
                    794:     SET_GLOBAL(drive_g->blksize, CDROM_SECTOR_SIZE);
                    795:     SET_GLOBAL(drive_g->sectors, (u64)-1);
                    796:     u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
                    797:     SET_GLOBAL(drive_g->floppy_type, iscd);
                    798: 
                    799:     // fill cdidmap
                    800:     if (iscd)
                    801:         map_cd_drive(drive_g);
                    802: 
                    803:     return drive_g;
                    804: }
                    805: 
1.1.1.2 ! root      806: // Print out a description of the given ata drive.
1.1       root      807: void
                    808: describe_ata(struct drive_s *drive_g)
                    809: {
                    810:     u8 ataid = drive_g->cntl_id;
                    811:     u8 channel = ataid / 2;
                    812:     u8 slave = ataid % 2;
                    813:     u64 sectors = drive_g->sectors;
                    814:     u8 version = drive_g->cntl_info;
                    815:     char *model = drive_g->model;
                    816:     printf("ata%d-%d: %s ATA-%d Hard-Disk", channel, slave, model, version);
                    817:     u64 sizeinmb = sectors >> 11;
                    818:     if (sizeinmb < (1 << 16))
                    819:         printf(" (%u MiBytes)", (u32)sizeinmb);
                    820:     else
                    821:         printf(" (%u GiBytes)", (u32)(sizeinmb >> 10));
                    822: }
                    823: 
1.1.1.2 ! root      824: // Detect if the given drive is a regular ata drive - initialize it if so.
1.1       root      825: static struct drive_s *
                    826: init_drive_ata(struct drive_s *dummy, u16 *buffer)
                    827: {
                    828:     // Send an IDENTIFY_DEVICE command to device
1.1.1.2 ! root      829:     int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_DEVICE);
1.1       root      830:     if (ret)
                    831:         return NULL;
                    832: 
                    833:     // Success - setup as ATA.
                    834:     struct drive_s *drive_g = allocDrive();
                    835:     if (! drive_g)
                    836:         return NULL;
                    837:     SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
                    838:     extract_identify(drive_g, buffer);
                    839:     SET_GLOBAL(drive_g->type, DTYPE_ATA);
                    840:     SET_GLOBAL(drive_g->blksize, DISK_SECTOR_SIZE);
                    841: 
                    842:     SET_GLOBAL(drive_g->pchs.cylinders, buffer[1]);
                    843:     SET_GLOBAL(drive_g->pchs.heads, buffer[3]);
                    844:     SET_GLOBAL(drive_g->pchs.spt, buffer[6]);
                    845: 
                    846:     u64 sectors;
                    847:     if (buffer[83] & (1 << 10)) // word 83 - lba48 support
                    848:         sectors = *(u64*)&buffer[100]; // word 100-103
                    849:     else
                    850:         sectors = *(u32*)&buffer[60]; // word 60 and word 61
                    851:     SET_GLOBAL(drive_g->sectors, sectors);
                    852: 
                    853:     // Setup disk geometry translation.
                    854:     setup_translation(drive_g);
                    855: 
                    856:     // Register with bcv system.
                    857:     add_bcv_internal(drive_g);
                    858: 
                    859:     return drive_g;
                    860: }
                    861: 
                    862: static u64 SpinupEnd;
                    863: 
1.1.1.2 ! root      864: // Wait for non-busy status and check for "floating bus" condition.
1.1       root      865: static int
                    866: powerup_await_non_bsy(u16 base)
                    867: {
                    868:     u8 orstatus = 0;
                    869:     u8 status;
                    870:     for (;;) {
                    871:         status = inb(base+ATA_CB_STAT);
                    872:         if (!(status & ATA_CB_STAT_BSY))
                    873:             break;
                    874:         orstatus |= status;
                    875:         if (orstatus == 0xff) {
                    876:             dprintf(1, "powerup IDE floating\n");
                    877:             return orstatus;
                    878:         }
                    879:         if (check_time(SpinupEnd)) {
                    880:             dprintf(1, "powerup IDE time out\n");
                    881:             return -1;
                    882:         }
                    883:         yield();
                    884:     }
                    885:     dprintf(6, "powerup iobase=%x st=%x\n", base, status);
                    886:     return status;
                    887: }
                    888: 
1.1.1.2 ! root      889: // Detect any drives attached to a given controller.
1.1       root      890: static void
                    891: ata_detect(void *data)
                    892: {
                    893:     struct ata_channel_s *atachannel = data;
                    894:     int startid = (atachannel - ATA_channels) * 2;
                    895:     struct drive_s dummy;
                    896:     memset(&dummy, 0, sizeof(dummy));
                    897:     // Device detection
                    898:     int ataid, last_reset_ataid=-1;
                    899:     for (ataid=startid; ataid<startid+2; ataid++) {
                    900:         u8 channel = ataid / 2;
                    901:         u8 slave = ataid % 2;
                    902: 
                    903:         u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
                    904:         if (!iobase1)
                    905:             break;
                    906: 
                    907:         // Wait for not-bsy.
                    908:         int status = powerup_await_non_bsy(iobase1);
                    909:         if (status < 0)
                    910:             continue;
                    911:         u8 newdh = slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0;
                    912:         outb(newdh, iobase1+ATA_CB_DH);
                    913:         ndelay(400);
                    914:         status = powerup_await_non_bsy(iobase1);
                    915:         if (status < 0)
                    916:             continue;
                    917: 
                    918:         // Check if ioport registers look valid.
                    919:         outb(newdh, iobase1+ATA_CB_DH);
                    920:         u8 dh = inb(iobase1+ATA_CB_DH);
                    921:         outb(0x55, iobase1+ATA_CB_SC);
                    922:         outb(0xaa, iobase1+ATA_CB_SN);
                    923:         u8 sc = inb(iobase1+ATA_CB_SC);
                    924:         u8 sn = inb(iobase1+ATA_CB_SN);
                    925:         dprintf(6, "ata_detect ataid=%d sc=%x sn=%x dh=%x\n"
                    926:                 , ataid, sc, sn, dh);
                    927:         if (sc != 0x55 || sn != 0xaa || dh != newdh)
                    928:             continue;
                    929: 
                    930:         // Prepare new drive.
                    931:         dummy.cntl_id = ataid;
                    932: 
                    933:         // reset the channel
                    934:         if (slave && ataid == last_reset_ataid + 1) {
                    935:             // The drive was just reset - no need to reset it again.
                    936:         } else {
                    937:             ata_reset(&dummy);
                    938:             last_reset_ataid = ataid;
                    939:         }
                    940: 
                    941:         // check for ATAPI
                    942:         u16 buffer[256];
                    943:         struct drive_s *drive_g = init_drive_atapi(&dummy, buffer);
                    944:         if (!drive_g) {
                    945:             // Didn't find an ATAPI drive - look for ATA drive.
                    946:             u8 st = inb(iobase1+ATA_CB_STAT);
                    947:             if (!st)
                    948:                 // Status not set - can't be a valid drive.
                    949:                 continue;
                    950: 
                    951:             // Wait for RDY.
                    952:             int ret = await_rdy(iobase1);
                    953:             if (ret < 0)
                    954:                 continue;
                    955: 
                    956:             // check for ATA.
                    957:             drive_g = init_drive_ata(&dummy, buffer);
                    958:             if (!drive_g)
                    959:                 // No ATA drive found
                    960:                 continue;
                    961:         }
                    962: 
                    963:         u16 resetresult = buffer[93];
                    964:         dprintf(6, "ata_detect resetresult=%04x\n", resetresult);
                    965:         if (!slave && (resetresult & 0xdf61) == 0x4041)
                    966:             // resetresult looks valid and device 0 is responding to
                    967:             // device 1 requests - device 1 must not be present - skip
                    968:             // detection.
                    969:             ataid++;
                    970:     }
                    971: }
                    972: 
1.1.1.2 ! root      973: // Initialize an ata controller and detect its drives.
1.1       root      974: static void
                    975: init_controller(struct ata_channel_s *atachannel
1.1.1.2 ! root      976:                 , int bdf, int irq, u32 port1, u32 port2, u32 master)
1.1       root      977: {
                    978:     SET_GLOBAL(atachannel->irq, irq);
                    979:     SET_GLOBAL(atachannel->pci_bdf, bdf);
                    980:     SET_GLOBAL(atachannel->iobase1, port1);
                    981:     SET_GLOBAL(atachannel->iobase2, port2);
1.1.1.2 ! root      982:     SET_GLOBAL(atachannel->iomaster, master);
        !           983:     dprintf(1, "ATA controller %d at %x/%x/%x (irq %d dev %x)\n"
        !           984:             , atachannel - ATA_channels, port1, port2, master, irq, bdf);
1.1       root      985:     run_thread(ata_detect, atachannel);
                    986: }
                    987: 
                    988: #define IRQ_ATA1 14
                    989: #define IRQ_ATA2 15
                    990: 
1.1.1.2 ! root      991: // Locate and init ata controllers.
1.1       root      992: static void
1.1.1.2 ! root      993: ata_init(void)
1.1       root      994: {
                    995:     // Scan PCI bus for ATA adapters
                    996:     int count=0, pcicount=0;
                    997:     int bdf, max;
                    998:     foreachpci(bdf, max) {
                    999:         pcicount++;
                   1000:         if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE)
                   1001:             continue;
                   1002:         if (count >= ARRAY_SIZE(ATA_channels))
                   1003:             break;
                   1004: 
                   1005:         u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
                   1006:         u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
1.1.1.2 ! root     1007:         int master = 0;
        !          1008:         if (prog_if & 0x80) {
        !          1009:             // Check for bus-mastering.
        !          1010:             u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4);
        !          1011:             if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
        !          1012:                 master = bar & PCI_BASE_ADDRESS_IO_MASK;
        !          1013:                 pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
        !          1014:             }
        !          1015:         }
        !          1016: 
1.1       root     1017:         u32 port1, port2, irq;
                   1018:         if (prog_if & 1) {
                   1019:             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) & ~3;
                   1020:             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_1) & ~3;
                   1021:             irq = pciirq;
                   1022:         } else {
                   1023:             port1 = PORT_ATA1_CMD_BASE;
                   1024:             port2 = PORT_ATA1_CTRL_BASE;
                   1025:             irq = IRQ_ATA1;
                   1026:         }
1.1.1.2 ! root     1027:         init_controller(&ATA_channels[count], bdf, irq, port1, port2, master);
1.1       root     1028:         count++;
                   1029: 
                   1030:         if (prog_if & 4) {
                   1031:             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_2) & ~3;
                   1032:             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_3) & ~3;
                   1033:             irq = pciirq;
                   1034:         } else {
                   1035:             port1 = PORT_ATA2_CMD_BASE;
                   1036:             port2 = PORT_ATA2_CTRL_BASE;
                   1037:             irq = IRQ_ATA2;
                   1038:         }
1.1.1.2 ! root     1039:         init_controller(&ATA_channels[count], bdf, irq, port1, port2
        !          1040:                         , master ? master + 8 : 0);
1.1       root     1041:         count++;
                   1042:     }
                   1043: 
                   1044:     if (!CONFIG_COREBOOT && !pcicount && ARRAY_SIZE(ATA_channels) >= 2) {
                   1045:         // No PCI devices found - probably a QEMU "-M isapc" machine.
                   1046:         // Try using ISA ports for ATA controllers.
1.1.1.2 ! root     1047:         init_controller(&ATA_channels[0], -1, IRQ_ATA1
        !          1048:                         , PORT_ATA1_CMD_BASE, PORT_ATA1_CTRL_BASE, 0);
        !          1049:         init_controller(&ATA_channels[1], -1, IRQ_ATA2
        !          1050:                         , PORT_ATA2_CMD_BASE, PORT_ATA2_CTRL_BASE, 0);
1.1       root     1051:     }
                   1052: }
                   1053: 
                   1054: void
1.1.1.2 ! root     1055: ata_setup(void)
1.1       root     1056: {
                   1057:     if (!CONFIG_ATA)
                   1058:         return;
                   1059: 
                   1060:     dprintf(3, "init hard drives\n");
                   1061: 
                   1062:     SpinupEnd = calc_future_tsc(IDE_TIMEOUT);
                   1063:     ata_init();
                   1064: 
                   1065:     SET_BDA(disk_control_byte, 0xc0);
                   1066: 
                   1067:     enable_hwirq(14, entry_76);
                   1068: }

unix.superglobalmegacorp.com

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