Changes in uspace/drv/block/ahci/ahci.c [267f235:730dce77] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/block/ahci/ahci.c
r267f235 r730dce77 34 34 #include <errno.h> 35 35 #include <stdio.h> 36 #include <devman.h> 36 37 #include <ddf/interrupt.h> 37 38 #include <ddf/log.h> … … 48 49 #define NAME "ahci" 49 50 51 #define AHCI_TIMER_TICKS 1000000000 52 50 53 #define LO(ptr) \ 51 54 ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff)) … … 53 56 #define HI(ptr) \ 54 57 ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32)) 55 56 /** Interrupt pseudocode for a single port57 *58 * The interrupt handling works as follows:59 *60 * 1. Port interrupt status register is read61 * (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 read65 * and cleared (any potential interrupts from66 * 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 }112 58 113 59 static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *); … … 124 70 static void ahci_sata_devices_create(ahci_dev_t *, ddf_dev_t *); 125 71 static ahci_dev_t *ahci_ahci_create(ddf_dev_t *); 126 static void ahci_ahci_ hw_start(ahci_dev_t *);72 static void ahci_ahci_init(ahci_dev_t *); 127 73 128 74 static int ahci_dev_add(ddf_dev_t *); 129 75 130 76 static void ahci_get_model_name(uint16_t *, char *); 131 static int ahci_ enable_interrupt(int);77 static int ahci_pciintel_enable_interrupt(int); 132 78 133 79 static fibril_mutex_t sata_devices_count_lock; … … 159 105 }; 160 106 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 */182 107 static int ahci_get_sata_device_name(ddf_fun_t *fun, 183 108 size_t sata_dev_name_length, char *sata_dev_name) 184 109 { 185 sata_dev_t *sata = fun_sata_dev(fun);110 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 186 111 str_cpy(sata_dev_name, sata_dev_name_length, sata->model); 187 112 return EOK; 188 113 } 189 114 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 */198 115 static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks) 199 116 { 200 sata_dev_t *sata = fun_sata_dev(fun);117 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 201 118 *num_blocks = sata->blocks; 202 119 return EOK; 203 120 } 204 121 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 */213 122 static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size) 214 123 { 215 sata_dev_t *sata = fun_sata_dev(fun);124 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 216 125 *block_size = sata->block_size; 217 126 return EOK; 218 127 } 219 128 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 otherwise228 *229 */230 129 static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum, 231 130 size_t count, void *buf) 232 131 { 233 sata_dev_t *sata = fun_sata_dev(fun); 132 int rc = EOK; 133 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 234 134 235 135 void *phys; 236 136 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, 238 139 0, &phys, (void **) &ibuf); 239 if (rc != EOK) {240 ddf_msg(LVL_ERROR, "Cannot allocate read buffer.");241 return rc;242 }243 244 140 bzero(buf, sata->block_size); 245 141 … … 261 157 } 262 158 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 otherwise271 *272 */273 159 static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum, 274 160 size_t count, void *buf) 275 161 { 276 sata_dev_t *sata = fun_sata_dev(fun); 162 int rc = EOK; 163 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 277 164 278 165 void *phys; 279 166 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, 281 169 0, &phys, (void **) &ibuf); 282 if (rc != EOK) {283 ddf_msg(LVL_ERROR, "Cannot allocate write buffer.");284 return rc;285 }286 170 287 171 fibril_mutex_lock(&sata->lock); … … 297 181 fibril_mutex_unlock(&sata->lock); 298 182 dmamem_unmap_anonymous(ibuf); 299 300 183 return rc; 301 184 } … … 305 188 /*----------------------------------------------------------------------------*/ 306 189 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 */338 190 static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys) 339 191 { 340 volatile s ata_std_command_frame_t *cmd =341 (s ata_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; 345 197 cmd->command = 0xec; 346 198 cmd->features = 0; … … 360 212 prdt->data_address_upper = HI(phys); 361 213 prdt->reserved1 = 0; 362 prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH -1;214 prdt->dbc = 511; 363 215 prdt->reserved2 = 0; 364 216 prdt->ioc = 0; 365 217 366 218 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; 370 220 sata->cmd_header->bytesprocessed = 0; 371 221 372 /* Run command. */373 222 sata->port->pxsact |= 1; 374 223 sata->port->pxci |= 1; 375 224 } 376 225 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 */383 226 static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys) 384 227 { 385 volatile s ata_std_command_frame_t *cmd =386 (s ata_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; 390 233 cmd->command = 0xa1; 391 234 cmd->features = 0; … … 405 248 prdt->data_address_upper = HI(phys); 406 249 prdt->reserved1 = 0; 407 prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH -1;250 prdt->dbc = 511; 408 251 prdt->reserved2 = 0; 409 252 prdt->ioc = 0; 410 253 411 254 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; 415 256 sata->cmd_header->bytesprocessed = 0; 416 257 417 /* Run command. */418 258 sata->port->pxsact |= 1; 419 259 sata->port->pxci |= 1; 420 260 } 421 261 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 */429 262 static int ahci_identify_device(sata_dev_t *sata) 430 263 { 431 if (sata->i s_invalid_device) {264 if (sata->invalid_device) { 432 265 ddf_msg(LVL_ERROR, 433 266 "Identify command device on invalid device"); … … 436 269 437 270 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); 447 276 448 277 fibril_mutex_lock(&sata->lock); 449 278 450 279 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) { 454 289 ddf_msg(LVL_ERROR, 455 290 "Unrecoverable error during ata identify device"); … … 459 294 if (ahci_port_is_tfes(pxis)) { 460 295 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))) { 464 305 ddf_msg(LVL_ERROR, 465 306 "Unrecoverable error during ata identify packet device"); … … 467 308 } 468 309 469 sata->is_packet_device = true; 470 } 310 sata->packet_device = true; 311 } else 312 sata->packet_device = false; 471 313 472 314 ahci_get_model_name(idata->model_name, sata->model); … … 476 318 * only NCQ FPDMA mode is supported. 477 319 */ 478 if ((idata->sata_cap & sata_np_cap_ncq) == 0) {320 if ((idata->sata_cap & np_cap_ncq) == 0) { 479 321 ddf_msg(LVL_ERROR, "%s: NCQ must be supported", sata->model); 480 322 goto error; 481 323 } 482 324 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) { 504 326 /* 505 327 * 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! 508 330 */ 509 sata->block_size = SATA_DEFAULT_SECTOR_SIZE;331 sata->block_size = 512; 510 332 sata->blocks = 0; 511 333 } 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) { 515 337 ddf_msg(LVL_ERROR, "%s: LBA for NCQ must be supported", 516 338 sata->model); 517 339 goto error; 518 } else if ((idata->cmd_set1 & sata_cs1_addr48) == 0) {340 } else if ((idata->cmd_set1 & cs1_addr48) == 0) { 519 341 sata->blocks = (uint32_t) idata->total_lba28_0 | 520 342 ((uint32_t) idata->total_lba28_1 << 16); … … 529 351 530 352 uint8_t udma_mask = idata->udma & 0x007f; 531 sata->highest_udma_mode = (uint8_t) -1;532 353 if (udma_mask == 0) { 533 354 ddf_msg(LVL_ERROR, … … 536 357 goto error; 537 358 } else { 538 for (u int8_t i = 0; i < 7; i++) {359 for (unsigned int i = 0; i < 7; i++) { 539 360 if (udma_mask & (1 << i)) 540 361 sata->highest_udma_mode = i; … … 554 375 } 555 376 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 */563 377 static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode) 564 378 { 565 volatile s ata_std_command_frame_t *cmd =566 (s ata_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; 570 384 cmd->command = 0xef; 571 385 cmd->features = 0x03; … … 579 393 cmd->reserved2 = 0; 580 394 581 volatile ahci_cmd_prdt_t *prdt =395 volatile ahci_cmd_prdt_t* prdt = 582 396 (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]); 583 397 … … 585 399 prdt->data_address_upper = HI(phys); 586 400 prdt->reserved1 = 0; 587 prdt->dbc = SATA_SET_FEATURE_BUFFER_LENGTH -1;401 prdt->dbc = 511; 588 402 prdt->reserved2 = 0; 589 403 prdt->ioc = 0; 590 404 591 405 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; 595 407 sata->cmd_header->bytesprocessed = 0; 596 408 597 /* Run command. */598 409 sata->port->pxsact |= 1; 599 410 sata->port->pxci |= 1; 600 411 } 601 412 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 otherwise607 *608 */609 413 static int ahci_set_highest_ultra_dma_mode(sata_dev_t *sata) 610 414 { 611 if (sata->i s_invalid_device) {415 if (sata->invalid_device) { 612 416 ddf_msg(LVL_ERROR, 613 417 "%s: Setting highest UDMA mode on invalid device", … … 616 420 } 617 421 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 630 422 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); 640 428 641 429 fibril_mutex_lock(&sata->lock); … … 643 431 uint8_t mode = 0x40 | (sata->highest_udma_mode & 0x07); 644 432 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) { 648 442 ddf_msg(LVL_ERROR, 649 443 "%s: Unrecoverable error during set highest UDMA mode", … … 670 464 } 671 465 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 */679 466 static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 680 467 { 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; 686 473 cmd->command = 0x60; 687 474 cmd->tag = 0; … … 716 503 717 504 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; 721 506 sata->cmd_header->bytesprocessed = 0; 722 507 … … 725 510 } 726 511 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 otherwise734 *735 */736 512 static int ahci_rb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum) 737 513 { 738 if (sata->i s_invalid_device) {514 if (sata->invalid_device) { 739 515 ddf_msg(LVL_ERROR, 740 516 "%s: FPDMA read from invalid device", sata->model); … … 743 519 744 520 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))) { 748 530 ddf_msg(LVL_ERROR, 749 531 "%s: Unrecoverable error during FPDMA read", sata->model); … … 754 536 } 755 537 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 otherwise763 *764 */765 538 static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 766 539 { 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; 772 545 cmd->command = 0x61; 773 546 cmd->tag = 0; … … 791 564 cmd->lba5 = (blocknum >> 40) & 0xff; 792 565 793 volatile ahci_cmd_prdt_t * prdt =566 volatile ahci_cmd_prdt_t * prdt = 794 567 (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]); 795 568 … … 802 575 803 576 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; 808 578 sata->cmd_header->bytesprocessed = 0; 809 579 … … 812 582 } 813 583 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 otherwise821 *822 */823 584 static int ahci_wb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum) 824 585 { 825 if (sata->i s_invalid_device) {586 if (sata->invalid_device) { 826 587 ddf_msg(LVL_ERROR, 827 588 "%s: FPDMA write to invalid device", sata->model); … … 830 591 831 592 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))) { 835 602 ddf_msg(LVL_ERROR, 836 603 "%s: Unrecoverable error during FPDMA write", sata->model); … … 842 609 843 610 /*----------------------------------------------------------------------------*/ 844 /*-- Interrupts handling -----------------------------------------------------*/611 /*-- Interrupts and timer unified handling -----------------------------------*/ 845 612 /*----------------------------------------------------------------------------*/ 846 613 … … 848 615 { 849 616 .base = 0, 850 .size = 0,617 .size = 32, 851 618 } 852 619 }; 853 620 854 621 static 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 } 887 642 }; 643 644 /** Unified AHCI interrupt and timer interrupt handler. 645 * 646 * @param ahci AHCI device. 647 * @param is_timer Indicate timer interrupt. 648 * 649 */ 650 static 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 */ 709 static 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 } 888 716 889 717 /** AHCI interrupt handler. 890 718 * 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. 894 720 * 895 721 */ 896 722 static void ahci_interrupt(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *icall) 897 723 { 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; 919 730 } 920 731 … … 923 734 /*----------------------------------------------------------------------------*/ 924 735 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) 736 static sata_dev_t *ahci_sata_device_allocate(volatile ahci_port_t *port) 933 737 { 934 738 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)); 944 745 if (sata == NULL) 945 746 return NULL; 946 747 947 sata->fun = fun; 748 bzero(sata, sizeof(sata_dev_t)); 749 948 750 sata->port = port; 949 751 … … 961 763 rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0, 962 764 &phys, &virt_cmd); 765 963 766 if (rc != EOK) 964 767 goto error_cmd; … … 972 775 rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0, 973 776 &phys, &virt_table); 777 974 778 if (rc != EOK) 975 779 goto error_table; … … 989 793 free(sata); 990 794 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 802 static int ahci_sata_device_create(ahci_dev_t *ahci, ddf_dev_t *dev, 1041 803 volatile ahci_port_t *port, unsigned int port_num) 1042 804 { 1043 805 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 1047 808 if (sata == NULL) 1048 809 return EINTR; … … 1053 814 ahci->sata_devs[port_num] = sata; 1054 815 1055 /* Initialize synchronization structures */1056 816 fibril_mutex_initialize(&sata->lock); 1057 817 fibril_mutex_initialize(&sata->event_lock); 1058 818 fibril_condvar_initialize(&sata->event_condvar); 1059 819 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 1063 827 if (ahci_identify_device(sata) != EOK) 1064 828 goto error; 1065 829 1066 /* Set required UDMA mode */1067 830 if (ahci_set_highest_ultra_dma_mode(sata) != EOK) 1068 831 goto error; 1069 832 1070 /* Add device to the system*/1071 char sata_dev_name[1 6];1072 snprintf(sata_dev_name, 1 6, "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); 1073 836 1074 837 fibril_mutex_lock(&sata_devices_count_lock); … … 1076 839 fibril_mutex_unlock(&sata_devices_count_lock); 1077 840 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."); 1081 844 goto error; 1082 845 } 1083 846 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); 1087 850 if (rc != EOK) { 1088 851 ddf_msg(LVL_ERROR, "Failed binding function."); … … 1093 856 1094 857 error: 1095 sata->i s_invalid_device = true;858 sata->invalid_device = true; 1096 859 if (fun != NULL) 1097 860 ddf_fun_destroy(fun); … … 1100 863 } 1101 864 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 */1108 865 static void ahci_sata_devices_create(ahci_dev_t *ahci, ddf_dev_t *dev) 1109 866 { 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++) { 1111 868 /* Active ports only */ 1112 869 if (!(ahci->memregs->ghc.pi & (1 << port_num))) … … 1116 873 1117 874 /* 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) 1121 876 continue; 1122 877 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 1134 882 static ahci_dev_t *ahci_ahci_create(ddf_dev_t *dev) 1135 883 { 1136 ahci_dev_t *ahci = ddf_dev_data_alloc(dev,sizeof(ahci_dev_t));884 ahci_dev_t *ahci = malloc(sizeof(ahci_dev_t)); 1137 885 if (!ahci) 1138 886 return NULL; 1139 887 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)); 1144 889 1145 890 ahci->dev = dev; … … 1147 892 hw_res_list_parsed_t hw_res_parsed; 1148 893 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) 1150 895 goto error_get_res_parsed; 1151 896 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. */ 1155 926 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 1158 930 if (ahci->memregs == NULL) 1159 931 goto error_map_registers; 1160 932 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 937 error_map_registers: 938 error_enable_interrupt: 939 error_register_interrupt_handler: 1199 940 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 memory1207 1208 error_map_registers:1209 hw_res_list_parsed_clean(&hw_res_parsed);1210 1211 941 error_get_res_parsed: 1212 free(ahci);1213 942 return NULL; 1214 943 } 1215 944 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 */ 945 static 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. */ 1224 959 ahci_ghc_ccc_ctl_t ccc; 1225 1226 960 ccc.u32 = ahci->memregs->ghc.ccc_ctl; 1227 961 ccc.en = 0; 1228 962 ahci->memregs->ghc.ccc_ctl = ccc.u32; 1229 963 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 1241 964 /* 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 1255 971 static int ahci_dev_add(ddf_dev_t *dev) 1256 972 { 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 1257 978 ahci_dev_t *ahci = ahci_ahci_create(dev); 1258 979 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); 1265 984 ahci_sata_devices_create(ahci, dev); 1266 985 1267 986 return EOK; 1268 1269 error:1270 return EINTR;1271 987 } 1272 988 … … 1275 991 /*----------------------------------------------------------------------------*/ 1276 992 1277 /** Convert SATA model name1278 *1279 * Convert SATA model name from machine format returned by1280 * 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 */1286 993 static void ahci_get_model_name(uint16_t *src, char *dst) 1287 994 { … … 1311 1018 } 1312 1019 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) 1020 static int ahci_pciintel_enable_interrupt(int irq) 1321 1021 { 1322 1022 async_sess_t *irc_sess = NULL; 1323 1023 irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_IRC, 0, 0); 1024 1324 1025 if (!irc_sess) 1325 1026 return EINTR; … … 1340 1041 { 1341 1042 printf("%s: HelenOS AHCI device driver\n", NAME); 1342 ddf_log_init(NAME );1043 ddf_log_init(NAME, LVL_ERROR); 1343 1044 fibril_mutex_initialize(&sata_devices_count_lock); 1344 1045 return ddf_driver_main(&ahci_driver);
Note:
See TracChangeset
for help on using the changeset viewer.