Changeset ae3ff9f5 in mainline for uspace/drv/block/ahci/ahci.c


Ignore:
Timestamp:
2012-07-18T17:35:08Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7030bc9
Parents:
730dce77
Message:

import AHCI updates (comments, fixes) from Petr Jerman (lp:~petr-jerman/+junk/hos-ahci)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/block/ahci/ahci.c

    r730dce77 rae3ff9f5  
    4949#define NAME  "ahci"
    5050
    51 #define AHCI_TIMER_TICKS  1000000000
     51/** Number of ticks for watchdog timer. */
     52#define AHCI_TIMER_TICKS  800000
     53
     54/** Number of ticks for timer based interrupt. */
     55#define AHCI_TIMER_NO_INTR_TICKS  8000
    5256
    5357#define LO(ptr) \
     
    7074static void ahci_sata_devices_create(ahci_dev_t *, ddf_dev_t *);
    7175static ahci_dev_t *ahci_ahci_create(ddf_dev_t *);
    72 static void ahci_ahci_init(ahci_dev_t *);
     76static void ahci_ahci_hw_start(ahci_dev_t *);
    7377
    7478static int ahci_dev_add(ddf_dev_t *);
    7579
    7680static void ahci_get_model_name(uint16_t *, char *);
    77 static int ahci_pciintel_enable_interrupt(int);
     81static int ahci_enable_interrupt(int);
    7882
    7983static fibril_mutex_t sata_devices_count_lock;
     
    105109};
    106110
     111/** Get SATA device name.
     112 *
     113 * @param fun                  Device function handling the call.
     114 * @param sata_dev_name_length Length of the sata_dev_name buffer.
     115 * @param sata_dev_name        Buffer for SATA device name.
     116 *
     117 * @return EOK.
     118 *
     119 */
    107120static int ahci_get_sata_device_name(ddf_fun_t *fun,
    108121    size_t sata_dev_name_length, char *sata_dev_name)
     
    113126}
    114127
     128/** Get Number of blocks in SATA device.
     129 *
     130 * @param fun    Device function handling the call.
     131 * @param blocks Return number of blocks in SATA device.
     132 *
     133 * @return EOK.
     134 *
     135 */
    115136static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
    116137{
     
    120141}
    121142
     143/** Get SATA device block size.
     144 *
     145 * @param fun        Device function handling the call.
     146 * @param block_size Return block size.
     147 *
     148 * @return EOK.
     149 *
     150 */
    122151static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size)
    123152{
     
    127156}
    128157
     158/** Read data blocks into SATA device.
     159 *
     160 * @param fun      Device function handling the call.
     161 * @param blocknum Number of first block.
     162 * @param count    Number of blocks to read.
     163 * @param buf      Buffer for data.
     164 *
     165 * @return EOK if succeed, error code otherwise
     166 *
     167 */
    129168static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum,
    130169    size_t count, void *buf)
    131170{
    132         int rc = EOK;
    133171        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    134172       
    135173        void *phys;
    136174        void *ibuf;
    137        
    138         dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
     175        int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
    139176            0, &phys, (void **) &ibuf);
     177        if (rc != EOK) {
     178                ddf_msg(LVL_ERROR, "Cannot allocate read buffer.");
     179                return rc;
     180        }
     181       
    140182        bzero(buf, sata->block_size);
    141183       
     
    157199}
    158200
     201/** Write data blocks into SATA device.
     202 *
     203 * @param fun      Device function handling the call.
     204 * @param blocknum Number of first block.
     205 * @param count    Number of blocks to write.
     206 * @param buf      Buffer with data.
     207 *
     208 * @return EOK if succeed, error code otherwise
     209 *
     210 */
    159211static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum,
    160212    size_t count, void *buf)
    161213{
    162         int rc = EOK;
    163214        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    164215       
    165216        void *phys;
    166217        void *ibuf;
    167        
    168         dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
     218        int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
    169219            0, &phys, (void **) &ibuf);
     220        if (rc != EOK) {
     221                ddf_msg(LVL_ERROR, "Cannot allocate write buffer.");
     222                return rc;
     223        }
    170224       
    171225        fibril_mutex_lock(&sata->lock);
     
    181235        fibril_mutex_unlock(&sata->lock);
    182236        dmamem_unmap_anonymous(ibuf);
     237       
    183238        return rc;
    184239}
     
    188243/*----------------------------------------------------------------------------*/
    189244
     245/** Get and clear AHCI port interrupt state register.
     246 *
     247 * @param sata SATA device structure.
     248 *
     249 * @return Value of interrupt state register.
     250 *
     251 */
     252static ahci_port_is_t ahci_get_and_clear_pxis(sata_dev_t *sata)
     253{
     254        ahci_port_is_t pxis;
     255       
     256        fibril_mutex_lock(&sata->pxis_lock);
     257       
     258        pxis.u32 = sata->ahci->memregs->ports[sata->port_num].pxis;
     259        sata->ahci->memregs->ports[sata->port_num].pxis = pxis.u32;
     260       
     261        if (ahci_port_is_permanent_error(pxis))
     262                sata->is_invalid_device = true;
     263       
     264        fibril_mutex_unlock(&sata->pxis_lock);
     265       
     266        return pxis;
     267}
     268
     269/** Set AHCI registers for identifying SATA device.
     270 *
     271 * @param sata SATA device structure.
     272 * @param phys Physical address of working buffer.
     273 *
     274 */
    190275static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys)
    191276{
    192         volatile std_command_frame_t *cmd =
    193             (std_command_frame_t *) sata->cmd_table;
    194        
    195         cmd->fis_type = 0x27;
    196         cmd->c = 0x80;
     277        /* Clear interrupt state registers */
     278        ahci_get_and_clear_pxis(sata);
     279        sata->shadow_pxis.u32 = 0;
     280       
     281        volatile sata_std_command_frame_t *cmd =
     282            (sata_std_command_frame_t *) sata->cmd_table;
     283       
     284        cmd->fis_type = SATA_CMD_FIS_TYPE;
     285        cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
    197286        cmd->command = 0xec;
    198287        cmd->features = 0;
     
    212301        prdt->data_address_upper = HI(phys);
    213302        prdt->reserved1 = 0;
    214         prdt->dbc = 511;
     303        prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1;
    215304        prdt->reserved2 = 0;
    216305        prdt->ioc = 0;
    217306       
    218307        sata->cmd_header->prdtl = 1;
    219         sata->cmd_header->flags = 0x402;
     308        sata->cmd_header->flags =
     309            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
     310            AHCI_CMDHDR_FLAGS_2DWCMD;
    220311        sata->cmd_header->bytesprocessed = 0;
    221312       
     313        /* Run command. */
    222314        sata->port->pxsact |= 1;
    223315        sata->port->pxci |= 1;
    224316}
    225317
     318/** Set AHCI registers for identifying packet SATA device.
     319 *
     320 * @param sata SATA device structure.
     321 * @param phys Physical address of working buffer.
     322 *
     323 */
    226324static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys)
    227325{
    228         volatile std_command_frame_t *cmd =
    229             (std_command_frame_t *) sata->cmd_table;
    230        
    231         cmd->fis_type = 0x27;
    232         cmd->c = 0x80;
     326        /* Clear interrupt state registers */
     327        ahci_get_and_clear_pxis(sata);
     328        sata->shadow_pxis.u32 = 0;
     329       
     330        volatile sata_std_command_frame_t * cmd =
     331            (sata_std_command_frame_t *) sata->cmd_table;
     332       
     333        cmd->fis_type = SATA_CMD_FIS_TYPE;
     334        cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
    233335        cmd->command = 0xa1;
    234336        cmd->features = 0;
     
    248350        prdt->data_address_upper = HI(phys);
    249351        prdt->reserved1 = 0;
    250         prdt->dbc = 511;
     352        prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1;
    251353        prdt->reserved2 = 0;
    252354        prdt->ioc = 0;
    253355       
    254356        sata->cmd_header->prdtl = 1;
    255         sata->cmd_header->flags = 0x402;
     357        sata->cmd_header->flags =
     358            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
     359            AHCI_CMDHDR_FLAGS_2DWCMD;
    256360        sata->cmd_header->bytesprocessed = 0;
    257361       
     362        /* Run command. */
    258363        sata->port->pxsact |= 1;
    259364        sata->port->pxci |= 1;
    260365}
    261366
     367/** Fill device identification in SATA device structure.
     368 *
     369 * @param sata SATA device structure.
     370 *
     371 * @return EOK if succeed, error code otherwise.
     372 *
     373 */
    262374static int ahci_identify_device(sata_dev_t *sata)
    263375{
    264         if (sata->invalid_device) {
     376        if (sata->is_invalid_device) {
    265377                ddf_msg(LVL_ERROR,
    266378                    "Identify command device on invalid device");
     
    269381       
    270382        void *phys;
    271         identify_data_t *idata;
    272        
     383        sata_identify_data_t *idata;
    273384        dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
    274385            (void **) &idata);
     
    286397        sata->shadow_pxis.u32 &= ~pxis.u32;
    287398       
    288         if (sata->invalid_device) {
     399        if (sata->is_invalid_device) {
    289400                ddf_msg(LVL_ERROR,
    290401                    "Unrecoverable error during ata identify device");
     
    302413                sata->shadow_pxis.u32 &= ~pxis.u32;
    303414               
    304                 if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
     415                if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
    305416                        ddf_msg(LVL_ERROR,
    306417                            "Unrecoverable error during ata identify packet device");
     
    308419                }
    309420               
    310                 sata->packet_device = true;
    311         } else
    312                 sata->packet_device = false;
     421                sata->is_packet_device = true;
     422        }
    313423       
    314424        ahci_get_model_name(idata->model_name, sata->model);
     
    318428         * only NCQ FPDMA mode is supported.
    319429         */
    320         if ((idata->sata_cap & np_cap_ncq) == 0) {
     430        if ((idata->sata_cap & sata_np_cap_ncq) == 0) {
    321431                ddf_msg(LVL_ERROR, "%s: NCQ must be supported", sata->model);
    322432                goto error;
    323433        }
    324434       
    325         if (sata->packet_device) {
     435        uint16_t logsec = idata->physical_logic_sector_size;
     436        if ((logsec & 0xc000) == 0x4000) {
     437                /* Length of sector may be larger than 512 B */
     438                if (logsec & 0x0100) {
     439                        /* Size of sector is larger than 512 B */
     440                        ddf_msg(LVL_ERROR,
     441                            "%s: Sector length other than 512 B not supported",
     442                            sata->model);
     443                        goto error;     
     444                }
     445               
     446                if ((logsec & 0x0200) && ((logsec & 0x000f) != 0)) {
     447                        /* Physical sectors per logical sector is greather than 1 */
     448                        ddf_msg(LVL_ERROR,
     449                            "%s: Sector length other than 512 B not supported",
     450                            sata->model);
     451                        goto error;     
     452                }
     453        }
     454       
     455        if (sata->is_packet_device) {
    326456                /*
    327457                 * Due to QEMU limitation (as of 2012-06-22),
    328                  * only NCQ FPDMA mode supported - block size is 512 B,
    329                  * not 2048 B!
     458                 * only NCQ FPDMA mode supported - block size is
     459                 * 512 B, not 2048 B!
    330460                 */
    331                 sata->block_size = 512;
     461                sata->block_size = SATA_DEFAULT_SECTOR_SIZE;
    332462                sata->blocks = 0;
    333463        } else {
    334                 sata->block_size = 512;
     464                sata->block_size = SATA_DEFAULT_SECTOR_SIZE;
    335465               
    336                 if ((idata->caps & rd_cap_lba) == 0) {
     466                if ((idata->caps & sata_rd_cap_lba) == 0) {
    337467                        ddf_msg(LVL_ERROR, "%s: LBA for NCQ must be supported",
    338468                            sata->model);
    339469                        goto error;
    340                 } else if ((idata->cmd_set1 & cs1_addr48) == 0) {
     470                } else if ((idata->cmd_set1 & sata_cs1_addr48) == 0) {
    341471                        sata->blocks = (uint32_t) idata->total_lba28_0 |
    342472                            ((uint32_t) idata->total_lba28_1 << 16);
     
    351481       
    352482        uint8_t udma_mask = idata->udma & 0x007f;
     483        sata->highest_udma_mode = (uint8_t) -1;
    353484        if (udma_mask == 0) {
    354485                ddf_msg(LVL_ERROR,
     
    375506}
    376507
     508/** Set AHCI registers for setting SATA device transfer mode.
     509 *
     510 * @param sata SATA device structure.
     511 * @param phys Physical address of working buffer.
     512 * @param mode Required mode.
     513 *
     514 */
    377515static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode)
    378516{
    379         volatile std_command_frame_t *cmd =
    380             (std_command_frame_t *) sata->cmd_table;
    381        
    382         cmd->fis_type = 0x27;
    383         cmd->c = 0x80;
     517        /* Clear interrupt state registers */
     518        ahci_get_and_clear_pxis(sata);
     519        sata->shadow_pxis.u32 = 0;
     520       
     521        volatile sata_std_command_frame_t *cmd =
     522            (sata_std_command_frame_t *) sata->cmd_table;
     523       
     524        cmd->fis_type = SATA_CMD_FIS_TYPE;
     525        cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
    384526        cmd->command = 0xef;
    385527        cmd->features = 0x03;
     
    393535        cmd->reserved2 = 0;
    394536       
    395         volatile ahci_cmd_prdt_t* prdt =
     537        volatile ahci_cmd_prdt_t *prdt =
    396538            (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]);
    397539       
     
    399541        prdt->data_address_upper = HI(phys);
    400542        prdt->reserved1 = 0;
    401         prdt->dbc = 511;
     543        prdt->dbc = SATA_SET_FEATURE_BUFFER_LENGTH - 1;
    402544        prdt->reserved2 = 0;
    403545        prdt->ioc = 0;
    404546       
    405547        sata->cmd_header->prdtl = 1;
    406         sata->cmd_header->flags = 0x402;
     548        sata->cmd_header->flags =
     549            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
     550            AHCI_CMDHDR_FLAGS_2DWCMD;
    407551        sata->cmd_header->bytesprocessed = 0;
    408552       
     553        /* Run command. */
    409554        sata->port->pxsact |= 1;
    410555        sata->port->pxci |= 1;
    411556}
    412557
     558/** Set highest ultra DMA mode supported by SATA device.
     559 *
     560 * @param sata SATA device structure.
     561 *
     562 * @return EOK if succeed, error code otherwise
     563 *
     564 */
    413565static int ahci_set_highest_ultra_dma_mode(sata_dev_t *sata)
    414566{
    415         if (sata->invalid_device) {
     567        if (sata->is_invalid_device) {
    416568                ddf_msg(LVL_ERROR,
    417569                    "%s: Setting highest UDMA mode on invalid device",
     
    420572        }
    421573       
     574        if (sata->highest_udma_mode == (uint8_t) -1) {
     575                ddf_msg(LVL_ERROR,
     576                    "%s: No AHCI UDMA support.", sata->model);
     577                return EINTR;
     578        }
     579       
     580        if (sata->highest_udma_mode > 6) {
     581                ddf_msg(LVL_ERROR,
     582                    "%s: Unknown AHCI UDMA mode.", sata->model);
     583                return EINTR;
     584        }
     585       
    422586        void *phys;
    423         identify_data_t *idata;
    424        
    425         dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
    426             (void **) &idata);
    427         bzero(idata, 512);
     587        sata_identify_data_t *idata;
     588        int rc = dmamem_map_anonymous(SATA_SET_FEATURE_BUFFER_LENGTH,
     589            AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata);
     590        if (rc != EOK) {
     591                ddf_msg(LVL_ERROR, "Cannot allocate buffer for device set mode.");
     592                return rc;
     593        }
     594       
     595        bzero(idata, SATA_SET_FEATURE_BUFFER_LENGTH);
    428596       
    429597        fibril_mutex_lock(&sata->lock);
     
    439607        sata->shadow_pxis.u32 &= ~pxis.u32;
    440608       
    441         if (sata->invalid_device) {
     609        if (sata->is_invalid_device) {
    442610                ddf_msg(LVL_ERROR,
    443611                    "%s: Unrecoverable error during set highest UDMA mode",
     
    464632}
    465633
     634/** Set AHCI registers for reading one sector from the SATA device using FPDMA.
     635 *
     636 * @param sata     SATA device structure.
     637 * @param phys     Physical address of buffer for sector data.
     638 * @param blocknum Block number to read.
     639 *
     640 */
    466641static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
    467642{
    468         volatile ncq_command_frame_t *cmd =
    469             (ncq_command_frame_t *) sata->cmd_table;
    470        
    471         cmd->fis_type = 0x27;
    472         cmd->c = 0x80;
     643        /* Clear interrupt state registers */
     644        ahci_get_and_clear_pxis(sata);
     645        sata->shadow_pxis.u32 = 0;
     646       
     647        volatile sata_ncq_command_frame_t *cmd =
     648            (sata_ncq_command_frame_t *) sata->cmd_table;
     649       
     650        cmd->fis_type = SATA_CMD_FIS_TYPE;
     651        cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
    473652        cmd->command = 0x60;
    474653        cmd->tag = 0;
     
    503682       
    504683        sata->cmd_header->prdtl = 1;
    505         sata->cmd_header->flags = 0x405;
     684        sata->cmd_header->flags =
     685            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
     686            AHCI_CMDHDR_FLAGS_5DWCMD;
    506687        sata->cmd_header->bytesprocessed = 0;
    507688       
     
    510691}
    511692
     693/** Read one sector from the SATA device using FPDMA.
     694 *
     695 * @param sata     SATA device structure.
     696 * @param phys     Physical address of buffer for sector data.
     697 * @param blocknum Block number to read.
     698 *
     699 * @return EOK if succeed, error code otherwise
     700 *
     701 */
    512702static int ahci_rb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum)
    513703{
    514         if (sata->invalid_device) {
     704        if (sata->is_invalid_device) {
    515705                ddf_msg(LVL_ERROR,
    516706                    "%s: FPDMA read from invalid device", sata->model);
     
    527717        sata->shadow_pxis.u32 &= ~pxis.u32;
    528718       
    529         if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
     719        if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
    530720                ddf_msg(LVL_ERROR,
    531721                    "%s: Unrecoverable error during FPDMA read", sata->model);
     
    536726}
    537727
     728/** Set AHCI registers for writing one sector to the SATA device, use FPDMA.
     729 *
     730 * @param sata     SATA device structure.
     731 * @param phys     Physical address of buffer with sector data.
     732 * @param blocknum Block number to write.
     733 *
     734 * @return EOK if succeed, error code otherwise
     735 *
     736 */
    538737static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
    539738{
    540         volatile ncq_command_frame_t *cmd =
    541             (ncq_command_frame_t *) sata->cmd_table;
    542        
    543         cmd->fis_type = 0x27;
    544         cmd->c = 0x80;
     739        /* Clear interrupt state registers */
     740        ahci_get_and_clear_pxis(sata);
     741        sata->shadow_pxis.u32 = 0;
     742       
     743        volatile sata_ncq_command_frame_t * cmd =
     744            (sata_ncq_command_frame_t *) sata->cmd_table;
     745       
     746        cmd->fis_type = SATA_CMD_FIS_TYPE;
     747        cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
    545748        cmd->command = 0x61;
    546749        cmd->tag = 0;
     
    575778       
    576779        sata->cmd_header->prdtl = 1;
    577         sata->cmd_header->flags = 0x445;
     780        sata->cmd_header->flags =
     781            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
     782            AHCI_CMDHDR_FLAGS_WRITE |
     783            AHCI_CMDHDR_FLAGS_5DWCMD;
    578784        sata->cmd_header->bytesprocessed = 0;
    579785       
     
    582788}
    583789
     790/** Write one sector into the SATA device, use FPDMA.
     791 *
     792 * @param sata     SATA device structure.
     793 * @param phys     Physical addres of buffer with sector data.
     794 * @param blocknum Block number to write.
     795 *
     796 * @return EOK if succeed, error code otherwise
     797 *
     798 */
    584799static int ahci_wb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum)
    585800{
    586         if (sata->invalid_device) {
     801        if (sata->is_invalid_device) {
    587802                ddf_msg(LVL_ERROR,
    588803                    "%s: FPDMA write to invalid device", sata->model);
     
    599814        sata->shadow_pxis.u32 &= ~pxis.u32;
    600815       
    601         if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
     816        if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
    602817                ddf_msg(LVL_ERROR,
    603818                    "%s: Unrecoverable error during FPDMA write", sata->model);
     
    658873        is.u32 = ahci->memregs->ghc.is;
    659874        ahci->memregs->ghc.is = is.u32;
    660         is.u32 = ahci->memregs->ghc.is;
     875       
     876        if (!is_timer)
     877                ahci->is_hw_interrupt = true;
     878        else if (is.u32)
     879                ahci->is_hw_interrupt = false;
    661880       
    662881        uint32_t port_event_flags = 0;
    663882        uint32_t port_mask = 1;
    664883        for (unsigned int i = 0; i < 32; i++) {
    665                 /*
    666                  * Get current value of hardware port interrupt state register,
    667                  * clear hardware register (write to clear behavior).
    668                  */
    669                 ahci_port_is_t pxis;
    670                
    671                 pxis.u32 = ahci->memregs->ports[i].pxis;
    672                 ahci->memregs->ports[i].pxis = pxis.u32;
    673                
    674884                sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];
    675885                if (sata != NULL) {
    676                         /* add value to shadow copy of port interrupt state register. */
     886                        ahci_port_is_t pxis = ahci_get_and_clear_pxis(sata);
     887                       
     888                        /* Add value to shadow copy of port interrupt state register. */
    677889                        sata->shadow_pxis.u32 |= pxis.u32;
    678890                       
     
    681893                            (ahci_port_is_error(pxis)))
    682894                                port_event_flags |= port_mask;
    683                        
    684                         if (ahci_port_is_permanent_error(pxis))
    685                                 sata->invalid_device = true;
    686895                }
    687896               
     
    704913/** AHCI timer interrupt handler.
    705914 *
    706  * @param arg Pointer to AHCI device.
     915 * @param arg AHCI device.
    707916 *
    708917 */
     
    712921       
    713922        ahci_interrupt_or_timer(ahci, 1);
    714         fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
     923       
     924        if (ahci->is_hw_interrupt)
     925                fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
     926        else
     927                fibril_timer_set(ahci->timer, AHCI_TIMER_NO_INTR_TICKS,
     928                    ahci_timer, ahci);
    715929}
    716930
    717931/** AHCI interrupt handler.
    718932 *
    719  * @param dev Pointer to device driver handler.
     933 * @param dev   DDF device structure.
     934 * @param iid   The IPC call id.
     935 * @param icall The IPC call structure.
    720936 *
    721937 */
     
    727943       
    728944        /* Enable interrupt. */
    729         ahci->memregs->ghc.ghc |= 2;
     945        ahci->memregs->ghc.ghc |= AHCI_GHC_GHC_IE;
    730946}
    731947
     
    734950/*----------------------------------------------------------------------------*/
    735951
    736 static sata_dev_t *ahci_sata_device_allocate(volatile ahci_port_t *port)
     952/** Allocate SATA device structure with buffers for hardware.
     953 *
     954 * @param port AHCI port structure
     955 *
     956 * @return SATA device structure if succeed, NULL otherwise.
     957 *
     958 */
     959static sata_dev_t *ahci_sata_allocate(volatile ahci_port_t *port)
    737960{
    738961        size_t size = 4096;
     
    763986        rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0,
    764987            &phys, &virt_cmd);
    765        
    766988        if (rc != EOK)
    767989                goto error_cmd;
     
    775997        rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0,
    776998            &phys, &virt_table);
    777        
    778999        if (rc != EOK)
    7791000                goto error_table;
     
    7931014        free(sata);
    7941015        return NULL;
    795        
    796         /*
    797          * Deleting of pointers in memory hardware mapped register
    798          * unneccessary, hardware port is not in operational state.
    799          */
    800 }
    801 
    802 static int ahci_sata_device_create(ahci_dev_t *ahci, ddf_dev_t *dev,
     1016}
     1017
     1018/** Initialize and start SATA hardware device.
     1019 *
     1020 * @param sata SATA device structure.
     1021 *
     1022 */
     1023static void ahci_sata_hw_start(sata_dev_t *sata)
     1024{
     1025        ahci_port_cmd_t pxcmd;
     1026       
     1027        pxcmd.u32 = sata->port->pxcmd;
     1028       
     1029        /* Frame receiver disabled. */
     1030        pxcmd.fre = 0;
     1031       
     1032        /* Disable process the command list. */
     1033        pxcmd.st = 0;
     1034       
     1035        sata->port->pxcmd = pxcmd.u32;
     1036       
     1037        /* Clear interrupt status. */
     1038        sata->port->pxis = 0xffffffff;
     1039       
     1040        /* Clear error status. */
     1041        sata->port->pxserr = 0xffffffff;
     1042       
     1043        /* Enable all interrupts. */
     1044        sata->port->pxie = 0xffffffff;
     1045       
     1046        /* Frame receiver enabled. */
     1047        pxcmd.fre = 1;
     1048       
     1049        /* Enable process the command list. */
     1050        pxcmd.st = 1;
     1051       
     1052        sata->port->pxcmd = pxcmd.u32;
     1053}
     1054
     1055/** Create and initialize connected SATA structure device
     1056 *
     1057 * @param ahci     AHCI device structure.
     1058 * @param dev      DDF device structure.
     1059 * @param port     AHCI port structure.
     1060 * @param port_num Number of AHCI port with existing SATA device.
     1061 *
     1062 * @return EOK if succeed, error code otherwise.
     1063 *
     1064 */
     1065static int ahci_sata_create(ahci_dev_t *ahci, ddf_dev_t *dev,
    8031066    volatile ahci_port_t *port, unsigned int port_num)
    8041067{
    8051068        ddf_fun_t *fun = NULL;
    806         sata_dev_t *sata = ahci_sata_device_allocate(port);
    807        
     1069        sata_dev_t *sata = ahci_sata_allocate(port);
    8081070        if (sata == NULL)
    8091071                return EINTR;
     
    8141076        ahci->sata_devs[port_num] = sata;
    8151077       
     1078        /* Initialize synchronization structures */
    8161079        fibril_mutex_initialize(&sata->lock);
     1080        fibril_mutex_initialize(&sata->pxis_lock);
    8171081        fibril_mutex_initialize(&sata->event_lock);
    8181082        fibril_condvar_initialize(&sata->event_condvar);
    819        
    820         /* Initialize SATA port operational registers. */
    821         sata->port->pxis = 0;
    822         sata->port->pxie = 0xffffffff;
    823         sata->port->pxserr = 0;
    824         sata->port->pxcmd |= 0x10;
    825         sata->port->pxcmd |= 0x01;
    826        
     1083
     1084        ahci_sata_hw_start(sata);
     1085
     1086        /* Identify device. */
    8271087        if (ahci_identify_device(sata) != EOK)
    8281088                goto error;
    8291089       
     1090        /* Set required UDMA mode */
    8301091        if (ahci_set_highest_ultra_dma_mode(sata) != EOK)
    8311092                goto error;
    8321093       
    833         /* Add sata device to system. */
    834         char sata_dev_name[1024];
    835         snprintf(sata_dev_name, 1024, "ahci_%u", sata_devices_count);
     1094        /* Add device to the system */
     1095        char sata_dev_name[16];
     1096        snprintf(sata_dev_name, 16, "ahci_%u", sata_devices_count);
    8361097       
    8371098        fibril_mutex_lock(&sata_devices_count_lock);
     
    8561117       
    8571118error:
    858         sata->invalid_device = true;
     1119        sata->is_invalid_device = true;
    8591120        if (fun != NULL)
    8601121                ddf_fun_destroy(fun);
     
    8631124}
    8641125
     1126/** Create and initialize all SATA structure devices for connected SATA drives.
     1127 *
     1128 * @param ahci AHCI device structure.
     1129 * @param dev  DDF device structure.
     1130 *
     1131 */
    8651132static void ahci_sata_devices_create(ahci_dev_t *ahci, ddf_dev_t *dev)
    8661133{
    867         for (unsigned int port_num = 0; port_num < 32; port_num++) {
     1134        for (unsigned int port_num = 0; port_num < AHCI_MAX_PORTS; port_num++) {
    8681135                /* Active ports only */
    8691136                if (!(ahci->memregs->ghc.pi & (1 << port_num)))
     
    8731140               
    8741141                /* Active devices only */
    875                 if ((port->pxssts & 0x0f) != 3)
     1142                ahci_port_ssts_t pxssts;
     1143                pxssts.u32 = port->pxssts;
     1144                if (pxssts.det != AHCI_PORT_SSTS_DET_ACTIVE)
    8761145                        continue;
    8771146               
    878                 ahci_sata_device_create(ahci, dev, port, port_num);
    879         }
    880 }
    881 
     1147                ahci_sata_create(ahci, dev, port, port_num);
     1148        }
     1149}
     1150
     1151/** Create AHCI device structure, intialize it and register interrupt routine.
     1152 * 
     1153 * @param dev DDF device structure.
     1154 *
     1155 * @return AHCI device structure if succeed, NULL otherwise.
     1156 *
     1157 */
    8821158static ahci_dev_t *ahci_ahci_create(ddf_dev_t *dev)
    8831159{
     
    8891165       
    8901166        ahci->dev = dev;
     1167
     1168        /* Create timer for AHCI. */
     1169        ahci->timer = fibril_timer_create();
     1170        if (ahci->timer == NULL)
     1171                goto error_create_timer;
    8911172       
    8921173        hw_res_list_parsed_t hw_res_parsed;
     
    8951176                goto error_get_res_parsed;
    8961177       
     1178        /* Map AHCI registers. */
     1179        ahci->memregs = NULL;
     1180       
     1181        physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address),
     1182            AHCI_MEMREGS_PAGES_COUNT, AS_AREA_READ | AS_AREA_WRITE,
     1183            (void **) &ahci->memregs);
     1184        if (ahci->memregs == NULL)
     1185                goto error_map_registers;
     1186       
    8971187        /* Register interrupt handler */
    8981188        ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address;
    8991189        ahci_ranges[0].size = sizeof(ahci_dev_t);
     1190       
    9001191        ahci_cmds[0].addr =
    901             ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1;
     1192            ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
     1193            AHCI_GHC_GHC_REGISTER_OFFSET;
    9021194        ahci_cmds[1].addr =
    903             ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 2;
     1195            ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
     1196            AHCI_GHC_IS_REGISTER_OFFSET;
    9041197        ahci_cmds[2].addr = ahci_cmds[1].addr;
    9051198       
    9061199        irq_code_t ct;
    907         ct.cmdcount = 3;
     1200        ct.cmdcount = sizeof(ahci_cmds) / sizeof(irq_cmd_t);
    9081201        ct.cmds = ahci_cmds;
    909         ct.rangecount = 1;
     1202        ct.rangecount = sizeof(ahci_ranges) / sizeof(irq_pio_range_t);
    9101203        ct.ranges = ahci_ranges;
    9111204       
     
    9181211        }
    9191212       
    920         if (ahci_pciintel_enable_interrupt(hw_res_parsed.irqs.irqs[0]) != EOK) {
     1213        rc = ahci_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
     1214        if (rc != EOK) {
    9211215                ddf_msg(LVL_ERROR, "Failed enable interupt.");
    9221216                goto error_enable_interrupt;
    9231217        }
    9241218       
    925         /* Map AHCI register. */
    926         physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address),
    927             8, AS_AREA_READ | AS_AREA_WRITE, (void **) &ahci->memregs);
    9281219        hw_res_list_parsed_clean(&hw_res_parsed);
    929        
    930         if (ahci->memregs == NULL)
    931                 goto error_map_registers;
    932        
    933         ahci->timer = fibril_timer_create();
    934        
    9351220        return ahci;
    9361221       
     1222error_enable_interrupt:
     1223        unregister_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0]);
     1224       
     1225error_register_interrupt_handler:
     1226        // FIXME: unmap physical memory
     1227       
    9371228error_map_registers:
    938 error_enable_interrupt:
    939 error_register_interrupt_handler:
    9401229        hw_res_list_parsed_clean(&hw_res_parsed);
     1230       
    9411231error_get_res_parsed:
     1232        fibril_timer_destroy(ahci->timer);
     1233       
     1234error_create_timer:
     1235        free(ahci);
    9421236        return NULL;
    9431237}
    9441238
    945 static void ahci_ahci_init(ahci_dev_t *ahci)
    946 {
    947         /* Enable interrupt and bus mastering */
     1239/** Initialize and start AHCI hardware device.
     1240 *
     1241 * @param ahci AHCI device.
     1242 *
     1243 */
     1244static void ahci_ahci_hw_start(ahci_dev_t *ahci)
     1245{
     1246        /* Disable command completion coalescing feature */
     1247        ahci_ghc_ccc_ctl_t ccc;
     1248       
     1249        ccc.u32 = ahci->memregs->ghc.ccc_ctl;
     1250        ccc.en = 0;
     1251        ahci->memregs->ghc.ccc_ctl = ccc.u32;   
     1252       
     1253        /* Set master latency timer. */
     1254        pci_config_space_write_8(ahci->dev->parent_sess, AHCI_PCI_MLT, 32);
     1255       
     1256        /* Enable PCI interrupt and bus mastering */
    9481257        ahci_pcireg_cmd_t cmd;
    9491258       
     
    9531262        pci_config_space_write_16(ahci->dev->parent_sess, AHCI_PCI_CMD, cmd.u16);
    9541263       
    955         /* Set master latency timer */
    956         pci_config_space_write_8(ahci->dev->parent_sess, AHCI_PCI_MLT, 32);
    957        
    958         /* Disable command completion coalescing feature. */
    959         ahci_ghc_ccc_ctl_t ccc;
    960         ccc.u32 = ahci->memregs->ghc.ccc_ctl;
    961         ccc.en = 0;
    962         ahci->memregs->ghc.ccc_ctl = ccc.u32;
    963        
    9641264        /* Enable AHCI and interrupt. */
    9651265        ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE;
    966        
    967         /* Enable timer. */
    968         fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
    969 }
    970 
     1266}
     1267
     1268/** AHCI device driver initialization
     1269 *
     1270 * Create and initialize all SATA structure devices for connected
     1271 * SATA drives.
     1272 *
     1273 * @param dev DDF device structure.
     1274 *
     1275 * @return EOK if succeed, error code otherwise.
     1276 *
     1277 */
    9711278static int ahci_dev_add(ddf_dev_t *dev)
    9721279{
     1280        /* Connect to parent device */
    9731281        dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
    9741282            dev->handle, IPC_FLAG_BLOCKING);
     
    9781286        ahci_dev_t *ahci = ahci_ahci_create(dev);
    9791287        if (ahci == NULL)
    980                 return EINTR;
     1288                goto error;
    9811289       
    9821290        dev->driver_data = ahci;
    983         ahci_ahci_init(ahci);
     1291       
     1292        /* Set timer and AHCI hardware start. */
     1293        fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
     1294        ahci_ahci_hw_start(ahci);
     1295       
     1296        /* Create device structures for sata devices attached to AHCI. */
    9841297        ahci_sata_devices_create(ahci, dev);
    9851298       
    9861299        return EOK;
     1300       
     1301error:
     1302        async_hangup(dev->parent_sess);
     1303        return EINTR;
    9871304}
    9881305
     
    9911308/*----------------------------------------------------------------------------*/
    9921309
     1310/** Convert SATA model name
     1311 *
     1312 * Convert SATA model name from machine format returned by
     1313 * identify device command to human readable form.
     1314 *
     1315 * @param src Source buffer with device name in machine format.
     1316 * @param dst Buffer for human readable string, minimum size is 41 chars.
     1317 *
     1318 */
    9931319static void ahci_get_model_name(uint16_t *src, char *dst)
    9941320{
     
    10181344}
    10191345
    1020 static int ahci_pciintel_enable_interrupt(int irq)
     1346/** Enable interrupt using SERVICE_IRC.
     1347 *
     1348 * @param irq Requested irq number.
     1349 *
     1350 * @return EOK if succeed, error code otherwise.
     1351 *
     1352 */
     1353static int ahci_enable_interrupt(int irq)
    10211354{
    10221355        async_sess_t *irc_sess = NULL;
    10231356        irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_IRC, 0, 0);
    1024        
    10251357        if (!irc_sess)
    10261358                return EINTR;
Note: See TracChangeset for help on using the changeset viewer.