Changeset ae3ff9f5 in mainline
- Timestamp:
- 2012-07-18T17:35:08Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7030bc9
- Parents:
- 730dce77
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/block/ahci/ahci.c
r730dce77 rae3ff9f5 49 49 #define NAME "ahci" 50 50 51 #define AHCI_TIMER_TICKS 1000000000 51 /** Number of ticks for watchdog timer. */ 52 #define AHCI_TIMER_TICKS 800000 53 54 /** Number of ticks for timer based interrupt. */ 55 #define AHCI_TIMER_NO_INTR_TICKS 8000 52 56 53 57 #define LO(ptr) \ … … 70 74 static void ahci_sata_devices_create(ahci_dev_t *, ddf_dev_t *); 71 75 static ahci_dev_t *ahci_ahci_create(ddf_dev_t *); 72 static void ahci_ahci_ init(ahci_dev_t *);76 static void ahci_ahci_hw_start(ahci_dev_t *); 73 77 74 78 static int ahci_dev_add(ddf_dev_t *); 75 79 76 80 static void ahci_get_model_name(uint16_t *, char *); 77 static int ahci_ pciintel_enable_interrupt(int);81 static int ahci_enable_interrupt(int); 78 82 79 83 static fibril_mutex_t sata_devices_count_lock; … … 105 109 }; 106 110 111 /** Get SATA device name. 112 * 113 * @param fun Device function handling the call. 114 * @param sata_dev_name_length Length of the sata_dev_name buffer. 115 * @param sata_dev_name Buffer for SATA device name. 116 * 117 * @return EOK. 118 * 119 */ 107 120 static int ahci_get_sata_device_name(ddf_fun_t *fun, 108 121 size_t sata_dev_name_length, char *sata_dev_name) … … 113 126 } 114 127 128 /** Get Number of blocks in SATA device. 129 * 130 * @param fun Device function handling the call. 131 * @param blocks Return number of blocks in SATA device. 132 * 133 * @return EOK. 134 * 135 */ 115 136 static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks) 116 137 { … … 120 141 } 121 142 143 /** Get SATA device block size. 144 * 145 * @param fun Device function handling the call. 146 * @param block_size Return block size. 147 * 148 * @return EOK. 149 * 150 */ 122 151 static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size) 123 152 { … … 127 156 } 128 157 158 /** Read data blocks into SATA device. 159 * 160 * @param fun Device function handling the call. 161 * @param blocknum Number of first block. 162 * @param count Number of blocks to read. 163 * @param buf Buffer for data. 164 * 165 * @return EOK if succeed, error code otherwise 166 * 167 */ 129 168 static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum, 130 169 size_t count, void *buf) 131 170 { 132 int rc = EOK;133 171 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 134 172 135 173 void *phys; 136 174 void *ibuf; 137 138 dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE, 175 int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE, 139 176 0, &phys, (void **) &ibuf); 177 if (rc != EOK) { 178 ddf_msg(LVL_ERROR, "Cannot allocate read buffer."); 179 return rc; 180 } 181 140 182 bzero(buf, sata->block_size); 141 183 … … 157 199 } 158 200 201 /** Write data blocks into SATA device. 202 * 203 * @param fun Device function handling the call. 204 * @param blocknum Number of first block. 205 * @param count Number of blocks to write. 206 * @param buf Buffer with data. 207 * 208 * @return EOK if succeed, error code otherwise 209 * 210 */ 159 211 static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum, 160 212 size_t count, void *buf) 161 213 { 162 int rc = EOK;163 214 sata_dev_t *sata = (sata_dev_t *) fun->driver_data; 164 215 165 216 void *phys; 166 217 void *ibuf; 167 168 dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE, 218 int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE, 169 219 0, &phys, (void **) &ibuf); 220 if (rc != EOK) { 221 ddf_msg(LVL_ERROR, "Cannot allocate write buffer."); 222 return rc; 223 } 170 224 171 225 fibril_mutex_lock(&sata->lock); … … 181 235 fibril_mutex_unlock(&sata->lock); 182 236 dmamem_unmap_anonymous(ibuf); 237 183 238 return rc; 184 239 } … … 188 243 /*----------------------------------------------------------------------------*/ 189 244 245 /** Get and clear AHCI port interrupt state register. 246 * 247 * @param sata SATA device structure. 248 * 249 * @return Value of interrupt state register. 250 * 251 */ 252 static ahci_port_is_t ahci_get_and_clear_pxis(sata_dev_t *sata) 253 { 254 ahci_port_is_t pxis; 255 256 fibril_mutex_lock(&sata->pxis_lock); 257 258 pxis.u32 = sata->ahci->memregs->ports[sata->port_num].pxis; 259 sata->ahci->memregs->ports[sata->port_num].pxis = pxis.u32; 260 261 if (ahci_port_is_permanent_error(pxis)) 262 sata->is_invalid_device = true; 263 264 fibril_mutex_unlock(&sata->pxis_lock); 265 266 return pxis; 267 } 268 269 /** Set AHCI registers for identifying SATA device. 270 * 271 * @param sata SATA device structure. 272 * @param phys Physical address of working buffer. 273 * 274 */ 190 275 static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys) 191 276 { 192 volatile std_command_frame_t *cmd = 193 (std_command_frame_t *) sata->cmd_table; 194 195 cmd->fis_type = 0x27; 196 cmd->c = 0x80; 277 /* Clear interrupt state registers */ 278 ahci_get_and_clear_pxis(sata); 279 sata->shadow_pxis.u32 = 0; 280 281 volatile sata_std_command_frame_t *cmd = 282 (sata_std_command_frame_t *) sata->cmd_table; 283 284 cmd->fis_type = SATA_CMD_FIS_TYPE; 285 cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR; 197 286 cmd->command = 0xec; 198 287 cmd->features = 0; … … 212 301 prdt->data_address_upper = HI(phys); 213 302 prdt->reserved1 = 0; 214 prdt->dbc = 511;303 prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1; 215 304 prdt->reserved2 = 0; 216 305 prdt->ioc = 0; 217 306 218 307 sata->cmd_header->prdtl = 1; 219 sata->cmd_header->flags = 0x402; 308 sata->cmd_header->flags = 309 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 310 AHCI_CMDHDR_FLAGS_2DWCMD; 220 311 sata->cmd_header->bytesprocessed = 0; 221 312 313 /* Run command. */ 222 314 sata->port->pxsact |= 1; 223 315 sata->port->pxci |= 1; 224 316 } 225 317 318 /** Set AHCI registers for identifying packet SATA device. 319 * 320 * @param sata SATA device structure. 321 * @param phys Physical address of working buffer. 322 * 323 */ 226 324 static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys) 227 325 { 228 volatile std_command_frame_t *cmd = 229 (std_command_frame_t *) sata->cmd_table; 230 231 cmd->fis_type = 0x27; 232 cmd->c = 0x80; 326 /* Clear interrupt state registers */ 327 ahci_get_and_clear_pxis(sata); 328 sata->shadow_pxis.u32 = 0; 329 330 volatile sata_std_command_frame_t * cmd = 331 (sata_std_command_frame_t *) sata->cmd_table; 332 333 cmd->fis_type = SATA_CMD_FIS_TYPE; 334 cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR; 233 335 cmd->command = 0xa1; 234 336 cmd->features = 0; … … 248 350 prdt->data_address_upper = HI(phys); 249 351 prdt->reserved1 = 0; 250 prdt->dbc = 511;352 prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1; 251 353 prdt->reserved2 = 0; 252 354 prdt->ioc = 0; 253 355 254 356 sata->cmd_header->prdtl = 1; 255 sata->cmd_header->flags = 0x402; 357 sata->cmd_header->flags = 358 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 359 AHCI_CMDHDR_FLAGS_2DWCMD; 256 360 sata->cmd_header->bytesprocessed = 0; 257 361 362 /* Run command. */ 258 363 sata->port->pxsact |= 1; 259 364 sata->port->pxci |= 1; 260 365 } 261 366 367 /** Fill device identification in SATA device structure. 368 * 369 * @param sata SATA device structure. 370 * 371 * @return EOK if succeed, error code otherwise. 372 * 373 */ 262 374 static int ahci_identify_device(sata_dev_t *sata) 263 375 { 264 if (sata->i nvalid_device) {376 if (sata->is_invalid_device) { 265 377 ddf_msg(LVL_ERROR, 266 378 "Identify command device on invalid device"); … … 269 381 270 382 void *phys; 271 identify_data_t *idata; 272 383 sata_identify_data_t *idata; 273 384 dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys, 274 385 (void **) &idata); … … 286 397 sata->shadow_pxis.u32 &= ~pxis.u32; 287 398 288 if (sata->i nvalid_device) {399 if (sata->is_invalid_device) { 289 400 ddf_msg(LVL_ERROR, 290 401 "Unrecoverable error during ata identify device"); … … 302 413 sata->shadow_pxis.u32 &= ~pxis.u32; 303 414 304 if ((sata->i nvalid_device) || (ahci_port_is_error(pxis))) {415 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { 305 416 ddf_msg(LVL_ERROR, 306 417 "Unrecoverable error during ata identify packet device"); … … 308 419 } 309 420 310 sata->packet_device = true; 311 } else 312 sata->packet_device = false; 421 sata->is_packet_device = true; 422 } 313 423 314 424 ahci_get_model_name(idata->model_name, sata->model); … … 318 428 * only NCQ FPDMA mode is supported. 319 429 */ 320 if ((idata->sata_cap & np_cap_ncq) == 0) {430 if ((idata->sata_cap & sata_np_cap_ncq) == 0) { 321 431 ddf_msg(LVL_ERROR, "%s: NCQ must be supported", sata->model); 322 432 goto error; 323 433 } 324 434 325 if (sata->packet_device) { 435 uint16_t logsec = idata->physical_logic_sector_size; 436 if ((logsec & 0xc000) == 0x4000) { 437 /* Length of sector may be larger than 512 B */ 438 if (logsec & 0x0100) { 439 /* Size of sector is larger than 512 B */ 440 ddf_msg(LVL_ERROR, 441 "%s: Sector length other than 512 B not supported", 442 sata->model); 443 goto error; 444 } 445 446 if ((logsec & 0x0200) && ((logsec & 0x000f) != 0)) { 447 /* Physical sectors per logical sector is greather than 1 */ 448 ddf_msg(LVL_ERROR, 449 "%s: Sector length other than 512 B not supported", 450 sata->model); 451 goto error; 452 } 453 } 454 455 if (sata->is_packet_device) { 326 456 /* 327 457 * Due to QEMU limitation (as of 2012-06-22), 328 * only NCQ FPDMA mode supported - block size is 512 B,329 * not 2048 B!458 * only NCQ FPDMA mode supported - block size is 459 * 512 B, not 2048 B! 330 460 */ 331 sata->block_size = 512;461 sata->block_size = SATA_DEFAULT_SECTOR_SIZE; 332 462 sata->blocks = 0; 333 463 } else { 334 sata->block_size = 512;464 sata->block_size = SATA_DEFAULT_SECTOR_SIZE; 335 465 336 if ((idata->caps & rd_cap_lba) == 0) {466 if ((idata->caps & sata_rd_cap_lba) == 0) { 337 467 ddf_msg(LVL_ERROR, "%s: LBA for NCQ must be supported", 338 468 sata->model); 339 469 goto error; 340 } else if ((idata->cmd_set1 & cs1_addr48) == 0) {470 } else if ((idata->cmd_set1 & sata_cs1_addr48) == 0) { 341 471 sata->blocks = (uint32_t) idata->total_lba28_0 | 342 472 ((uint32_t) idata->total_lba28_1 << 16); … … 351 481 352 482 uint8_t udma_mask = idata->udma & 0x007f; 483 sata->highest_udma_mode = (uint8_t) -1; 353 484 if (udma_mask == 0) { 354 485 ddf_msg(LVL_ERROR, … … 375 506 } 376 507 508 /** Set AHCI registers for setting SATA device transfer mode. 509 * 510 * @param sata SATA device structure. 511 * @param phys Physical address of working buffer. 512 * @param mode Required mode. 513 * 514 */ 377 515 static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode) 378 516 { 379 volatile std_command_frame_t *cmd = 380 (std_command_frame_t *) sata->cmd_table; 381 382 cmd->fis_type = 0x27; 383 cmd->c = 0x80; 517 /* Clear interrupt state registers */ 518 ahci_get_and_clear_pxis(sata); 519 sata->shadow_pxis.u32 = 0; 520 521 volatile sata_std_command_frame_t *cmd = 522 (sata_std_command_frame_t *) sata->cmd_table; 523 524 cmd->fis_type = SATA_CMD_FIS_TYPE; 525 cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR; 384 526 cmd->command = 0xef; 385 527 cmd->features = 0x03; … … 393 535 cmd->reserved2 = 0; 394 536 395 volatile ahci_cmd_prdt_t *prdt =537 volatile ahci_cmd_prdt_t *prdt = 396 538 (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]); 397 539 … … 399 541 prdt->data_address_upper = HI(phys); 400 542 prdt->reserved1 = 0; 401 prdt->dbc = 511;543 prdt->dbc = SATA_SET_FEATURE_BUFFER_LENGTH - 1; 402 544 prdt->reserved2 = 0; 403 545 prdt->ioc = 0; 404 546 405 547 sata->cmd_header->prdtl = 1; 406 sata->cmd_header->flags = 0x402; 548 sata->cmd_header->flags = 549 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 550 AHCI_CMDHDR_FLAGS_2DWCMD; 407 551 sata->cmd_header->bytesprocessed = 0; 408 552 553 /* Run command. */ 409 554 sata->port->pxsact |= 1; 410 555 sata->port->pxci |= 1; 411 556 } 412 557 558 /** Set highest ultra DMA mode supported by SATA device. 559 * 560 * @param sata SATA device structure. 561 * 562 * @return EOK if succeed, error code otherwise 563 * 564 */ 413 565 static int ahci_set_highest_ultra_dma_mode(sata_dev_t *sata) 414 566 { 415 if (sata->i nvalid_device) {567 if (sata->is_invalid_device) { 416 568 ddf_msg(LVL_ERROR, 417 569 "%s: Setting highest UDMA mode on invalid device", … … 420 572 } 421 573 574 if (sata->highest_udma_mode == (uint8_t) -1) { 575 ddf_msg(LVL_ERROR, 576 "%s: No AHCI UDMA support.", sata->model); 577 return EINTR; 578 } 579 580 if (sata->highest_udma_mode > 6) { 581 ddf_msg(LVL_ERROR, 582 "%s: Unknown AHCI UDMA mode.", sata->model); 583 return EINTR; 584 } 585 422 586 void *phys; 423 identify_data_t *idata; 424 425 dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys, 426 (void **) &idata); 427 bzero(idata, 512); 587 sata_identify_data_t *idata; 588 int rc = dmamem_map_anonymous(SATA_SET_FEATURE_BUFFER_LENGTH, 589 AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata); 590 if (rc != EOK) { 591 ddf_msg(LVL_ERROR, "Cannot allocate buffer for device set mode."); 592 return rc; 593 } 594 595 bzero(idata, SATA_SET_FEATURE_BUFFER_LENGTH); 428 596 429 597 fibril_mutex_lock(&sata->lock); … … 439 607 sata->shadow_pxis.u32 &= ~pxis.u32; 440 608 441 if (sata->i nvalid_device) {609 if (sata->is_invalid_device) { 442 610 ddf_msg(LVL_ERROR, 443 611 "%s: Unrecoverable error during set highest UDMA mode", … … 464 632 } 465 633 634 /** Set AHCI registers for reading one sector from the SATA device using FPDMA. 635 * 636 * @param sata SATA device structure. 637 * @param phys Physical address of buffer for sector data. 638 * @param blocknum Block number to read. 639 * 640 */ 466 641 static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 467 642 { 468 volatile ncq_command_frame_t *cmd = 469 (ncq_command_frame_t *) sata->cmd_table; 470 471 cmd->fis_type = 0x27; 472 cmd->c = 0x80; 643 /* Clear interrupt state registers */ 644 ahci_get_and_clear_pxis(sata); 645 sata->shadow_pxis.u32 = 0; 646 647 volatile sata_ncq_command_frame_t *cmd = 648 (sata_ncq_command_frame_t *) sata->cmd_table; 649 650 cmd->fis_type = SATA_CMD_FIS_TYPE; 651 cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR; 473 652 cmd->command = 0x60; 474 653 cmd->tag = 0; … … 503 682 504 683 sata->cmd_header->prdtl = 1; 505 sata->cmd_header->flags = 0x405; 684 sata->cmd_header->flags = 685 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 686 AHCI_CMDHDR_FLAGS_5DWCMD; 506 687 sata->cmd_header->bytesprocessed = 0; 507 688 … … 510 691 } 511 692 693 /** Read one sector from the SATA device using FPDMA. 694 * 695 * @param sata SATA device structure. 696 * @param phys Physical address of buffer for sector data. 697 * @param blocknum Block number to read. 698 * 699 * @return EOK if succeed, error code otherwise 700 * 701 */ 512 702 static int ahci_rb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum) 513 703 { 514 if (sata->i nvalid_device) {704 if (sata->is_invalid_device) { 515 705 ddf_msg(LVL_ERROR, 516 706 "%s: FPDMA read from invalid device", sata->model); … … 527 717 sata->shadow_pxis.u32 &= ~pxis.u32; 528 718 529 if ((sata->i nvalid_device) || (ahci_port_is_error(pxis))) {719 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { 530 720 ddf_msg(LVL_ERROR, 531 721 "%s: Unrecoverable error during FPDMA read", sata->model); … … 536 726 } 537 727 728 /** Set AHCI registers for writing one sector to the SATA device, use FPDMA. 729 * 730 * @param sata SATA device structure. 731 * @param phys Physical address of buffer with sector data. 732 * @param blocknum Block number to write. 733 * 734 * @return EOK if succeed, error code otherwise 735 * 736 */ 538 737 static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 539 738 { 540 volatile ncq_command_frame_t *cmd = 541 (ncq_command_frame_t *) sata->cmd_table; 542 543 cmd->fis_type = 0x27; 544 cmd->c = 0x80; 739 /* Clear interrupt state registers */ 740 ahci_get_and_clear_pxis(sata); 741 sata->shadow_pxis.u32 = 0; 742 743 volatile sata_ncq_command_frame_t * cmd = 744 (sata_ncq_command_frame_t *) sata->cmd_table; 745 746 cmd->fis_type = SATA_CMD_FIS_TYPE; 747 cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR; 545 748 cmd->command = 0x61; 546 749 cmd->tag = 0; … … 575 778 576 779 sata->cmd_header->prdtl = 1; 577 sata->cmd_header->flags = 0x445; 780 sata->cmd_header->flags = 781 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 782 AHCI_CMDHDR_FLAGS_WRITE | 783 AHCI_CMDHDR_FLAGS_5DWCMD; 578 784 sata->cmd_header->bytesprocessed = 0; 579 785 … … 582 788 } 583 789 790 /** Write one sector into the SATA device, use FPDMA. 791 * 792 * @param sata SATA device structure. 793 * @param phys Physical addres of buffer with sector data. 794 * @param blocknum Block number to write. 795 * 796 * @return EOK if succeed, error code otherwise 797 * 798 */ 584 799 static int ahci_wb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum) 585 800 { 586 if (sata->i nvalid_device) {801 if (sata->is_invalid_device) { 587 802 ddf_msg(LVL_ERROR, 588 803 "%s: FPDMA write to invalid device", sata->model); … … 599 814 sata->shadow_pxis.u32 &= ~pxis.u32; 600 815 601 if ((sata->i nvalid_device) || (ahci_port_is_error(pxis))) {816 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { 602 817 ddf_msg(LVL_ERROR, 603 818 "%s: Unrecoverable error during FPDMA write", sata->model); … … 658 873 is.u32 = ahci->memregs->ghc.is; 659 874 ahci->memregs->ghc.is = is.u32; 660 is.u32 = ahci->memregs->ghc.is; 875 876 if (!is_timer) 877 ahci->is_hw_interrupt = true; 878 else if (is.u32) 879 ahci->is_hw_interrupt = false; 661 880 662 881 uint32_t port_event_flags = 0; 663 882 uint32_t port_mask = 1; 664 883 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 884 sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i]; 675 885 if (sata != NULL) { 676 /* add value to shadow copy of port interrupt state register. */ 886 ahci_port_is_t pxis = ahci_get_and_clear_pxis(sata); 887 888 /* Add value to shadow copy of port interrupt state register. */ 677 889 sata->shadow_pxis.u32 |= pxis.u32; 678 890 … … 681 893 (ahci_port_is_error(pxis))) 682 894 port_event_flags |= port_mask; 683 684 if (ahci_port_is_permanent_error(pxis))685 sata->invalid_device = true;686 895 } 687 896 … … 704 913 /** AHCI timer interrupt handler. 705 914 * 706 * @param arg Pointer toAHCI device.915 * @param arg AHCI device. 707 916 * 708 917 */ … … 712 921 713 922 ahci_interrupt_or_timer(ahci, 1); 714 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci); 923 924 if (ahci->is_hw_interrupt) 925 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci); 926 else 927 fibril_timer_set(ahci->timer, AHCI_TIMER_NO_INTR_TICKS, 928 ahci_timer, ahci); 715 929 } 716 930 717 931 /** AHCI interrupt handler. 718 932 * 719 * @param dev Pointer to device driver handler. 933 * @param dev DDF device structure. 934 * @param iid The IPC call id. 935 * @param icall The IPC call structure. 720 936 * 721 937 */ … … 727 943 728 944 /* Enable interrupt. */ 729 ahci->memregs->ghc.ghc |= 2;945 ahci->memregs->ghc.ghc |= AHCI_GHC_GHC_IE; 730 946 } 731 947 … … 734 950 /*----------------------------------------------------------------------------*/ 735 951 736 static sata_dev_t *ahci_sata_device_allocate(volatile ahci_port_t *port) 952 /** Allocate SATA device structure with buffers for hardware. 953 * 954 * @param port AHCI port structure 955 * 956 * @return SATA device structure if succeed, NULL otherwise. 957 * 958 */ 959 static sata_dev_t *ahci_sata_allocate(volatile ahci_port_t *port) 737 960 { 738 961 size_t size = 4096; … … 763 986 rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0, 764 987 &phys, &virt_cmd); 765 766 988 if (rc != EOK) 767 989 goto error_cmd; … … 775 997 rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0, 776 998 &phys, &virt_table); 777 778 999 if (rc != EOK) 779 1000 goto error_table; … … 793 1014 free(sata); 794 1015 return NULL; 795 796 /* 797 * Deleting of pointers in memory hardware mapped register 798 * unneccessary, hardware port is not in operational state. 799 */ 800 } 801 802 static int ahci_sata_device_create(ahci_dev_t *ahci, ddf_dev_t *dev, 1016 } 1017 1018 /** Initialize and start SATA hardware device. 1019 * 1020 * @param sata SATA device structure. 1021 * 1022 */ 1023 static void ahci_sata_hw_start(sata_dev_t *sata) 1024 { 1025 ahci_port_cmd_t pxcmd; 1026 1027 pxcmd.u32 = sata->port->pxcmd; 1028 1029 /* Frame receiver disabled. */ 1030 pxcmd.fre = 0; 1031 1032 /* Disable process the command list. */ 1033 pxcmd.st = 0; 1034 1035 sata->port->pxcmd = pxcmd.u32; 1036 1037 /* Clear interrupt status. */ 1038 sata->port->pxis = 0xffffffff; 1039 1040 /* Clear error status. */ 1041 sata->port->pxserr = 0xffffffff; 1042 1043 /* Enable all interrupts. */ 1044 sata->port->pxie = 0xffffffff; 1045 1046 /* Frame receiver enabled. */ 1047 pxcmd.fre = 1; 1048 1049 /* Enable process the command list. */ 1050 pxcmd.st = 1; 1051 1052 sata->port->pxcmd = pxcmd.u32; 1053 } 1054 1055 /** Create and initialize connected SATA structure device 1056 * 1057 * @param ahci AHCI device structure. 1058 * @param dev DDF device structure. 1059 * @param port AHCI port structure. 1060 * @param port_num Number of AHCI port with existing SATA device. 1061 * 1062 * @return EOK if succeed, error code otherwise. 1063 * 1064 */ 1065 static int ahci_sata_create(ahci_dev_t *ahci, ddf_dev_t *dev, 803 1066 volatile ahci_port_t *port, unsigned int port_num) 804 1067 { 805 1068 ddf_fun_t *fun = NULL; 806 sata_dev_t *sata = ahci_sata_device_allocate(port); 807 1069 sata_dev_t *sata = ahci_sata_allocate(port); 808 1070 if (sata == NULL) 809 1071 return EINTR; … … 814 1076 ahci->sata_devs[port_num] = sata; 815 1077 1078 /* Initialize synchronization structures */ 816 1079 fibril_mutex_initialize(&sata->lock); 1080 fibril_mutex_initialize(&sata->pxis_lock); 817 1081 fibril_mutex_initialize(&sata->event_lock); 818 1082 fibril_condvar_initialize(&sata->event_condvar); 819 820 /* Initialize SATA port operational registers. */ 821 sata->port->pxis = 0; 822 sata->port->pxie = 0xffffffff; 823 sata->port->pxserr = 0; 824 sata->port->pxcmd |= 0x10; 825 sata->port->pxcmd |= 0x01; 826 1083 1084 ahci_sata_hw_start(sata); 1085 1086 /* Identify device. */ 827 1087 if (ahci_identify_device(sata) != EOK) 828 1088 goto error; 829 1089 1090 /* Set required UDMA mode */ 830 1091 if (ahci_set_highest_ultra_dma_mode(sata) != EOK) 831 1092 goto error; 832 1093 833 /* Add sata device to system.*/834 char sata_dev_name[1 024];835 snprintf(sata_dev_name, 1 024, "ahci_%u", sata_devices_count);1094 /* Add device to the system */ 1095 char sata_dev_name[16]; 1096 snprintf(sata_dev_name, 16, "ahci_%u", sata_devices_count); 836 1097 837 1098 fibril_mutex_lock(&sata_devices_count_lock); … … 856 1117 857 1118 error: 858 sata->i nvalid_device = true;1119 sata->is_invalid_device = true; 859 1120 if (fun != NULL) 860 1121 ddf_fun_destroy(fun); … … 863 1124 } 864 1125 1126 /** Create and initialize all SATA structure devices for connected SATA drives. 1127 * 1128 * @param ahci AHCI device structure. 1129 * @param dev DDF device structure. 1130 * 1131 */ 865 1132 static void ahci_sata_devices_create(ahci_dev_t *ahci, ddf_dev_t *dev) 866 1133 { 867 for (unsigned int port_num = 0; port_num < 32; port_num++) {1134 for (unsigned int port_num = 0; port_num < AHCI_MAX_PORTS; port_num++) { 868 1135 /* Active ports only */ 869 1136 if (!(ahci->memregs->ghc.pi & (1 << port_num))) … … 873 1140 874 1141 /* Active devices only */ 875 if ((port->pxssts & 0x0f) != 3) 1142 ahci_port_ssts_t pxssts; 1143 pxssts.u32 = port->pxssts; 1144 if (pxssts.det != AHCI_PORT_SSTS_DET_ACTIVE) 876 1145 continue; 877 1146 878 ahci_sata_device_create(ahci, dev, port, port_num); 879 } 880 } 881 1147 ahci_sata_create(ahci, dev, port, port_num); 1148 } 1149 } 1150 1151 /** Create AHCI device structure, intialize it and register interrupt routine. 1152 * 1153 * @param dev DDF device structure. 1154 * 1155 * @return AHCI device structure if succeed, NULL otherwise. 1156 * 1157 */ 882 1158 static ahci_dev_t *ahci_ahci_create(ddf_dev_t *dev) 883 1159 { … … 889 1165 890 1166 ahci->dev = dev; 1167 1168 /* Create timer for AHCI. */ 1169 ahci->timer = fibril_timer_create(); 1170 if (ahci->timer == NULL) 1171 goto error_create_timer; 891 1172 892 1173 hw_res_list_parsed_t hw_res_parsed; … … 895 1176 goto error_get_res_parsed; 896 1177 1178 /* Map AHCI registers. */ 1179 ahci->memregs = NULL; 1180 1181 physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address), 1182 AHCI_MEMREGS_PAGES_COUNT, AS_AREA_READ | AS_AREA_WRITE, 1183 (void **) &ahci->memregs); 1184 if (ahci->memregs == NULL) 1185 goto error_map_registers; 1186 897 1187 /* Register interrupt handler */ 898 1188 ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address; 899 1189 ahci_ranges[0].size = sizeof(ahci_dev_t); 1190 900 1191 ahci_cmds[0].addr = 901 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1; 1192 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1193 AHCI_GHC_GHC_REGISTER_OFFSET; 902 1194 ahci_cmds[1].addr = 903 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 2; 1195 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1196 AHCI_GHC_IS_REGISTER_OFFSET; 904 1197 ahci_cmds[2].addr = ahci_cmds[1].addr; 905 1198 906 1199 irq_code_t ct; 907 ct.cmdcount = 3;1200 ct.cmdcount = sizeof(ahci_cmds) / sizeof(irq_cmd_t); 908 1201 ct.cmds = ahci_cmds; 909 ct.rangecount = 1;1202 ct.rangecount = sizeof(ahci_ranges) / sizeof(irq_pio_range_t); 910 1203 ct.ranges = ahci_ranges; 911 1204 … … 918 1211 } 919 1212 920 if (ahci_pciintel_enable_interrupt(hw_res_parsed.irqs.irqs[0]) != EOK) { 1213 rc = ahci_enable_interrupt(hw_res_parsed.irqs.irqs[0]); 1214 if (rc != EOK) { 921 1215 ddf_msg(LVL_ERROR, "Failed enable interupt."); 922 1216 goto error_enable_interrupt; 923 1217 } 924 1218 925 /* Map AHCI register. */926 physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address),927 8, AS_AREA_READ | AS_AREA_WRITE, (void **) &ahci->memregs);928 1219 hw_res_list_parsed_clean(&hw_res_parsed); 929 930 if (ahci->memregs == NULL)931 goto error_map_registers;932 933 ahci->timer = fibril_timer_create();934 935 1220 return ahci; 936 1221 1222 error_enable_interrupt: 1223 unregister_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0]); 1224 1225 error_register_interrupt_handler: 1226 // FIXME: unmap physical memory 1227 937 1228 error_map_registers: 938 error_enable_interrupt:939 error_register_interrupt_handler:940 1229 hw_res_list_parsed_clean(&hw_res_parsed); 1230 941 1231 error_get_res_parsed: 1232 fibril_timer_destroy(ahci->timer); 1233 1234 error_create_timer: 1235 free(ahci); 942 1236 return NULL; 943 1237 } 944 1238 945 static void ahci_ahci_init(ahci_dev_t *ahci) 946 { 947 /* Enable interrupt and bus mastering */ 1239 /** Initialize and start AHCI hardware device. 1240 * 1241 * @param ahci AHCI device. 1242 * 1243 */ 1244 static void ahci_ahci_hw_start(ahci_dev_t *ahci) 1245 { 1246 /* Disable command completion coalescing feature */ 1247 ahci_ghc_ccc_ctl_t ccc; 1248 1249 ccc.u32 = ahci->memregs->ghc.ccc_ctl; 1250 ccc.en = 0; 1251 ahci->memregs->ghc.ccc_ctl = ccc.u32; 1252 1253 /* Set master latency timer. */ 1254 pci_config_space_write_8(ahci->dev->parent_sess, AHCI_PCI_MLT, 32); 1255 1256 /* Enable PCI interrupt and bus mastering */ 948 1257 ahci_pcireg_cmd_t cmd; 949 1258 … … 953 1262 pci_config_space_write_16(ahci->dev->parent_sess, AHCI_PCI_CMD, cmd.u16); 954 1263 955 /* Set master latency timer */956 pci_config_space_write_8(ahci->dev->parent_sess, AHCI_PCI_MLT, 32);957 958 /* Disable command completion coalescing feature. */959 ahci_ghc_ccc_ctl_t ccc;960 ccc.u32 = ahci->memregs->ghc.ccc_ctl;961 ccc.en = 0;962 ahci->memregs->ghc.ccc_ctl = ccc.u32;963 964 1264 /* Enable AHCI and interrupt. */ 965 1265 ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 966 967 /* Enable timer. */ 968 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci); 969 } 970 1266 } 1267 1268 /** AHCI device driver initialization 1269 * 1270 * Create and initialize all SATA structure devices for connected 1271 * SATA drives. 1272 * 1273 * @param dev DDF device structure. 1274 * 1275 * @return EOK if succeed, error code otherwise. 1276 * 1277 */ 971 1278 static int ahci_dev_add(ddf_dev_t *dev) 972 1279 { 1280 /* Connect to parent device */ 973 1281 dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE, 974 1282 dev->handle, IPC_FLAG_BLOCKING); … … 978 1286 ahci_dev_t *ahci = ahci_ahci_create(dev); 979 1287 if (ahci == NULL) 980 return EINTR;1288 goto error; 981 1289 982 1290 dev->driver_data = ahci; 983 ahci_ahci_init(ahci); 1291 1292 /* Set timer and AHCI hardware start. */ 1293 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci); 1294 ahci_ahci_hw_start(ahci); 1295 1296 /* Create device structures for sata devices attached to AHCI. */ 984 1297 ahci_sata_devices_create(ahci, dev); 985 1298 986 1299 return EOK; 1300 1301 error: 1302 async_hangup(dev->parent_sess); 1303 return EINTR; 987 1304 } 988 1305 … … 991 1308 /*----------------------------------------------------------------------------*/ 992 1309 1310 /** Convert SATA model name 1311 * 1312 * Convert SATA model name from machine format returned by 1313 * identify device command to human readable form. 1314 * 1315 * @param src Source buffer with device name in machine format. 1316 * @param dst Buffer for human readable string, minimum size is 41 chars. 1317 * 1318 */ 993 1319 static void ahci_get_model_name(uint16_t *src, char *dst) 994 1320 { … … 1018 1344 } 1019 1345 1020 static int ahci_pciintel_enable_interrupt(int irq) 1346 /** Enable interrupt using SERVICE_IRC. 1347 * 1348 * @param irq Requested irq number. 1349 * 1350 * @return EOK if succeed, error code otherwise. 1351 * 1352 */ 1353 static int ahci_enable_interrupt(int irq) 1021 1354 { 1022 1355 async_sess_t *irc_sess = NULL; 1023 1356 irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_IRC, 0, 0); 1024 1025 1357 if (!irc_sess) 1026 1358 return EINTR; -
uspace/drv/block/ahci/ahci.h
r730dce77 rae3ff9f5 46 46 47 47 /** Pointer to AHCI memory registers. */ 48 ahci_memregs_t *memregs;48 volatile ahci_memregs_t *memregs; 49 49 50 50 /** AHCI device global timer. */ … … 53 53 /** Pointers to sata devices. */ 54 54 void *sata_devs[32]; 55 56 /** Device has harware interrupt. */ 57 bool is_hw_interrupt; 55 58 } ahci_dev_t; 56 59 … … 64 67 65 68 /** Port interrupt states shadow registers. */ 66 volatileahci_port_is_t shadow_pxis;69 ahci_port_is_t shadow_pxis; 67 70 68 71 /** Device in invalid state (disconnected and so on). */ 69 volatile boolinvalid_device;72 bool is_invalid_device; 70 73 71 74 /** Pointer to SATA port. */ 72 75 volatile ahci_port_t *port; 76 73 77 /** Pointer to command header. */ 74 78 volatile ahci_cmdhdr_t *cmd_header; 79 75 80 /** Pointer to command table. */ 76 81 volatile uint32_t *cmd_table; … … 78 83 /** Mutex for single operation on device. */ 79 84 fibril_mutex_t lock; 85 86 /** Mutex for port interrupt state register manipulation. */ 87 fibril_mutex_t pxis_lock; 80 88 81 89 /** Mutex for event signaling condition variable. */ … … 96 104 97 105 /** Device in invalid state (disconnected and so on). */ 98 bool packet_device;106 bool is_packet_device; 99 107 100 108 /** Highest UDMA mode supported. */ -
uspace/drv/block/ahci/ahci_hw.h
r730dce77 rae3ff9f5 35 35 36 36 #include <sys/types.h> 37 38 /*----------------------------------------------------------------------------*/ 39 /*-- AHCI standard constants -------------------------------------------------*/ 40 /*----------------------------------------------------------------------------*/ 41 42 /** AHCI standard 1.3 - maximum ports. */ 43 #define AHCI_MAX_PORTS 32 37 44 38 45 /*----------------------------------------------------------------------------*/ … … 198 205 typedef union { 199 206 struct { 200 207 /** Header layout. */ 201 208 unsigned int hl : 7; 202 /** Multi function device . */209 /** Multi function device flag. */ 203 210 unsigned int mfd : 1; 204 211 }; … … 281 288 typedef struct 282 289 { 283 /** Indicates the minimum grant time (in ? microseconds)284 * that the devicewishes grant asserted.290 /** Indicates the minimum grant time that the device 291 * wishes grant asserted. 285 292 */ 286 293 uint8_t u8; … … 297 304 /*-- AHCI Memory Registers ---------------------------------------------------*/ 298 305 /*----------------------------------------------------------------------------*/ 306 307 /** Number of pages for ahci memory registers. */ 308 #define AHCI_MEMREGS_PAGES_COUNT 8 299 309 300 310 /** AHCI Memory register Generic Host Control - HBA Capabilities. */ … … 364 374 } ahci_ghc_ghc_t; 365 375 376 /** AHCI GHC register offset. */ 377 #define AHCI_GHC_GHC_REGISTER_OFFSET 1 378 366 379 /** AHCI Enable mask bit. */ 367 380 #define AHCI_GHC_GHC_AE 0x80000000 … … 377 390 uint32_t u32; 378 391 } ahci_ghc_is_t; 392 393 /** AHCI GHC register offset. */ 394 #define AHCI_GHC_IS_REGISTER_OFFSET 2 379 395 380 396 /** AHCI Memory register Ports implemented. */ … … 427 443 /** Size of the transmit message buffer area in dwords. */ 428 444 uint16_t sz; 429 /* Offset of the transmit message buffer area in dwords 445 /* 446 * Offset of the transmit message buffer area in dwords 430 447 * from the beginning of ABAR 431 448 */ … … 462 479 /** Activity LED hardware driven. */ 463 480 unsigned int alhd : 1; 464 /** port multiplier support. */481 /** Port multiplier support. */ 465 482 unsigned int pm : 1; 466 483 /** Reserved. */ … … 509 526 typedef struct 510 527 { 511 /** Host Capabilities .*/528 /** Host Capabilities */ 512 529 uint32_t cap; 513 /** Global Host Control .*/530 /** Global Host Control */ 514 531 uint32_t ghc; 515 /** Interrupt Status .*/532 /** Interrupt Status */ 516 533 uint32_t is; 517 /** Ports Implemented .*/534 /** Ports Implemented */ 518 535 uint32_t pi; 519 /** Version .*/536 /** Version */ 520 537 uint32_t vs; 521 /** Command Completion Coalescing Control .*/538 /** Command Completion Coalescing Control */ 522 539 uint32_t ccc_ctl; 523 /** Command Completion Coal secing Ports.*/540 /** Command Completion Coalescing Ports */ 524 541 uint32_t ccc_ports; 525 /** Enclosure Management Location .*/542 /** Enclosure Management Location */ 526 543 uint32_t em_loc; 527 /** Enclosure Management Control .*/544 /** Enclosure Management Control */ 528 545 uint32_t em_ctl; 529 /** Host Capabilities Extended .*/546 /** Host Capabilities Extended */ 530 547 uint32_t cap2; 531 /** BIOS/OS Handoff Control and Status .*/548 /** BIOS/OS Handoff Control and Status */ 532 549 uint32_t bohc; 533 550 } ahci_ghc_t; … … 817 834 * Values: 818 835 * 7h - fh Reserved, 819 * 6h Slumber - This shall cause the HBA to request a transition of the820 * 836 * 6h Slumber - This shall cause the HBA to request a transition 837 * of the interface to the Slumber state, 821 838 * 3h - 5h Reserved, 822 * 2h Partial - This shall cause the HBA to request a transition of the823 * 839 * 2h Partial - This shall cause the HBA to request a transition 840 * of the interface to the Partial state, 824 841 * 1h Active, 825 842 * 0h No-Op / Idle. … … 856 873 /** LBA Mid Register */ 857 874 uint8_t lba_mr; 858 /** 875 /** LBA High Register */ 859 876 uint8_t lba_hr; 860 877 }; … … 876 893 uint32_t u32; 877 894 } ahci_port_ssts_t; 895 896 /** Device detection active status. */ 897 #define AHCI_PORT_SSTS_DET_ACTIVE 3 878 898 879 899 /** AHCI Memory register Port x Serial ATA Control (SCR2: SControl). */ … … 1010 1030 ahci_ghc_t ghc; 1011 1031 /** Reserved. */ 1012 uint 8_t reserved[52];1032 uint32_t reserved[13]; 1013 1033 /** Reserved for NVMHCI. */ 1014 uint 8_t reservedfornvmhci[64];1034 uint32_t reservedfornvmhci[16]; 1015 1035 /** Vendor Specific registers. */ 1016 uint 8_t vendorspecificsregs[96];1036 uint32_t vendorspecificsregs[24]; 1017 1037 /** Ports. */ 1018 1038 ahci_port_t ports[32]; 1019 1039 } ahci_memregs_t; 1020 1040 1021 /** AHCI Command header entry. */ 1041 /** AHCI Command header entry. 1042 * 1043 * This structure is not an AHCI register. 1044 * 1045 */ 1022 1046 typedef volatile struct { 1023 1047 /** Flags. */ … … 1033 1057 } ahci_cmdhdr_t; 1034 1058 1035 /** AHCI Command Physical Region Descriptor entry. */ 1059 /** Clear Busy upon R_OK (C) flag. */ 1060 #define AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK 0x0400 1061 1062 /** Write operation flag. */ 1063 #define AHCI_CMDHDR_FLAGS_WRITE 0x0040 1064 1065 /** 2 DW length command flag. */ 1066 #define AHCI_CMDHDR_FLAGS_2DWCMD 0x0002 1067 1068 /** 5 DW length command flag. */ 1069 #define AHCI_CMDHDR_FLAGS_5DWCMD 0x0005 1070 1071 /** AHCI Command Physical Region Descriptor entry. 1072 * 1073 * This structure is not an AHCI register. 1074 * 1075 */ 1036 1076 typedef volatile struct { 1037 1077 /** Word aligned 32-bit data base address. */ … … 1045 1085 /** Reserved */ 1046 1086 unsigned int reserved2 : 9; 1047 /** Interrupton completion */1087 /** Set Interrupt on each operation completion */ 1048 1088 unsigned int ioc : 1; 1049 1089 } ahci_cmd_prdt_t; -
uspace/drv/block/ahci/ahci_sata.h
r730dce77 rae3ff9f5 36 36 #include <sys/types.h> 37 37 38 /*----------------------------------------------------------------------------*/ 39 /*-- SATA Buffer Lengths -----------------------------------------------------*/ 40 /*----------------------------------------------------------------------------*/ 41 42 /** Default sector size in bytes. */ 43 #define SATA_DEFAULT_SECTOR_SIZE 512 44 45 /** Size for set feature command buffer in bytes. */ 46 #define SATA_SET_FEATURE_BUFFER_LENGTH 512 47 48 /** Size for indentify (packet) device buffer in bytes. */ 49 #define SATA_IDENTIFY_DEVICE_BUFFER_LENGTH 512 50 51 /*----------------------------------------------------------------------------*/ 52 /*-- SATA Fis Frames ---------------------------------------------------------*/ 53 /*----------------------------------------------------------------------------*/ 54 55 /** Sata FIS Type number. */ 56 #define SATA_CMD_FIS_TYPE 0x27 57 58 /** Sata FIS Type command indicator. */ 59 #define SATA_CMD_FIS_COMMAND_INDICATOR 0x80 60 38 61 /** Standard Command frame. */ 39 62 typedef struct { 40 /** FIS type - always 0x27. */63 /** FIS type - always SATA_CMD_FIS_TYPE. */ 41 64 unsigned int fis_type : 8; 42 /** Indicate that FIS is a Command - always 0x80. */65 /** Indicate that FIS is a Command - always SATA_CMD_FIS_COMMAND_INDICATOR. */ 43 66 unsigned int c : 8; 44 67 /** Command - Identity device - 0xec, Set fetures - 0xef. */ … … 62 85 /** Reserved. */ 63 86 unsigned int reserved2 : 32; 64 } s td_command_frame_t;87 } sata_std_command_frame_t; 65 88 66 89 /** Command frame for NCQ data operation. */ … … 68 91 /** FIS type - always 0x27. */ 69 92 uint8_t fis_type; 70 /** Indicate that FIS is a Command - always 0x80. */93 /** Indicate that FIS is a Command - always SATA_CMD_FIS_COMMAND_INDICATOR. */ 71 94 uint8_t c; 72 95 /** Command - FPDMA Read - 0x60, FPDMA Write - 0x61. */ … … 105 128 /** Reserved. */ 106 129 uint8_t reserved6; 107 } ncq_command_frame_t; 130 } sata_ncq_command_frame_t; 131 132 /*----------------------------------------------------------------------------*/ 133 /*-- SATA Identify device ----------------------------------------------------*/ 134 /*----------------------------------------------------------------------------*/ 108 135 109 136 /** Data returned from identify device and identify packet device command. */ … … 129 156 uint16_t max_rw_multiple; 130 157 uint16_t reserved48; 131 /* *Different meaning for packet device. */158 /* Different meaning for packet device. */ 132 159 uint16_t caps; 133 160 uint16_t reserved50; … … 183 210 uint16_t total_lba48_3; 184 211 212 uint16_t reserved104[1 + 105 - 104]; 213 uint16_t physical_logic_sector_size; 185 214 /* Note: more fields are defined in ATA/ATAPI-7. */ 186 uint16_t reserved10 4[1 + 127 - 104];187 uint16_t _vs128[1 + 159 - 128];215 uint16_t reserved107[1 + 127 - 107]; 216 uint16_t reserved128[1 + 159 - 128]; 188 217 uint16_t reserved160[1 + 255 - 160]; 189 } identify_data_t;218 } sata_identify_data_t; 190 219 191 220 /** Capability bits for register device. */ 192 enum ata_regdev_caps {193 rd_cap_iordy = 0x0800,194 rd_cap_iordy_cbd = 0x0400,195 rd_cap_lba = 0x0200,196 rd_cap_dma = 0x0100221 enum sata_rd_caps { 222 sata_rd_cap_iordy = 0x0800, 223 sata_rd_cap_iordy_cbd = 0x0400, 224 sata_rd_cap_lba = 0x0200, 225 sata_rd_cap_dma = 0x0100 197 226 }; 198 227 199 228 /** Bits of @c identify_data_t.cmd_set1. */ 200 enum ata_cs1 {229 enum sata_cs1 { 201 230 /** 48-bit address feature set. */ 202 cs1_addr48 = 0x0400231 sata_cs1_addr48 = 0x0400 203 232 }; 204 233 205 234 /** SATA capatibilities for not packet device - Serial ATA revision 3_1. */ 206 enum sata_np_cap {235 enum sata_np_caps { 207 236 /** Supports READ LOG DMA EXT. */ 208 np_cap_log_ext = 0x8000,237 sata_np_cap_log_ext = 0x8000, 209 238 /** Supports Device Automatic Partial to Slumber transitions. */ 210 np_cap_dev_slm = 0x4000,239 sata_np_cap_dev_slm = 0x4000, 211 240 /** Supports Host Automatic Partial to Slumber transitions. */ 212 np_cap_host_slm = 0x2000,241 sata_np_cap_host_slm = 0x2000, 213 242 /** Supports NCQ priority information. */ 214 np_cap_ncq_prio = 0x1000,243 sata_np_cap_ncq_prio = 0x1000, 215 244 /** Supports Unload while NCQ command outstanding. */ 216 np_cap_unload_ncq = 0x0800,245 sata_np_cap_unload_ncq = 0x0800, 217 246 /** Supports Phy event counters. */ 218 np_cap_phy_ctx = 0x0400,247 sata_np_cap_phy_ctx = 0x0400, 219 248 /** Supports recepits of host-initiated interface power management. */ 220 np_cap_host_pmngmnt = 0x0200,249 sata_np_cap_host_pmngmnt = 0x0200, 221 250 222 251 /** Supports NCQ. */ 223 np_cap_ncq = 0x0100,252 sata_np_cap_ncq = 0x0100, 224 253 225 254 /** Supports SATA 3. */ 226 np_cap_sata_3 = 0x0008,255 sata_np_cap_sata_3 = 0x0008, 227 256 /** Supports SATA 2. */ 228 np_cap_sata_2 = 0x0004,257 sata_np_cap_sata_2 = 0x0004, 229 258 /** Supports SATA 1. */ 230 np_cap_sata_1 = 0x0002259 sata_np_cap_sata_1 = 0x0002 231 260 }; 232 261 233 262 /** SATA capatibilities for packet device - Serial ATA revision 3_1. */ 234 enum sata_pt_cap {263 enum sata_pt_caps { 235 264 /** Supports READ LOG DMA EXT. */ 236 pt_cap_log_ext = 0x8000,265 sata_pt_cap_log_ext = 0x8000, 237 266 /** Supports Device Automatic Partial to Slumber transitions. */ 238 pt_cap_dev_slm = 0x4000,267 sata_pt_cap_dev_slm = 0x4000, 239 268 /** Supports Host Automatic Partial to Slumber transitions. */ 240 pt_cap_host_slm = 0x2000,269 sata_pt_cap_host_slm = 0x2000, 241 270 /** Supports Phy event counters. */ 242 pt_cap_phy_ctx = 0x0400,271 sata_pt_cap_phy_ctx = 0x0400, 243 272 /** Supports recepits of host-initiated interface power management. */ 244 pt_cap_host_pmngmnt = 0x0200,273 sata_pt_cap_host_pmngmnt = 0x0200, 245 274 246 275 /** Supports SATA 3. */ 247 pt_cap_sat_3 = 0x0008,276 sata_pt_cap_sat_3 = 0x0008, 248 277 /** Supports SATA 2. */ 249 pt_cap_sat_2 = 0x0004,278 sata_pt_cap_sat_2 = 0x0004, 250 279 /** Supports SATA 1. */ 251 pt_cap_sat_1 = 0x0002280 sata_pt_cap_sat_1 = 0x0002 252 281 }; 253 282 -
uspace/srv/bd/sata_bd/sata_bd.c
r730dce77 rae3ff9f5 51 51 #define NAMESPACE "bd" 52 52 53 #define MAXDISKS 256 54 55 static sata_dev_t disk[MAXDISKS]; 53 /** Maximum number of disks handled */ 54 #define MAXDISKS 256 55 56 static sata_bd_dev_t disk[MAXDISKS]; 56 57 static int disk_count; 57 58 59 /** Find SATA devices in device tree. 60 * 61 * @param Device manager handle describing container for searching. 62 * 63 * @return EOK if succeed, error code otherwise. 64 * 65 */ 58 66 static int scan_device_tree(devman_handle_t funh) 59 67 { … … 107 115 } 108 116 109 /** Find sata devices in device tree from root. */ 117 /** Find sata devices in device tree from root. 118 * 119 * @return EOK if succeed, error code otherwise. 120 * 121 */ 110 122 static int get_sata_disks() 111 123 { -
uspace/srv/bd/sata_bd/sata_bd.h
r730dce77 rae3ff9f5 41 41 #include <loc.h> 42 42 43 /** SATA Device. */43 /** SATA Block Device. */ 44 44 typedef struct { 45 45 /** Device name in device tree. */ … … 55 55 /** Size of block. */ 56 56 size_t block_size; 57 } sata_ dev_t;57 } sata_bd_dev_t; 58 58 59 59 #endif
Note:
See TracChangeset
for help on using the changeset viewer.