SATA: Choose first available command slot
This commit is contained in:
parent
c95623a976
commit
a7a2ffeb59
2 changed files with 13 additions and 34 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
45
src/sata.c
45
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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue