diff --git a/include/sata.h b/include/sata.h index 312b111..8173e72 100644 --- a/include/sata.h +++ b/include/sata.h @@ -26,7 +26,7 @@ void sata_free_request(struct sata_request *req); void sata_add_dma_region(struct sata_request *req, struct pa pa, uint64_t size); void sata_set_callback(struct sata_request *req, sata_request_callback callback, void *userdata); void sata_set_read(struct sata_request *req, uint64_t start_sector, uint64_t num_sectors); -bool sata_dispatch_request(unsigned drive_id, int slot, struct sata_request *req); +bool sata_dispatch_request(unsigned drive_id, struct sata_request *req); void sata_read_and_dump(unsigned drive_id, uint64_t addr); diff --git a/src/sata.c b/src/sata.c index 6917411..8159dbd 100644 --- a/src/sata.c +++ b/src/sata.c @@ -700,13 +700,22 @@ sata_set_read(struct sata_request *req, uint64_t start_sector, uint64_t num_sect cmd_fis->counth = (num_sectors >> 8) & 0xFF; } -bool sata_dispatch_request(unsigned drive_id, int slot, struct sata_request *req) +bool sata_dispatch_request(unsigned drive_id, struct sata_request *req) { unsigned port_num = drive_id & 0xFF; struct hba_context *hba = &sata_hbas[drive_id >> 8]; struct port_context *pctx = &hba->ports[port_num]; volatile HBA_PORT *port = pctx->port_mem; + unsigned slot = 0; + while (slot < hba->max_slots) { + if (!(port->ci & (1 << slot))) break; + slot++; + } + if (slot >= hba->max_slots) { + return false; + } + uint64_t ctb = pa_to_value(req->my_pa) + 128; volatile HBA_CMD_HEADER *cmd_hdr = &pctx->cmd_list_ptr[slot]; @@ -729,7 +738,7 @@ bool sata_dispatch_request(unsigned drive_id, int slot, struct sata_request *req } if (spin == 1000000) { printf("AHCI Port %d is hung\n", port_num); - int_restore(saved_flags); + int_restore(saved_flags); return false; } @@ -741,36 +750,6 @@ bool sata_dispatch_request(unsigned drive_id, int slot, struct sata_request *req __asm__ volatile ("" ::: "memory"); return true; - -#if 0 - // Wait for completion - for (;;) { - // In some longer duration reads, it may be helpful to spin on the DPS bit - // in the PxIS port field as well (1 << 5) - if ((port->ci & (1 << slot)) == 0) { - break; - } - if (port->is & (1u << 30)) { // Task file error - printf("SATA Request Error\n"); - int_restore(saved_flags); - return false; - } - } - - // Check again - if (port->is & (1u << 30)) { - printf("SATA Request Error\n"); - int_restore(saved_flags); - return false; - } - - if (req->callback != NULL) { - req->callback(req->userdata); - } - - int_restore(saved_flags); - return true; -#endif } static void sata_dump_callback(void *userdata) @@ -802,7 +781,7 @@ void sata_read_and_dump(unsigned drive_id, uint64_t addr) sata_set_read(req, addr, 1); sata_add_dma_region(req, pctx->buffer_pa, 512); sata_set_callback(req, sata_dump_callback, (void *)pctx->buffer_ptr); - bool success = sata_dispatch_request(port_num, 0, req); + bool success = sata_dispatch_request(port_num, req); //sata_free_request(req); if (!success) {