Ignore:
File:
1 edited

Legend:

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

    r267f235 r730dce77  
    3434#include <errno.h>
    3535#include <stdio.h>
     36#include <devman.h>
    3637#include <ddf/interrupt.h>
    3738#include <ddf/log.h>
     
    4849#define NAME  "ahci"
    4950
     51#define AHCI_TIMER_TICKS  1000000000
     52
    5053#define LO(ptr) \
    5154        ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
     
    5356#define HI(ptr) \
    5457        ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32))
    55 
    56 /** Interrupt pseudocode for a single port
    57  *
    58  * The interrupt handling works as follows:
    59  *
    60  * 1. Port interrupt status register is read
    61  *    (stored as arg2).
    62  * 2. If port interrupt is indicated, then:
    63  *    3. Port interrupt status register is cleared.
    64  *    4. Global interrupt status register is read
    65  *       and cleared (any potential interrupts from
    66  *       other ports are reasserted automatically).
    67  *    5. Port number is stored as arg1.
    68  *    6. The interrupt is accepted.
    69  *
    70  */
    71 #define AHCI_PORT_CMDS(port) \
    72         { \
    73                 /* Read port interrupt status register */ \
    74                 .cmd = CMD_PIO_READ_32, \
    75                 .addr = NULL, \
    76                 .dstarg = 2 \
    77         }, \
    78         { \
    79                 /* Check if port asserted interrupt */ \
    80                 .cmd = CMD_PREDICATE, \
    81                 .value = 5, \
    82                 .srcarg = 2, \
    83         }, \
    84         { \
    85                 /* Clear port interrupt status register */ \
    86                 .cmd = CMD_PIO_WRITE_A_32, \
    87                 .addr = NULL, \
    88                 .srcarg = 2 \
    89         }, \
    90         { \
    91                 /* Read global interrupt status register */ \
    92                 .cmd = CMD_PIO_READ_32, \
    93                 .addr = NULL, \
    94                 .dstarg = 0 \
    95         }, \
    96         { \
    97                 /* Clear global interrupt status register */ \
    98                 .cmd = CMD_PIO_WRITE_A_32, \
    99                 .addr = NULL, \
    100                 .srcarg = 0 \
    101         }, \
    102         { \
    103                 /* Indicate port interrupt assertion */ \
    104                 .cmd = CMD_LOAD, \
    105                 .value = (port), \
    106                 .dstarg = 1 \
    107         }, \
    108         { \
    109                 /* Accept the interrupt */ \
    110                 .cmd = CMD_ACCEPT \
    111         }
    11258
    11359static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *);
     
    12470static void ahci_sata_devices_create(ahci_dev_t *, ddf_dev_t *);
    12571static ahci_dev_t *ahci_ahci_create(ddf_dev_t *);
    126 static void ahci_ahci_hw_start(ahci_dev_t *);
     72static void ahci_ahci_init(ahci_dev_t *);
    12773
    12874static int ahci_dev_add(ddf_dev_t *);
    12975
    13076static void ahci_get_model_name(uint16_t *, char *);
    131 static int ahci_enable_interrupt(int);
     77static int ahci_pciintel_enable_interrupt(int);
    13278
    13379static fibril_mutex_t sata_devices_count_lock;
     
    159105};
    160106
    161 /** Get SATA structure from DDF function. */
    162 static sata_dev_t *fun_sata_dev(ddf_fun_t *fun)
    163 {
    164         return ddf_fun_data_get(fun);
    165 }
    166 
    167 /** Get AHCI structure from DDF device. */
    168 static ahci_dev_t *dev_ahci_dev(ddf_dev_t *dev)
    169 {
    170         return ddf_dev_data_get(dev);
    171 }
    172 
    173 /** Get SATA device name.
    174  *
    175  * @param fun                  Device function handling the call.
    176  * @param sata_dev_name_length Length of the sata_dev_name buffer.
    177  * @param sata_dev_name        Buffer for SATA device name.
    178  *
    179  * @return EOK.
    180  *
    181  */
    182107static int ahci_get_sata_device_name(ddf_fun_t *fun,
    183108    size_t sata_dev_name_length, char *sata_dev_name)
    184109{
    185         sata_dev_t *sata = fun_sata_dev(fun);
     110        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    186111        str_cpy(sata_dev_name, sata_dev_name_length, sata->model);
    187112        return EOK;
    188113}
    189114
    190 /** Get Number of blocks in SATA device.
    191  *
    192  * @param fun    Device function handling the call.
    193  * @param blocks Return number of blocks in SATA device.
    194  *
    195  * @return EOK.
    196  *
    197  */
    198115static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
    199116{
    200         sata_dev_t *sata = fun_sata_dev(fun);
     117        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    201118        *num_blocks = sata->blocks;
    202119        return EOK;
    203120}
    204121
    205 /** Get SATA device block size.
    206  *
    207  * @param fun        Device function handling the call.
    208  * @param block_size Return block size.
    209  *
    210  * @return EOK.
    211  *
    212  */
    213122static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size)
    214123{
    215         sata_dev_t *sata = fun_sata_dev(fun);
     124        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    216125        *block_size = sata->block_size;
    217126        return EOK;
    218127}
    219128
    220 /** Read data blocks into SATA device.
    221  *
    222  * @param fun      Device function handling the call.
    223  * @param blocknum Number of first block.
    224  * @param count    Number of blocks to read.
    225  * @param buf      Buffer for data.
    226  *
    227  * @return EOK if succeed, error code otherwise
    228  *
    229  */
    230129static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum,
    231130    size_t count, void *buf)
    232131{
    233         sata_dev_t *sata = fun_sata_dev(fun);
     132        int rc = EOK;
     133        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    234134       
    235135        void *phys;
    236136        void *ibuf;
    237         int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
     137       
     138        dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
    238139            0, &phys, (void **) &ibuf);
    239         if (rc != EOK) {
    240                 ddf_msg(LVL_ERROR, "Cannot allocate read buffer.");
    241                 return rc;
    242         }
    243        
    244140        bzero(buf, sata->block_size);
    245141       
     
    261157}
    262158
    263 /** Write data blocks into SATA device.
    264  *
    265  * @param fun      Device function handling the call.
    266  * @param blocknum Number of first block.
    267  * @param count    Number of blocks to write.
    268  * @param buf      Buffer with data.
    269  *
    270  * @return EOK if succeed, error code otherwise
    271  *
    272  */
    273159static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum,
    274160    size_t count, void *buf)
    275161{
    276         sata_dev_t *sata = fun_sata_dev(fun);
     162        int rc = EOK;
     163        sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
    277164       
    278165        void *phys;
    279166        void *ibuf;
    280         int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
     167       
     168        dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
    281169            0, &phys, (void **) &ibuf);
    282         if (rc != EOK) {
    283                 ddf_msg(LVL_ERROR, "Cannot allocate write buffer.");
    284                 return rc;
    285         }
    286170       
    287171        fibril_mutex_lock(&sata->lock);
     
    297181        fibril_mutex_unlock(&sata->lock);
    298182        dmamem_unmap_anonymous(ibuf);
    299        
    300183        return rc;
    301184}
     
    305188/*----------------------------------------------------------------------------*/
    306189
    307 /** Wait for interrupt event.
    308  *
    309  * @param sata SATA device structure.
    310  *
    311  * @return Value of interrupt state register.
    312  *
    313  */
    314 static ahci_port_is_t ahci_wait_event(sata_dev_t *sata)
    315 {
    316         fibril_mutex_lock(&sata->event_lock);
    317        
    318         sata->event_pxis = 0;
    319         while (sata->event_pxis == 0)
    320                 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
    321        
    322         ahci_port_is_t pxis = sata->event_pxis;
    323        
    324         if (ahci_port_is_permanent_error(pxis))
    325                 sata->is_invalid_device = true;
    326        
    327         fibril_mutex_unlock(&sata->event_lock);
    328        
    329         return pxis;
    330 }
    331 
    332 /** Set AHCI registers for identifying SATA device.
    333  *
    334  * @param sata SATA device structure.
    335  * @param phys Physical address of working buffer.
    336  *
    337  */
    338190static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys)
    339191{
    340         volatile sata_std_command_frame_t *cmd =
    341             (sata_std_command_frame_t *) sata->cmd_table;
    342        
    343         cmd->fis_type = SATA_CMD_FIS_TYPE;
    344         cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
     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;
    345197        cmd->command = 0xec;
    346198        cmd->features = 0;
     
    360212        prdt->data_address_upper = HI(phys);
    361213        prdt->reserved1 = 0;
    362         prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1;
     214        prdt->dbc = 511;
    363215        prdt->reserved2 = 0;
    364216        prdt->ioc = 0;
    365217       
    366218        sata->cmd_header->prdtl = 1;
    367         sata->cmd_header->flags =
    368             AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    369             AHCI_CMDHDR_FLAGS_2DWCMD;
     219        sata->cmd_header->flags = 0x402;
    370220        sata->cmd_header->bytesprocessed = 0;
    371221       
    372         /* Run command. */
    373222        sata->port->pxsact |= 1;
    374223        sata->port->pxci |= 1;
    375224}
    376225
    377 /** Set AHCI registers for identifying packet SATA device.
    378  *
    379  * @param sata SATA device structure.
    380  * @param phys Physical address of working buffer.
    381  *
    382  */
    383226static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys)
    384227{
    385         volatile sata_std_command_frame_t *cmd =
    386             (sata_std_command_frame_t *) sata->cmd_table;
    387        
    388         cmd->fis_type = SATA_CMD_FIS_TYPE;
    389         cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
     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;
    390233        cmd->command = 0xa1;
    391234        cmd->features = 0;
     
    405248        prdt->data_address_upper = HI(phys);
    406249        prdt->reserved1 = 0;
    407         prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1;
     250        prdt->dbc = 511;
    408251        prdt->reserved2 = 0;
    409252        prdt->ioc = 0;
    410253       
    411254        sata->cmd_header->prdtl = 1;
    412         sata->cmd_header->flags =
    413             AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    414             AHCI_CMDHDR_FLAGS_2DWCMD;
     255        sata->cmd_header->flags = 0x402;
    415256        sata->cmd_header->bytesprocessed = 0;
    416257       
    417         /* Run command. */
    418258        sata->port->pxsact |= 1;
    419259        sata->port->pxci |= 1;
    420260}
    421261
    422 /** Fill device identification in SATA device structure.
    423  *
    424  * @param sata SATA device structure.
    425  *
    426  * @return EOK if succeed, error code otherwise.
    427  *
    428  */
    429262static int ahci_identify_device(sata_dev_t *sata)
    430263{
    431         if (sata->is_invalid_device) {
     264        if (sata->invalid_device) {
    432265                ddf_msg(LVL_ERROR,
    433266                    "Identify command device on invalid device");
     
    436269       
    437270        void *phys;
    438         sata_identify_data_t *idata;
    439         int rc = dmamem_map_anonymous(SATA_IDENTIFY_DEVICE_BUFFER_LENGTH,
    440             AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata);
    441         if (rc != EOK) {
    442                 ddf_msg(LVL_ERROR, "Cannot allocate buffer to identify device.");
    443                 return rc;
    444         }
    445        
    446         bzero(idata, SATA_IDENTIFY_DEVICE_BUFFER_LENGTH);
     271        identify_data_t *idata;
     272       
     273        dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
     274            (void **) &idata);
     275        bzero(idata, 512);
    447276       
    448277        fibril_mutex_lock(&sata->lock);
    449278       
    450279        ahci_identify_device_cmd(sata, phys);
    451         ahci_port_is_t pxis = ahci_wait_event(sata);
    452        
    453         if (sata->is_invalid_device) {
     280       
     281        fibril_mutex_lock(&sata->event_lock);
     282        fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
     283        fibril_mutex_unlock(&sata->event_lock);
     284       
     285        ahci_port_is_t pxis = sata->shadow_pxis;
     286        sata->shadow_pxis.u32 &= ~pxis.u32;
     287       
     288        if (sata->invalid_device) {
    454289                ddf_msg(LVL_ERROR,
    455290                    "Unrecoverable error during ata identify device");
     
    459294        if (ahci_port_is_tfes(pxis)) {
    460295                ahci_identify_packet_device_cmd(sata, phys);
    461                 pxis = ahci_wait_event(sata);
    462                
    463                 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
     296               
     297                fibril_mutex_lock(&sata->event_lock);
     298                fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
     299                fibril_mutex_unlock(&sata->event_lock);
     300               
     301                pxis = sata->shadow_pxis;
     302                sata->shadow_pxis.u32 &= ~pxis.u32;
     303               
     304                if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
    464305                        ddf_msg(LVL_ERROR,
    465306                            "Unrecoverable error during ata identify packet device");
     
    467308                }
    468309               
    469                 sata->is_packet_device = true;
    470         }
     310                sata->packet_device = true;
     311        } else
     312                sata->packet_device = false;
    471313       
    472314        ahci_get_model_name(idata->model_name, sata->model);
     
    476318         * only NCQ FPDMA mode is supported.
    477319         */
    478         if ((idata->sata_cap & sata_np_cap_ncq) == 0) {
     320        if ((idata->sata_cap & np_cap_ncq) == 0) {
    479321                ddf_msg(LVL_ERROR, "%s: NCQ must be supported", sata->model);
    480322                goto error;
    481323        }
    482324       
    483         uint16_t logsec = idata->physical_logic_sector_size;
    484         if ((logsec & 0xc000) == 0x4000) {
    485                 /* Length of sector may be larger than 512 B */
    486                 if (logsec & 0x0100) {
    487                         /* Size of sector is larger than 512 B */
    488                         ddf_msg(LVL_ERROR,
    489                             "%s: Sector length other than 512 B not supported",
    490                             sata->model);
    491                         goto error;
    492                 }
    493                
    494                 if ((logsec & 0x0200) && ((logsec & 0x000f) != 0)) {
    495                         /* Physical sectors per logical sector is greather than 1 */
    496                         ddf_msg(LVL_ERROR,
    497                             "%s: Sector length other than 512 B not supported",
    498                             sata->model);
    499                         goto error;
    500                 }
    501         }
    502        
    503         if (sata->is_packet_device) {
     325        if (sata->packet_device) {
    504326                /*
    505327                 * Due to QEMU limitation (as of 2012-06-22),
    506                  * only NCQ FPDMA mode supported - block size is
    507                  * 512 B, not 2048 B!
     328                 * only NCQ FPDMA mode supported - block size is 512 B,
     329                 * not 2048 B!
    508330                 */
    509                 sata->block_size = SATA_DEFAULT_SECTOR_SIZE;
     331                sata->block_size = 512;
    510332                sata->blocks = 0;
    511333        } else {
    512                 sata->block_size = SATA_DEFAULT_SECTOR_SIZE;
    513                
    514                 if ((idata->caps & sata_rd_cap_lba) == 0) {
     334                sata->block_size = 512;
     335               
     336                if ((idata->caps & rd_cap_lba) == 0) {
    515337                        ddf_msg(LVL_ERROR, "%s: LBA for NCQ must be supported",
    516338                            sata->model);
    517339                        goto error;
    518                 } else if ((idata->cmd_set1 & sata_cs1_addr48) == 0) {
     340                } else if ((idata->cmd_set1 & cs1_addr48) == 0) {
    519341                        sata->blocks = (uint32_t) idata->total_lba28_0 |
    520342                            ((uint32_t) idata->total_lba28_1 << 16);
     
    529351       
    530352        uint8_t udma_mask = idata->udma & 0x007f;
    531         sata->highest_udma_mode = (uint8_t) -1;
    532353        if (udma_mask == 0) {
    533354                ddf_msg(LVL_ERROR,
     
    536357                goto error;
    537358        } else {
    538                 for (uint8_t i = 0; i < 7; i++) {
     359                for (unsigned int i = 0; i < 7; i++) {
    539360                        if (udma_mask & (1 << i))
    540361                                sata->highest_udma_mode = i;
     
    554375}
    555376
    556 /** Set AHCI registers for setting SATA device transfer mode.
    557  *
    558  * @param sata SATA device structure.
    559  * @param phys Physical address of working buffer.
    560  * @param mode Required mode.
    561  *
    562  */
    563377static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode)
    564378{
    565         volatile sata_std_command_frame_t *cmd =
    566             (sata_std_command_frame_t *) sata->cmd_table;
    567        
    568         cmd->fis_type = SATA_CMD_FIS_TYPE;
    569         cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
     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;
    570384        cmd->command = 0xef;
    571385        cmd->features = 0x03;
     
    579393        cmd->reserved2 = 0;
    580394       
    581         volatile ahci_cmd_prdt_t *prdt =
     395        volatile ahci_cmd_prdt_t* prdt =
    582396            (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]);
    583397       
     
    585399        prdt->data_address_upper = HI(phys);
    586400        prdt->reserved1 = 0;
    587         prdt->dbc = SATA_SET_FEATURE_BUFFER_LENGTH - 1;
     401        prdt->dbc = 511;
    588402        prdt->reserved2 = 0;
    589403        prdt->ioc = 0;
    590404       
    591405        sata->cmd_header->prdtl = 1;
    592         sata->cmd_header->flags =
    593             AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    594             AHCI_CMDHDR_FLAGS_2DWCMD;
     406        sata->cmd_header->flags = 0x402;
    595407        sata->cmd_header->bytesprocessed = 0;
    596408       
    597         /* Run command. */
    598409        sata->port->pxsact |= 1;
    599410        sata->port->pxci |= 1;
    600411}
    601412
    602 /** Set highest ultra DMA mode supported by SATA device.
    603  *
    604  * @param sata SATA device structure.
    605  *
    606  * @return EOK if succeed, error code otherwise
    607  *
    608  */
    609413static int ahci_set_highest_ultra_dma_mode(sata_dev_t *sata)
    610414{
    611         if (sata->is_invalid_device) {
     415        if (sata->invalid_device) {
    612416                ddf_msg(LVL_ERROR,
    613417                    "%s: Setting highest UDMA mode on invalid device",
     
    616420        }
    617421       
    618         if (sata->highest_udma_mode == (uint8_t) -1) {
    619                 ddf_msg(LVL_ERROR,
    620                     "%s: No AHCI UDMA support.", sata->model);
    621                 return EINTR;
    622         }
    623        
    624         if (sata->highest_udma_mode > 6) {
    625                 ddf_msg(LVL_ERROR,
    626                     "%s: Unknown AHCI UDMA mode.", sata->model);
    627                 return EINTR;
    628         }
    629        
    630422        void *phys;
    631         sata_identify_data_t *idata;
    632         int rc = dmamem_map_anonymous(SATA_SET_FEATURE_BUFFER_LENGTH,
    633             AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata);
    634         if (rc != EOK) {
    635                 ddf_msg(LVL_ERROR, "Cannot allocate buffer for device set mode.");
    636                 return rc;
    637         }
    638        
    639         bzero(idata, SATA_SET_FEATURE_BUFFER_LENGTH);
     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);
    640428       
    641429        fibril_mutex_lock(&sata->lock);
     
    643431        uint8_t mode = 0x40 | (sata->highest_udma_mode & 0x07);
    644432        ahci_set_mode_cmd(sata, phys, mode);
    645         ahci_port_is_t pxis = ahci_wait_event(sata);
    646        
    647         if (sata->is_invalid_device) {
     433       
     434        fibril_mutex_lock(&sata->event_lock);
     435        fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
     436        fibril_mutex_unlock(&sata->event_lock);
     437       
     438        ahci_port_is_t pxis = sata->shadow_pxis;
     439        sata->shadow_pxis.u32 &= ~pxis.u32;
     440       
     441        if (sata->invalid_device) {
    648442                ddf_msg(LVL_ERROR,
    649443                    "%s: Unrecoverable error during set highest UDMA mode",
     
    670464}
    671465
    672 /** Set AHCI registers for reading one sector from the SATA device using FPDMA.
    673  *
    674  * @param sata     SATA device structure.
    675  * @param phys     Physical address of buffer for sector data.
    676  * @param blocknum Block number to read.
    677  *
    678  */
    679466static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
    680467{
    681         volatile sata_ncq_command_frame_t *cmd =
    682             (sata_ncq_command_frame_t *) sata->cmd_table;
    683        
    684         cmd->fis_type = SATA_CMD_FIS_TYPE;
    685         cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
     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;
    686473        cmd->command = 0x60;
    687474        cmd->tag = 0;
     
    716503       
    717504        sata->cmd_header->prdtl = 1;
    718         sata->cmd_header->flags =
    719             AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    720             AHCI_CMDHDR_FLAGS_5DWCMD;
     505        sata->cmd_header->flags = 0x405;
    721506        sata->cmd_header->bytesprocessed = 0;
    722507       
     
    725510}
    726511
    727 /** Read one sector from the SATA device using FPDMA.
    728  *
    729  * @param sata     SATA device structure.
    730  * @param phys     Physical address of buffer for sector data.
    731  * @param blocknum Block number to read.
    732  *
    733  * @return EOK if succeed, error code otherwise
    734  *
    735  */
    736512static int ahci_rb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum)
    737513{
    738         if (sata->is_invalid_device) {
     514        if (sata->invalid_device) {
    739515                ddf_msg(LVL_ERROR,
    740516                    "%s: FPDMA read from invalid device", sata->model);
     
    743519       
    744520        ahci_rb_fpdma_cmd(sata, phys, blocknum);
    745         ahci_port_is_t pxis = ahci_wait_event(sata);
    746        
    747         if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
     521       
     522        fibril_mutex_lock(&sata->event_lock);
     523        fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
     524        fibril_mutex_unlock(&sata->event_lock);
     525       
     526        ahci_port_is_t pxis = sata->shadow_pxis;
     527        sata->shadow_pxis.u32 &= ~pxis.u32;
     528       
     529        if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
    748530                ddf_msg(LVL_ERROR,
    749531                    "%s: Unrecoverable error during FPDMA read", sata->model);
     
    754536}
    755537
    756 /** Set AHCI registers for writing one sector to the SATA device, use FPDMA.
    757  *
    758  * @param sata     SATA device structure.
    759  * @param phys     Physical address of buffer with sector data.
    760  * @param blocknum Block number to write.
    761  *
    762  * @return EOK if succeed, error code otherwise
    763  *
    764  */
    765538static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
    766539{
    767         volatile sata_ncq_command_frame_t *cmd =
    768             (sata_ncq_command_frame_t *) sata->cmd_table;
    769        
    770         cmd->fis_type = SATA_CMD_FIS_TYPE;
    771         cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
     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;
    772545        cmd->command = 0x61;
    773546        cmd->tag = 0;
     
    791564        cmd->lba5 = (blocknum >> 40) & 0xff;
    792565       
    793         volatile ahci_cmd_prdt_t *prdt =
     566        volatile ahci_cmd_prdt_t * prdt =
    794567            (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]);
    795568       
     
    802575       
    803576        sata->cmd_header->prdtl = 1;
    804         sata->cmd_header->flags =
    805             AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    806             AHCI_CMDHDR_FLAGS_WRITE |
    807             AHCI_CMDHDR_FLAGS_5DWCMD;
     577        sata->cmd_header->flags = 0x445;
    808578        sata->cmd_header->bytesprocessed = 0;
    809579       
     
    812582}
    813583
    814 /** Write one sector into the SATA device, use FPDMA.
    815  *
    816  * @param sata     SATA device structure.
    817  * @param phys     Physical addres of buffer with sector data.
    818  * @param blocknum Block number to write.
    819  *
    820  * @return EOK if succeed, error code otherwise
    821  *
    822  */
    823584static int ahci_wb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum)
    824585{
    825         if (sata->is_invalid_device) {
     586        if (sata->invalid_device) {
    826587                ddf_msg(LVL_ERROR,
    827588                    "%s: FPDMA write to invalid device", sata->model);
     
    830591       
    831592        ahci_wb_fpdma_cmd(sata, phys, blocknum);
    832         ahci_port_is_t pxis = ahci_wait_event(sata);
    833        
    834         if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
     593       
     594        fibril_mutex_lock(&sata->event_lock);
     595        fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
     596        fibril_mutex_unlock(&sata->event_lock);
     597       
     598        ahci_port_is_t pxis = sata->shadow_pxis;
     599        sata->shadow_pxis.u32 &= ~pxis.u32;
     600       
     601        if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
    835602                ddf_msg(LVL_ERROR,
    836603                    "%s: Unrecoverable error during FPDMA write", sata->model);
     
    842609
    843610/*----------------------------------------------------------------------------*/
    844 /*-- Interrupts handling -----------------------------------------------------*/
     611/*-- Interrupts and timer unified handling -----------------------------------*/
    845612/*----------------------------------------------------------------------------*/
    846613
     
    848615        {
    849616                .base = 0,
    850                 .size = 0,
     617                .size = 32,
    851618        }
    852619};
    853620
    854621static irq_cmd_t ahci_cmds[] = {
    855         AHCI_PORT_CMDS(0),
    856         AHCI_PORT_CMDS(1),
    857         AHCI_PORT_CMDS(2),
    858         AHCI_PORT_CMDS(3),
    859         AHCI_PORT_CMDS(4),
    860         AHCI_PORT_CMDS(5),
    861         AHCI_PORT_CMDS(6),
    862         AHCI_PORT_CMDS(7),
    863         AHCI_PORT_CMDS(8),
    864         AHCI_PORT_CMDS(9),
    865         AHCI_PORT_CMDS(10),
    866         AHCI_PORT_CMDS(11),
    867         AHCI_PORT_CMDS(12),
    868         AHCI_PORT_CMDS(13),
    869         AHCI_PORT_CMDS(14),
    870         AHCI_PORT_CMDS(15),
    871         AHCI_PORT_CMDS(16),
    872         AHCI_PORT_CMDS(17),
    873         AHCI_PORT_CMDS(18),
    874         AHCI_PORT_CMDS(19),
    875         AHCI_PORT_CMDS(20),
    876         AHCI_PORT_CMDS(21),
    877         AHCI_PORT_CMDS(22),
    878         AHCI_PORT_CMDS(23),
    879         AHCI_PORT_CMDS(24),
    880         AHCI_PORT_CMDS(25),
    881         AHCI_PORT_CMDS(26),
    882         AHCI_PORT_CMDS(27),
    883         AHCI_PORT_CMDS(28),
    884         AHCI_PORT_CMDS(29),
    885         AHCI_PORT_CMDS(30),
    886         AHCI_PORT_CMDS(31)
     622        {
     623                /* Disable interrupt - interrupt is deasserted in qemu 1.0.1 */
     624                .cmd = CMD_PIO_WRITE_32,
     625                .addr = NULL,
     626                .value = AHCI_GHC_GHC_AE
     627        },
     628        {
     629                .cmd = CMD_PIO_READ_32,
     630                .addr = NULL,
     631                .dstarg = 1
     632        },
     633        {
     634                /* Clear interrupt status register - for vbox and real hw */
     635                .cmd = CMD_PIO_WRITE_A_32,
     636                .addr = NULL,
     637                .srcarg = 1
     638        },
     639        {
     640                .cmd = CMD_ACCEPT
     641        }
    887642};
     643
     644/** Unified AHCI interrupt and timer interrupt handler.
     645 *
     646 * @param ahci     AHCI device.
     647 * @param is_timer Indicate timer interrupt.
     648 *
     649 */
     650static void ahci_interrupt_or_timer(ahci_dev_t *ahci, bool is_timer)
     651{
     652        /*
     653         * Get current value of hardware interrupt state register,
     654         * clear hardware register (write to clear behavior).
     655         */
     656        ahci_ghc_is_t is;
     657       
     658        is.u32 = ahci->memregs->ghc.is;
     659        ahci->memregs->ghc.is = is.u32;
     660        is.u32 = ahci->memregs->ghc.is;
     661       
     662        uint32_t port_event_flags = 0;
     663        uint32_t port_mask = 1;
     664        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               
     674                sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];
     675                if (sata != NULL) {
     676                        /* add value to shadow copy of port interrupt state register. */
     677                        sata->shadow_pxis.u32 |= pxis.u32;
     678                       
     679                        /* Evaluate port event. */
     680                        if ((ahci_port_is_end_of_operation(pxis)) ||
     681                            (ahci_port_is_error(pxis)))
     682                                port_event_flags |= port_mask;
     683                       
     684                        if (ahci_port_is_permanent_error(pxis))
     685                                sata->invalid_device = true;
     686                }
     687               
     688                port_mask <<= 1;
     689        }
     690       
     691        port_mask = 1;
     692        for (unsigned int i = 0; i < 32; i++) {
     693                sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];
     694                if ((port_event_flags & port_mask) && (sata != NULL)) {
     695                        fibril_mutex_lock(&sata->event_lock);
     696                        fibril_condvar_signal(&sata->event_condvar);
     697                        fibril_mutex_unlock(&sata->event_lock);
     698                }
     699               
     700                port_mask <<= 1;
     701        }
     702}
     703
     704/** AHCI timer interrupt handler.
     705 *
     706 * @param arg Pointer to AHCI device.
     707 *
     708 */
     709static void ahci_timer(void *arg)
     710{
     711        ahci_dev_t *ahci = (ahci_dev_t *) arg;
     712       
     713        ahci_interrupt_or_timer(ahci, 1);
     714        fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
     715}
    888716
    889717/** AHCI interrupt handler.
    890718 *
    891  * @param dev   DDF device structure.
    892  * @param iid   The IPC call id.
    893  * @param icall The IPC call structure.
     719 * @param dev Pointer to device driver handler.
    894720 *
    895721 */
    896722static void ahci_interrupt(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *icall)
    897723{
    898         ahci_dev_t *ahci = dev_ahci_dev(dev);
    899         unsigned int port = IPC_GET_ARG1(*icall);
    900         ahci_port_is_t pxis = IPC_GET_ARG2(*icall);
    901        
    902         if (port >= AHCI_MAX_PORTS)
    903                 return;
    904        
    905         sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[port];
    906         if (sata == NULL)
    907                 return;
    908        
    909         /* Evaluate port event */
    910         if ((ahci_port_is_end_of_operation(pxis)) ||
    911             (ahci_port_is_error(pxis))) {
    912                 fibril_mutex_lock(&sata->event_lock);
    913                
    914                 sata->event_pxis = pxis;
    915                 fibril_condvar_signal(&sata->event_condvar);
    916                
    917                 fibril_mutex_unlock(&sata->event_lock);
    918         }
     724        ahci_dev_t *ahci = (ahci_dev_t *) dev->driver_data;
     725       
     726        ahci_interrupt_or_timer(ahci, 0);
     727       
     728        /* Enable interrupt. */
     729        ahci->memregs->ghc.ghc |= 2;
    919730}
    920731
     
    923734/*----------------------------------------------------------------------------*/
    924735
    925 /** Allocate SATA device structure with buffers for hardware.
    926  *
    927  * @param port AHCI port structure
    928  *
    929  * @return SATA device structure if succeed, NULL otherwise.
    930  *
    931  */
    932 static sata_dev_t *ahci_sata_allocate(ahci_dev_t *ahci, volatile ahci_port_t *port)
     736static sata_dev_t *ahci_sata_device_allocate(volatile ahci_port_t *port)
    933737{
    934738        size_t size = 4096;
    935         void *phys = NULL;
    936         void *virt_fb = NULL;
    937         void *virt_cmd = NULL;
    938         void *virt_table = NULL;
    939         ddf_fun_t *fun;
    940        
    941         fun = ddf_fun_create(ahci->dev, fun_exposed, NULL);
    942        
    943         sata_dev_t *sata = ddf_fun_data_alloc(fun, sizeof(sata_dev_t));
     739        void* phys = NULL;
     740        void* virt_fb = NULL;
     741        void* virt_cmd = NULL;
     742        void* virt_table = NULL;
     743       
     744        sata_dev_t *sata = malloc(sizeof(sata_dev_t));
    944745        if (sata == NULL)
    945746                return NULL;
    946747       
    947         sata->fun = fun;
     748        bzero(sata, sizeof(sata_dev_t));
     749       
    948750        sata->port = port;
    949751       
     
    961763        rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0,
    962764            &phys, &virt_cmd);
     765       
    963766        if (rc != EOK)
    964767                goto error_cmd;
     
    972775        rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0,
    973776            &phys, &virt_table);
     777       
    974778        if (rc != EOK)
    975779                goto error_table;
     
    989793        free(sata);
    990794        return NULL;
    991 }
    992 
    993 /** Initialize and start SATA hardware device.
    994  *
    995  * @param sata SATA device structure.
    996  *
    997  */
    998 static void ahci_sata_hw_start(sata_dev_t *sata)
    999 {
    1000         ahci_port_cmd_t pxcmd;
    1001        
    1002         pxcmd.u32 = sata->port->pxcmd;
    1003        
    1004         /* Frame receiver disabled. */
    1005         pxcmd.fre = 0;
    1006        
    1007         /* Disable process the command list. */
    1008         pxcmd.st = 0;
    1009        
    1010         sata->port->pxcmd = pxcmd.u32;
    1011        
    1012         /* Clear interrupt status. */
    1013         sata->port->pxis = 0xffffffff;
    1014        
    1015         /* Clear error status. */
    1016         sata->port->pxserr = 0xffffffff;
    1017        
    1018         /* Enable all interrupts. */
    1019         sata->port->pxie = 0xffffffff;
    1020        
    1021         /* Frame receiver enabled. */
    1022         pxcmd.fre = 1;
    1023        
    1024         /* Enable process the command list. */
    1025         pxcmd.st = 1;
    1026        
    1027         sata->port->pxcmd = pxcmd.u32;
    1028 }
    1029 
    1030 /** Create and initialize connected SATA structure device
    1031  *
    1032  * @param ahci     AHCI device structure.
    1033  * @param dev      DDF device structure.
    1034  * @param port     AHCI port structure.
    1035  * @param port_num Number of AHCI port with existing SATA device.
    1036  *
    1037  * @return EOK if succeed, error code otherwise.
    1038  *
    1039  */
    1040 static int ahci_sata_create(ahci_dev_t *ahci, ddf_dev_t *dev,
     795       
     796        /*
     797         * Deleting of pointers in memory hardware mapped register
     798         * unneccessary, hardware port is not in operational state.
     799         */
     800}
     801
     802static int ahci_sata_device_create(ahci_dev_t *ahci, ddf_dev_t *dev,
    1041803    volatile ahci_port_t *port, unsigned int port_num)
    1042804{
    1043805        ddf_fun_t *fun = NULL;
    1044         int rc;
    1045        
    1046         sata_dev_t *sata = ahci_sata_allocate(ahci, port);
     806        sata_dev_t *sata = ahci_sata_device_allocate(port);
     807       
    1047808        if (sata == NULL)
    1048809                return EINTR;
     
    1053814        ahci->sata_devs[port_num] = sata;
    1054815       
    1055         /* Initialize synchronization structures */
    1056816        fibril_mutex_initialize(&sata->lock);
    1057817        fibril_mutex_initialize(&sata->event_lock);
    1058818        fibril_condvar_initialize(&sata->event_condvar);
    1059819       
    1060         ahci_sata_hw_start(sata);
    1061        
    1062         /* Identify device. */
     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       
    1063827        if (ahci_identify_device(sata) != EOK)
    1064828                goto error;
    1065829       
    1066         /* Set required UDMA mode */
    1067830        if (ahci_set_highest_ultra_dma_mode(sata) != EOK)
    1068831                goto error;
    1069832       
    1070         /* Add device to the system */
    1071         char sata_dev_name[16];
    1072         snprintf(sata_dev_name, 16, "ahci_%u", sata_devices_count);
     833        /* Add sata device to system. */
     834        char sata_dev_name[1024];
     835        snprintf(sata_dev_name, 1024, "ahci_%u", sata_devices_count);
    1073836       
    1074837        fibril_mutex_lock(&sata_devices_count_lock);
     
    1076839        fibril_mutex_unlock(&sata_devices_count_lock);
    1077840       
    1078         rc= ddf_fun_set_name(sata->fun, sata_dev_name);
    1079         if (rc != EOK) {
    1080                 ddf_msg(LVL_ERROR, "Failed setting function name.");
     841        fun = ddf_fun_create(dev, fun_exposed, sata_dev_name);
     842        if (fun == NULL) {
     843                ddf_msg(LVL_ERROR, "Failed creating function.");
    1081844                goto error;
    1082845        }
    1083846       
    1084         ddf_fun_set_ops(fun, &ahci_ops);
    1085        
    1086         rc = ddf_fun_bind(fun);
     847        fun->ops = &ahci_ops;
     848        fun->driver_data = sata;
     849        int rc = ddf_fun_bind(fun);
    1087850        if (rc != EOK) {
    1088851                ddf_msg(LVL_ERROR, "Failed binding function.");
     
    1093856       
    1094857error:
    1095         sata->is_invalid_device = true;
     858        sata->invalid_device = true;
    1096859        if (fun != NULL)
    1097860                ddf_fun_destroy(fun);
     
    1100863}
    1101864
    1102 /** Create and initialize all SATA structure devices for connected SATA drives.
    1103  *
    1104  * @param ahci AHCI device structure.
    1105  * @param dev  DDF device structure.
    1106  *
    1107  */
    1108865static void ahci_sata_devices_create(ahci_dev_t *ahci, ddf_dev_t *dev)
    1109866{
    1110         for (unsigned int port_num = 0; port_num < AHCI_MAX_PORTS; port_num++) {
     867        for (unsigned int port_num = 0; port_num < 32; port_num++) {
    1111868                /* Active ports only */
    1112869                if (!(ahci->memregs->ghc.pi & (1 << port_num)))
     
    1116873               
    1117874                /* Active devices only */
    1118                 ahci_port_ssts_t pxssts;
    1119                 pxssts.u32 = port->pxssts;
    1120                 if (pxssts.det != AHCI_PORT_SSTS_DET_ACTIVE)
     875                if ((port->pxssts & 0x0f) != 3)
    1121876                        continue;
    1122877               
    1123                 ahci_sata_create(ahci, dev, port, port_num);
    1124         }
    1125 }
    1126 
    1127 /** Create AHCI device structure, intialize it and register interrupt routine.
    1128  *
    1129  * @param dev DDF device structure.
    1130  *
    1131  * @return AHCI device structure if succeed, NULL otherwise.
    1132  *
    1133  */
     878                ahci_sata_device_create(ahci, dev, port, port_num);
     879        }
     880}
     881
    1134882static ahci_dev_t *ahci_ahci_create(ddf_dev_t *dev)
    1135883{
    1136         ahci_dev_t *ahci = ddf_dev_data_alloc(dev, sizeof(ahci_dev_t));
     884        ahci_dev_t *ahci = malloc(sizeof(ahci_dev_t));
    1137885        if (!ahci)
    1138886                return NULL;
    1139887       
    1140         /* Connect to parent device */
    1141         ahci->parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
    1142         if (ahci->parent_sess == NULL)
    1143                 return NULL;
     888        bzero(ahci, sizeof(ahci_dev_t));
    1144889       
    1145890        ahci->dev = dev;
     
    1147892        hw_res_list_parsed_t hw_res_parsed;
    1148893        hw_res_list_parsed_init(&hw_res_parsed);
    1149         if (hw_res_get_list_parsed(ahci->parent_sess, &hw_res_parsed, 0) != EOK)
     894        if (hw_res_get_list_parsed(dev->parent_sess, &hw_res_parsed, 0) != EOK)
    1150895                goto error_get_res_parsed;
    1151896       
    1152         /* Map AHCI registers. */
    1153         ahci->memregs = NULL;
    1154        
     897        /* Register interrupt handler */
     898        ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address;
     899        ahci_ranges[0].size = sizeof(ahci_dev_t);
     900        ahci_cmds[0].addr =
     901            ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1;
     902        ahci_cmds[1].addr =
     903            ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 2;
     904        ahci_cmds[2].addr = ahci_cmds[1].addr;
     905       
     906        irq_code_t ct;
     907        ct.cmdcount = 3;
     908        ct.cmds = ahci_cmds;
     909        ct.rangecount = 1;
     910        ct.ranges = ahci_ranges;
     911       
     912        int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0],
     913            ahci_interrupt, &ct);
     914       
     915        if (rc != EOK) {
     916                ddf_msg(LVL_ERROR, "Failed register_interrupt_handler function.");
     917                goto error_register_interrupt_handler;
     918        }
     919       
     920        if (ahci_pciintel_enable_interrupt(hw_res_parsed.irqs.irqs[0]) != EOK) {
     921                ddf_msg(LVL_ERROR, "Failed enable interupt.");
     922                goto error_enable_interrupt;
     923        }
     924       
     925        /* Map AHCI register. */
    1155926        physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address),
    1156             AHCI_MEMREGS_PAGES_COUNT, AS_AREA_READ | AS_AREA_WRITE,
    1157             (void **) &ahci->memregs);
     927            8, AS_AREA_READ | AS_AREA_WRITE, (void **) &ahci->memregs);
     928        hw_res_list_parsed_clean(&hw_res_parsed);
     929       
    1158930        if (ahci->memregs == NULL)
    1159931                goto error_map_registers;
    1160932       
    1161         /* Register interrupt handler */
    1162         ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address;
    1163         ahci_ranges[0].size = sizeof(ahci_memregs_t);
    1164        
    1165         for (unsigned int port = 0; port < AHCI_MAX_PORTS; port++) {
    1166                 size_t base = port * 7;
    1167                
    1168                 ahci_cmds[base].addr =
    1169                     ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
    1170                     AHCI_PORTS_REGISTERS_OFFSET + port * AHCI_PORT_REGISTERS_SIZE +
    1171                     AHCI_PORT_IS_REGISTER_OFFSET;
    1172                 ahci_cmds[base + 2].addr = ahci_cmds[base].addr;
    1173                
    1174                 ahci_cmds[base + 3].addr =
    1175                     ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
    1176                     AHCI_GHC_IS_REGISTER_OFFSET;
    1177                 ahci_cmds[base + 4].addr = ahci_cmds[base + 3].addr;
    1178         }
    1179        
    1180         irq_code_t ct;
    1181         ct.cmdcount = sizeof(ahci_cmds) / sizeof(irq_cmd_t);
    1182         ct.cmds = ahci_cmds;
    1183         ct.rangecount = sizeof(ahci_ranges) / sizeof(irq_pio_range_t);
    1184         ct.ranges = ahci_ranges;
    1185        
    1186         int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0],
    1187             ahci_interrupt, &ct);
    1188         if (rc != EOK) {
    1189                 ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
    1190                 goto error_register_interrupt_handler;
    1191         }
    1192        
    1193         rc = ahci_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
    1194         if (rc != EOK) {
    1195                 ddf_msg(LVL_ERROR, "Failed enable interupt.");
    1196                 goto error_enable_interrupt;
    1197         }
    1198        
     933        ahci->timer = fibril_timer_create();
     934       
     935        return ahci;
     936       
     937error_map_registers:
     938error_enable_interrupt:
     939error_register_interrupt_handler:
    1199940        hw_res_list_parsed_clean(&hw_res_parsed);
    1200         return ahci;
    1201        
    1202 error_enable_interrupt:
    1203         unregister_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0]);
    1204        
    1205 error_register_interrupt_handler:
    1206         // FIXME: unmap physical memory
    1207        
    1208 error_map_registers:
    1209         hw_res_list_parsed_clean(&hw_res_parsed);
    1210        
    1211941error_get_res_parsed:
    1212         free(ahci);
    1213942        return NULL;
    1214943}
    1215944
    1216 /** Initialize and start AHCI hardware device.
    1217  *
    1218  * @param ahci AHCI device.
    1219  *
    1220  */
    1221 static void ahci_ahci_hw_start(ahci_dev_t *ahci)
    1222 {
    1223         /* Disable command completion coalescing feature */
     945static void ahci_ahci_init(ahci_dev_t *ahci)
     946{
     947        /* Enable interrupt and bus mastering */
     948        ahci_pcireg_cmd_t cmd;
     949       
     950        pci_config_space_read_16(ahci->dev->parent_sess, AHCI_PCI_CMD, &cmd.u16);
     951        cmd.id = 0;
     952        cmd.bme = 1;
     953        pci_config_space_write_16(ahci->dev->parent_sess, AHCI_PCI_CMD, cmd.u16);
     954       
     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. */
    1224959        ahci_ghc_ccc_ctl_t ccc;
    1225        
    1226960        ccc.u32 = ahci->memregs->ghc.ccc_ctl;
    1227961        ccc.en = 0;
    1228962        ahci->memregs->ghc.ccc_ctl = ccc.u32;
    1229963       
    1230         /* Set master latency timer. */
    1231         pci_config_space_write_8(ahci->parent_sess, AHCI_PCI_MLT, 32);
    1232        
    1233         /* Enable PCI interrupt and bus mastering */
    1234         ahci_pcireg_cmd_t cmd;
    1235        
    1236         pci_config_space_read_16(ahci->parent_sess, AHCI_PCI_CMD, &cmd.u16);
    1237         cmd.id = 0;
    1238         cmd.bme = 1;
    1239         pci_config_space_write_16(ahci->parent_sess, AHCI_PCI_CMD, cmd.u16);
    1240        
    1241964        /* Enable AHCI and interrupt. */
    1242         ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE;
    1243 }
    1244 
    1245 /** AHCI device driver initialization
    1246  *
    1247  * Create and initialize all SATA structure devices for connected
    1248  * SATA drives.
    1249  *
    1250  * @param dev DDF device structure.
    1251  *
    1252  * @return EOK if succeed, error code otherwise.
    1253  *
    1254  */
     965        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
    1255971static int ahci_dev_add(ddf_dev_t *dev)
    1256972{
     973        dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
     974            dev->handle, IPC_FLAG_BLOCKING);
     975        if (dev->parent_sess == NULL)
     976                return EINTR;
     977       
    1257978        ahci_dev_t *ahci = ahci_ahci_create(dev);
    1258979        if (ahci == NULL)
    1259                 goto error;
    1260        
    1261         /* Start AHCI hardware. */
    1262         ahci_ahci_hw_start(ahci);
    1263        
    1264         /* Create device structures for sata devices attached to AHCI. */
     980                return EINTR;
     981       
     982        dev->driver_data = ahci;
     983        ahci_ahci_init(ahci);
    1265984        ahci_sata_devices_create(ahci, dev);
    1266985       
    1267986        return EOK;
    1268        
    1269 error:
    1270         return EINTR;
    1271987}
    1272988
     
    1275991/*----------------------------------------------------------------------------*/
    1276992
    1277 /** Convert SATA model name
    1278  *
    1279  * Convert SATA model name from machine format returned by
    1280  * identify device command to human readable form.
    1281  *
    1282  * @param src Source buffer with device name in machine format.
    1283  * @param dst Buffer for human readable string, minimum size is 41 chars.
    1284  *
    1285  */
    1286993static void ahci_get_model_name(uint16_t *src, char *dst)
    1287994{
     
    13111018}
    13121019
    1313 /** Enable interrupt using SERVICE_IRC.
    1314  *
    1315  * @param irq Requested irq number.
    1316  *
    1317  * @return EOK if succeed, error code otherwise.
    1318  *
    1319  */
    1320 static int ahci_enable_interrupt(int irq)
     1020static int ahci_pciintel_enable_interrupt(int irq)
    13211021{
    13221022        async_sess_t *irc_sess = NULL;
    13231023        irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_IRC, 0, 0);
     1024       
    13241025        if (!irc_sess)
    13251026                return EINTR;
     
    13401041{
    13411042        printf("%s: HelenOS AHCI device driver\n", NAME);
    1342         ddf_log_init(NAME);
     1043        ddf_log_init(NAME, LVL_ERROR);
    13431044        fibril_mutex_initialize(&sata_devices_count_lock);
    13441045        return ddf_driver_main(&ahci_driver);
Note: See TracChangeset for help on using the changeset viewer.