Annotation of qemu/roms/ipxe/src/drivers/block/ata.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2006 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <stddef.h>
                     22: #include <stdlib.h>
                     23: #include <string.h>
                     24: #include <assert.h>
                     25: #include <errno.h>
                     26: #include <byteswap.h>
                     27: #include <ipxe/list.h>
                     28: #include <ipxe/interface.h>
                     29: #include <ipxe/blockdev.h>
                     30: #include <ipxe/edd.h>
                     31: #include <ipxe/ata.h>
                     32: 
                     33: /** @file
                     34:  *
                     35:  * ATA block device
                     36:  *
                     37:  */
                     38: 
                     39: /******************************************************************************
                     40:  *
                     41:  * Interface methods
                     42:  *
                     43:  ******************************************************************************
                     44:  */
                     45: 
                     46: /**
                     47:  * Issue ATA command
                     48:  *
                     49:  * @v control          ATA control interface
                     50:  * @v data             ATA data interface
                     51:  * @v command          ATA command
                     52:  * @ret tag            Command tag, or negative error
                     53:  */
                     54: int ata_command ( struct interface *control, struct interface *data,
                     55:                  struct ata_cmd *command ) {
                     56:        struct interface *dest;
                     57:        ata_command_TYPE ( void * ) *op =
                     58:                intf_get_dest_op ( control, ata_command, &dest );
                     59:        void *object = intf_object ( dest );
                     60:        int tag;
                     61: 
                     62:        if ( op ) {
                     63:                tag = op ( object, data, command );
                     64:        } else {
                     65:                /* Default is to fail to issue the command */
                     66:                tag = -EOPNOTSUPP;
                     67:        }
                     68: 
                     69:        intf_put ( dest );
                     70:        return tag;
                     71: }
                     72: 
                     73: /******************************************************************************
                     74:  *
                     75:  * ATA devices and commands
                     76:  *
                     77:  ******************************************************************************
                     78:  */
                     79: 
                     80: /** List of all ATA commands */
                     81: static LIST_HEAD ( ata_commands );
                     82: 
                     83: /** An ATA device */
                     84: struct ata_device {
                     85:        /** Reference count */
                     86:        struct refcnt refcnt;
                     87:        /** Block control interface */
                     88:        struct interface block;
                     89:        /** ATA control interface */
                     90:        struct interface ata;
                     91: 
                     92:        /** Device number
                     93:         *
                     94:         * Must be ATA_DEV_MASTER or ATA_DEV_SLAVE.
                     95:         */
                     96:        unsigned int device;
                     97:        /** Maximum number of blocks per single transfer */
                     98:        unsigned int max_count;
                     99:        /** Device uses LBA48 extended addressing */
                    100:        int lba48;
                    101: };
                    102: 
                    103: /** An ATA command */
                    104: struct ata_command {
                    105:        /** Reference count */
                    106:        struct refcnt refcnt;
                    107:        /** ATA device */
                    108:        struct ata_device *atadev;
                    109:        /** List of ATA commands */
                    110:        struct list_head list;
                    111: 
                    112:        /** Block data interface */
                    113:        struct interface block;
                    114:        /** ATA data interface */
                    115:        struct interface ata;
                    116: 
                    117:        /** Command type */
                    118:        struct ata_command_type *type;
                    119:        /** Command tag */
                    120:        uint32_t tag;
                    121: 
                    122:        /** Private data */
                    123:        uint8_t priv[0];
                    124: };
                    125: 
                    126: /** An ATA command type */
                    127: struct ata_command_type {
                    128:        /** Name */
                    129:        const char *name;
                    130:        /** Additional working space */
                    131:        size_t priv_len;
                    132:        /** Command for non-LBA48-capable devices */
                    133:        uint8_t cmd_lba;
                    134:        /** Command for LBA48-capable devices */
                    135:        uint8_t cmd_lba48;
                    136:        /**
                    137:         * Calculate data-in buffer
                    138:         *
                    139:         * @v atacmd            ATA command
                    140:         * @v buffer            Available buffer
                    141:         * @v len               Available buffer length
                    142:         * @ret data_in         Data-in buffer
                    143:         * @ret data_in_len     Data-in buffer length
                    144:         */
                    145:        void ( * data_in ) ( struct ata_command *atacmd, userptr_t buffer,
                    146:                             size_t len, userptr_t *data_in,
                    147:                             size_t *data_in_len );
                    148:        /**
                    149:         * Calculate data-out buffer
                    150:         *
                    151:         *
                    152:         * @v atacmd            ATA command
                    153:         * @v buffer            Available buffer
                    154:         * @v len               Available buffer length
                    155:         * @ret data_out        Data-out buffer
                    156:         * @ret data_out_len    Data-out buffer length
                    157:         */
                    158:        void ( * data_out ) ( struct ata_command *atacmd, userptr_t buffer,
                    159:                              size_t len, userptr_t *data_out,
                    160:                              size_t *data_out_len );
                    161:        /**
                    162:         * Handle ATA command completion
                    163:         *
                    164:         * @v atacmd            ATA command
                    165:         * @v rc                Reason for completion
                    166:         */
                    167:        void ( * done ) ( struct ata_command *atacmd, int rc );
                    168: };
                    169: 
                    170: /**
                    171:  * Get reference to ATA device
                    172:  *
                    173:  * @v atadev           ATA device
                    174:  * @ret atadev         ATA device
                    175:  */
                    176: static inline __attribute__ (( always_inline )) struct ata_device *
                    177: atadev_get ( struct ata_device *atadev ) {
                    178:        ref_get ( &atadev->refcnt );
                    179:        return atadev;
                    180: }
                    181: 
                    182: /**
                    183:  * Drop reference to ATA device
                    184:  *
                    185:  * @v atadev           ATA device
                    186:  */
                    187: static inline __attribute__ (( always_inline )) void
                    188: atadev_put ( struct ata_device *atadev ) {
                    189:        ref_put ( &atadev->refcnt );
                    190: }
                    191: 
                    192: /**
                    193:  * Get reference to ATA command
                    194:  *
                    195:  * @v atacmd           ATA command
                    196:  * @ret atacmd         ATA command
                    197:  */
                    198: static inline __attribute__ (( always_inline )) struct ata_command *
                    199: atacmd_get ( struct ata_command *atacmd ) {
                    200:        ref_get ( &atacmd->refcnt );
                    201:        return atacmd;
                    202: }
                    203: 
                    204: /**
                    205:  * Drop reference to ATA command
                    206:  *
                    207:  * @v atacmd           ATA command
                    208:  */
                    209: static inline __attribute__ (( always_inline )) void
                    210: atacmd_put ( struct ata_command *atacmd ) {
                    211:        ref_put ( &atacmd->refcnt );
                    212: }
                    213: 
                    214: /**
                    215:  * Get ATA command private data
                    216:  *
                    217:  * @v atacmd           ATA command
                    218:  * @ret priv           Private data
                    219:  */
                    220: static inline __attribute__ (( always_inline )) void *
                    221: atacmd_priv ( struct ata_command *atacmd ) {
                    222:        return atacmd->priv;
                    223: }
                    224: 
                    225: /**
                    226:  * Free ATA command
                    227:  *
                    228:  * @v refcnt           Reference count
                    229:  */
                    230: static void atacmd_free ( struct refcnt *refcnt ) {
                    231:        struct ata_command *atacmd =
                    232:                container_of ( refcnt, struct ata_command, refcnt );
                    233: 
                    234:        /* Remove from list of commands */
                    235:        list_del ( &atacmd->list );
                    236:        atadev_put ( atacmd->atadev );
                    237: 
                    238:        /* Free command */
                    239:        free ( atacmd );
                    240: }
                    241: 
                    242: /**
                    243:  * Close ATA command
                    244:  *
                    245:  * @v atacmd           ATA command
                    246:  * @v rc               Reason for close
                    247:  */
                    248: static void atacmd_close ( struct ata_command *atacmd, int rc ) {
                    249:        struct ata_device *atadev = atacmd->atadev;
                    250: 
                    251:        if ( rc != 0 ) {
                    252:                DBGC ( atadev, "ATA %p tag %08x closed: %s\n",
                    253:                       atadev, atacmd->tag, strerror ( rc ) );
                    254:        }
                    255: 
                    256:        /* Shut down interfaces */
                    257:        intf_shutdown ( &atacmd->ata, rc );
                    258:        intf_shutdown ( &atacmd->block, rc );
                    259: }
                    260: 
                    261: /**
                    262:  * Handle ATA command completion
                    263:  *
                    264:  * @v atacmd           ATA command
                    265:  * @v rc               Reason for close
                    266:  */
                    267: static void atacmd_done ( struct ata_command *atacmd, int rc ) {
                    268: 
                    269:        /* Hand over to the command completion handler */
                    270:        atacmd->type->done ( atacmd, rc );
                    271: }
                    272: 
                    273: /**
                    274:  * Use provided data buffer for ATA command
                    275:  *
                    276:  * @v atacmd           ATA command
                    277:  * @v buffer           Available buffer
                    278:  * @v len              Available buffer length
                    279:  * @ret data           Data buffer
                    280:  * @ret data_len       Data buffer length
                    281:  */
                    282: static void atacmd_data_buffer ( struct ata_command *atacmd __unused,
                    283:                                 userptr_t buffer, size_t len,
                    284:                                 userptr_t *data, size_t *data_len ) {
                    285:        *data = buffer;
                    286:        *data_len = len;
                    287: }
                    288: 
                    289: /**
                    290:  * Use no data buffer for ATA command
                    291:  *
                    292:  * @v atacmd           ATA command
                    293:  * @v buffer           Available buffer
                    294:  * @v len              Available buffer length
                    295:  * @ret data           Data buffer
                    296:  * @ret data_len       Data buffer length
                    297:  */
                    298: static void atacmd_data_none ( struct ata_command *atacmd __unused,
                    299:                               userptr_t buffer __unused, size_t len __unused,
                    300:                               userptr_t *data __unused,
                    301:                               size_t *data_len __unused ) {
                    302:        /* Nothing to do */
                    303: }
                    304: 
                    305: /**
                    306:  * Use private data buffer for ATA command
                    307:  *
                    308:  * @v atacmd           ATA command
                    309:  * @v buffer           Available buffer
                    310:  * @v len              Available buffer length
                    311:  * @ret data           Data buffer
                    312:  * @ret data_len       Data buffer length
                    313:  */
                    314: static void atacmd_data_priv ( struct ata_command *atacmd,
                    315:                               userptr_t buffer __unused, size_t len __unused,
                    316:                               userptr_t *data, size_t *data_len ) {
                    317:        *data = virt_to_user ( atacmd_priv ( atacmd ) );
                    318:        *data_len = atacmd->type->priv_len;
                    319: }
                    320: 
                    321: /** ATA READ command type */
                    322: static struct ata_command_type atacmd_read = {
                    323:        .name = "READ",
                    324:        .cmd_lba = ATA_CMD_READ,
                    325:        .cmd_lba48 = ATA_CMD_READ_EXT,
                    326:        .data_in = atacmd_data_buffer,
                    327:        .data_out = atacmd_data_none,
                    328:        .done = atacmd_close,
                    329: };
                    330: 
                    331: /** ATA WRITE command type */
                    332: static struct ata_command_type atacmd_write = {
                    333:        .name = "WRITE",
                    334:        .cmd_lba = ATA_CMD_WRITE,
                    335:        .cmd_lba48 = ATA_CMD_WRITE_EXT,
                    336:        .data_in = atacmd_data_none,
                    337:        .data_out = atacmd_data_buffer,
                    338:        .done = atacmd_close,
                    339: };
                    340: 
                    341: /** ATA IDENTIFY private data */
                    342: struct ata_identify_private {
                    343:        /** Identity data */
                    344:        struct ata_identity identity;
                    345: };
                    346: 
                    347: /**
                    348:  * Return ATA model string (for debugging)
                    349:  *
                    350:  * @v identify         ATA identity data
                    351:  * @ret model          Model string
                    352:  */
                    353: static const char * ata_model ( struct ata_identity *identity ) {
                    354:        static union {
                    355:                uint16_t words[ sizeof ( identity->model ) / 2 ];
                    356:                char text[ sizeof ( identity->model ) + 1 /* NUL */ ];
                    357:        } buf;
                    358:        unsigned int i;
                    359: 
                    360:        for ( i = 0 ; i < ( sizeof ( identity->model ) / 2 ) ; i++ )
                    361:                buf.words[i] = bswap_16 ( identity->model[i] );
                    362: 
                    363:        return buf.text;
                    364: }
                    365: 
                    366: /**
                    367:  * Handle ATA IDENTIFY command completion
                    368:  *
                    369:  * @v atacmd           ATA command
                    370:  * @v rc               Reason for completion
                    371:  */
                    372: static void atacmd_identify_done ( struct ata_command *atacmd, int rc ) {
                    373:        struct ata_device *atadev = atacmd->atadev;
                    374:        struct ata_identify_private *priv = atacmd_priv ( atacmd );
                    375:        struct ata_identity *identity = &priv->identity;
                    376:        struct block_device_capacity capacity;
                    377: 
                    378:        /* Close if command failed */
                    379:        if ( rc != 0 ) {
                    380:                atacmd_close ( atacmd, rc );
                    381:                return;
                    382:        }
                    383: 
                    384:        /* Extract capacity */
                    385:        if ( identity->supports_lba48 & cpu_to_le16 ( ATA_SUPPORTS_LBA48 ) ) {
                    386:                atadev->lba48 = 1;
                    387:                capacity.blocks = le64_to_cpu ( identity->lba48_sectors );
                    388:        } else {
                    389:                capacity.blocks = le32_to_cpu ( identity->lba_sectors );
                    390:        }
                    391:        capacity.blksize = ATA_SECTOR_SIZE;
                    392:        capacity.max_count = atadev->max_count;
                    393:        DBGC ( atadev, "ATA %p is a %s\n", atadev, ata_model ( identity ) );
                    394:        DBGC ( atadev, "ATA %p has %#llx blocks (%ld MB) and uses %s\n",
                    395:               atadev, capacity.blocks,
                    396:               ( ( signed long ) ( capacity.blocks >> 11 ) ),
                    397:               ( atadev->lba48 ? "LBA48" : "LBA" ) );
                    398: 
                    399:        /* Return capacity to caller */
                    400:        block_capacity ( &atacmd->block, &capacity );
                    401: 
                    402:        /* Close command */
                    403:        atacmd_close ( atacmd, 0 );
                    404: }
                    405: 
                    406: /** ATA IDENTITY command type */
                    407: static struct ata_command_type atacmd_identify = {
                    408:        .name = "IDENTIFY",
                    409:        .priv_len = sizeof ( struct ata_identify_private ),
                    410:        .cmd_lba = ATA_CMD_IDENTIFY,
                    411:        .cmd_lba48 = ATA_CMD_IDENTIFY,
                    412:        .data_in = atacmd_data_priv,
                    413:        .data_out = atacmd_data_none,
                    414:        .done = atacmd_identify_done,
                    415: };
                    416: 
                    417: /** ATA command block interface operations */
                    418: static struct interface_operation atacmd_block_op[] = {
                    419:        INTF_OP ( intf_close, struct ata_command *, atacmd_close ),
                    420: };
                    421: 
                    422: /** ATA command block interface descriptor */
                    423: static struct interface_descriptor atacmd_block_desc =
                    424:        INTF_DESC_PASSTHRU ( struct ata_command, block,
                    425:                             atacmd_block_op, ata );
                    426: 
                    427: /** ATA command ATA interface operations */
                    428: static struct interface_operation atacmd_ata_op[] = {
                    429:        INTF_OP ( intf_close, struct ata_command *, atacmd_done ),
                    430: };
                    431: 
                    432: /** ATA command ATA interface descriptor */
                    433: static struct interface_descriptor atacmd_ata_desc =
                    434:        INTF_DESC_PASSTHRU ( struct ata_command, ata,
                    435:                             atacmd_ata_op, block );
                    436: 
                    437: /**
                    438:  * Create ATA command
                    439:  *
                    440:  * @v atadev           ATA device
                    441:  * @v block            Block data interface
                    442:  * @v type             ATA command type
                    443:  * @v lba              Starting logical block address
                    444:  * @v count            Number of blocks to transfer
                    445:  * @v buffer           Data buffer
                    446:  * @v len              Length of data buffer
                    447:  * @ret rc             Return status code
                    448:  */
                    449: static int atadev_command ( struct ata_device *atadev,
                    450:                            struct interface *block,
                    451:                            struct ata_command_type *type,
                    452:                            uint64_t lba, unsigned int count,
                    453:                            userptr_t buffer, size_t len ) {
                    454:        struct ata_command *atacmd;
                    455:        struct ata_cmd command;
                    456:        int tag;
                    457:        int rc;
                    458: 
                    459:        /* Allocate and initialise structure */
                    460:        atacmd = zalloc ( sizeof ( *atacmd ) + type->priv_len );
                    461:        if ( ! atacmd ) {
                    462:                rc = -ENOMEM;
                    463:                goto err_zalloc;
                    464:        }
                    465:        ref_init ( &atacmd->refcnt, atacmd_free );
                    466:        intf_init ( &atacmd->block, &atacmd_block_desc, &atacmd->refcnt );
                    467:        intf_init ( &atacmd->ata, &atacmd_ata_desc,
                    468:                    &atacmd->refcnt );
                    469:        atacmd->atadev = atadev_get ( atadev );
                    470:        list_add ( &atacmd->list, &ata_commands );
                    471:        atacmd->type = type;
                    472: 
                    473:        /* Sanity check */
                    474:        if ( len != ( count * ATA_SECTOR_SIZE ) ) {
                    475:                DBGC ( atadev, "ATA %p tag %08x buffer length mismatch (count "
                    476:                       "%d len %zd)\n", atadev, atacmd->tag, count, len );
                    477:                rc = -EINVAL;
                    478:                goto err_len;
                    479:        }
                    480: 
                    481:        /* Construct command */
                    482:        memset ( &command, 0, sizeof ( command ) );
                    483:        command.cb.lba.native = lba;
                    484:        command.cb.count.native = count;
                    485:        command.cb.device = ( atadev->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
                    486:        command.cb.lba48 = atadev->lba48;
                    487:        if ( ! atadev->lba48 )
                    488:                command.cb.device |= command.cb.lba.bytes.low_prev;
                    489:        command.cb.cmd_stat =
                    490:                ( atadev->lba48 ? type->cmd_lba48 : type->cmd_lba );
                    491:        type->data_in ( atacmd, buffer, len,
                    492:                        &command.data_in, &command.data_in_len );
                    493:        type->data_out ( atacmd, buffer, len,
                    494:                         &command.data_out, &command.data_out_len );
                    495: 
                    496:        /* Issue command */
                    497:        if ( ( tag = ata_command ( &atadev->ata, &atacmd->ata,
                    498:                                   &command ) ) < 0 ) {
                    499:                rc = tag;
                    500:                DBGC ( atadev, "ATA %p tag %08x could not issue command: %s\n",
                    501:                       atadev, atacmd->tag, strerror ( rc ) );
                    502:                goto err_command;
                    503:        }
                    504:        atacmd->tag = tag;
                    505: 
                    506:        DBGC2 ( atadev, "ATA %p tag %08x %s cmd %02x dev %02x LBA%s %08llx "
                    507:                "count %04x\n", atadev, atacmd->tag, atacmd->type->name,
                    508:                command.cb.cmd_stat, command.cb.device,
                    509:                ( command.cb.lba48 ? "48" : "" ),
                    510:                ( unsigned long long ) command.cb.lba.native,
                    511:                command.cb.count.native );
                    512: 
                    513:        /* Attach to parent interface, mortalise self, and return */
                    514:        intf_plug_plug ( &atacmd->block, block );
                    515:        ref_put ( &atacmd->refcnt );
                    516:        return 0;
                    517: 
                    518:  err_command:
                    519:  err_len:
                    520:        atacmd_close ( atacmd, rc );
                    521:        ref_put ( &atacmd->refcnt );
                    522:  err_zalloc:
                    523:        return rc;
                    524: }
                    525: 
                    526: /**
                    527:  * Issue ATA block read
                    528:  *
                    529:  * @v atadev           ATA device
                    530:  * @v block            Block data interface
                    531:  * @v lba              Starting logical block address
                    532:  * @v count            Number of blocks to transfer
                    533:  * @v buffer           Data buffer
                    534:  * @v len              Length of data buffer
                    535:  * @ret rc             Return status code
                    536: 
                    537:  */
                    538: static int atadev_read ( struct ata_device *atadev,
                    539:                         struct interface *block,
                    540:                         uint64_t lba, unsigned int count,
                    541:                         userptr_t buffer, size_t len ) {
                    542:        return atadev_command ( atadev, block, &atacmd_read,
                    543:                                lba, count, buffer, len );
                    544: }
                    545: 
                    546: /**
                    547:  * Issue ATA block write
                    548:  *
                    549:  * @v atadev           ATA device
                    550:  * @v block            Block data interface
                    551:  * @v lba              Starting logical block address
                    552:  * @v count            Number of blocks to transfer
                    553:  * @v buffer           Data buffer
                    554:  * @v len              Length of data buffer
                    555:  * @ret rc             Return status code
                    556:  */
                    557: static int atadev_write ( struct ata_device *atadev,
                    558:                          struct interface *block,
                    559:                          uint64_t lba, unsigned int count,
                    560:                          userptr_t buffer, size_t len ) {
                    561:        return atadev_command ( atadev, block, &atacmd_write,
                    562:                                lba, count, buffer, len );
                    563: }
                    564: 
                    565: /**
                    566:  * Read ATA device capacity
                    567:  *
                    568:  * @v atadev           ATA device
                    569:  * @v block            Block data interface
                    570:  * @ret rc             Return status code
                    571:  */
                    572: static int atadev_read_capacity ( struct ata_device *atadev,
                    573:                                  struct interface *block ) {
                    574:        struct ata_identity *identity;
                    575: 
                    576:        assert ( atacmd_identify.priv_len == sizeof ( *identity ) );
                    577:        assert ( atacmd_identify.priv_len == ATA_SECTOR_SIZE );
                    578:        return atadev_command ( atadev, block, &atacmd_identify,
                    579:                                0, 1, UNULL, ATA_SECTOR_SIZE );
                    580: }
                    581: 
                    582: /**
                    583:  * Close ATA device
                    584:  *
                    585:  * @v atadev           ATA device
                    586:  * @v rc               Reason for close
                    587:  */
                    588: static void atadev_close ( struct ata_device *atadev, int rc ) {
                    589:        struct ata_command *atacmd;
                    590:        struct ata_command *tmp;
                    591: 
                    592:        /* Shut down interfaces */
                    593:        intf_shutdown ( &atadev->block, rc );
                    594:        intf_shutdown ( &atadev->ata, rc );
                    595: 
                    596:        /* Shut down any remaining commands */
                    597:        list_for_each_entry_safe ( atacmd, tmp, &ata_commands, list ) {
                    598:                if ( atacmd->atadev != atadev )
                    599:                        continue;
                    600:                atacmd_get ( atacmd );
                    601:                atacmd_close ( atacmd, rc );
                    602:                atacmd_put ( atacmd );
                    603:        }
                    604: }
                    605: 
                    606: /**
                    607:  * Describe ATA device using EDD
                    608:  *
                    609:  * @v atadev           ATA device
                    610:  * @v type             EDD interface type
                    611:  * @v path             EDD device path
                    612:  * @ret rc             Return status code
                    613:  */
                    614: static int atadev_edd_describe ( struct ata_device *atadev,
                    615:                                 struct edd_interface_type *type,
                    616:                                 union edd_device_path *path ) {
                    617: 
                    618:        type->type = cpu_to_le64 ( EDD_INTF_TYPE_ATA );
                    619:        path->ata.slave = ( ( atadev->device == ATA_DEV_SLAVE ) ? 0x01 : 0x00 );
                    620:        return 0;
                    621: }
                    622: 
                    623: /** ATA device block interface operations */
                    624: static struct interface_operation atadev_block_op[] = {
                    625:        INTF_OP ( block_read, struct ata_device *, atadev_read ),
                    626:        INTF_OP ( block_write, struct ata_device *, atadev_write ),
                    627:        INTF_OP ( block_read_capacity, struct ata_device *,
                    628:                  atadev_read_capacity ),
                    629:        INTF_OP ( intf_close, struct ata_device *, atadev_close ),
                    630:        INTF_OP ( edd_describe, struct ata_device *, atadev_edd_describe ),
                    631: };
                    632: 
                    633: /** ATA device block interface descriptor */
                    634: static struct interface_descriptor atadev_block_desc =
                    635:        INTF_DESC_PASSTHRU ( struct ata_device, block,
                    636:                             atadev_block_op, ata );
                    637: 
                    638: /** ATA device ATA interface operations */
                    639: static struct interface_operation atadev_ata_op[] = {
                    640:        INTF_OP ( intf_close, struct ata_device *, atadev_close ),
                    641: };
                    642: 
                    643: /** ATA device ATA interface descriptor */
                    644: static struct interface_descriptor atadev_ata_desc =
                    645:        INTF_DESC_PASSTHRU ( struct ata_device, ata,
                    646:                             atadev_ata_op, block );
                    647: 
                    648: /**
                    649:  * Open ATA device
                    650:  *
                    651:  * @v block            Block control interface
                    652:  * @v ata              ATA control interface
                    653:  * @v device           ATA device number
                    654:  * @v max_count                Maximum number of blocks per single transfer
                    655:  * @ret rc             Return status code
                    656:  */
                    657: int ata_open ( struct interface *block, struct interface *ata,
                    658:               unsigned int device, unsigned int max_count ) {
                    659:        struct ata_device *atadev;
                    660: 
                    661:        /* Allocate and initialise structure */
                    662:        atadev = zalloc ( sizeof ( *atadev ) );
                    663:        if ( ! atadev )
                    664:                return -ENOMEM;
                    665:        ref_init ( &atadev->refcnt, NULL );
                    666:        intf_init ( &atadev->block, &atadev_block_desc, &atadev->refcnt );
                    667:        intf_init ( &atadev->ata, &atadev_ata_desc, &atadev->refcnt );
                    668:        atadev->device = device;
                    669:        atadev->max_count = max_count;
                    670: 
                    671:        /* Attach to ATA and parent and interfaces, mortalise self,
                    672:         * and return
                    673:         */
                    674:        intf_plug_plug ( &atadev->ata, ata );
                    675:        intf_plug_plug ( &atadev->block, block );
                    676:        ref_put ( &atadev->refcnt );
                    677:        return 0;
                    678: }

unix.superglobalmegacorp.com

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