Fix several AHCI problems
This commit is contained in:
parent
ee2b985ef6
commit
908a8fc37a
1 changed files with 18 additions and 10 deletions
|
@ -56,10 +56,12 @@ struct grub_ahci_hba_port
|
|||
grub_uint32_t intstatus;
|
||||
grub_uint32_t inten;
|
||||
grub_uint32_t command;
|
||||
grub_uint32_t unused1[6];
|
||||
grub_uint32_t unused1[3];
|
||||
grub_uint32_t status;
|
||||
grub_uint32_t unused2[2];
|
||||
grub_uint32_t sata_active;
|
||||
grub_uint32_t command_issue;
|
||||
grub_uint32_t unused2[17];
|
||||
grub_uint32_t unused3[17];
|
||||
};
|
||||
|
||||
struct grub_ahci_hba
|
||||
|
@ -195,6 +197,10 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
|||
if (!(hba->ports_implemented & (1 << i)))
|
||||
continue;
|
||||
|
||||
/* FIXME: support hotplugging. */
|
||||
if (!hba->ports[i].status)
|
||||
continue;
|
||||
|
||||
command_list = grub_memalign_dma32 (1024,
|
||||
sizeof (struct grub_ahci_cmd_head));
|
||||
if (!command_list)
|
||||
|
@ -333,9 +339,12 @@ grub_ahci_readwrite (grub_ata_t disk,
|
|||
parms->cmdsize);
|
||||
|
||||
dev->command_table[0].cfis[0] = GRUB_AHCI_FIS_REG_H2D;
|
||||
dev->command_table[0].cfis[1] = 0x80;
|
||||
for (i = 0; i < sizeof (parms->taskfile.raw); i++)
|
||||
dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i];
|
||||
|
||||
dev->command_table[0].cfis[7] |= (parms->cmdsize ? 0 : 0xE0);
|
||||
|
||||
dev->command_table[0].prdt[0].data_base = grub_dma_get_phys (bufc);
|
||||
dev->command_table[0].prdt[0].unused = 0;
|
||||
dev->command_table[0].prdt[0].size = (parms->size + (parms->size & 1) - 1)
|
||||
|
@ -345,8 +354,8 @@ grub_ahci_readwrite (grub_ata_t disk,
|
|||
grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size);
|
||||
|
||||
grub_dprintf ("ahci", "AHCI command schedulded\n");
|
||||
dev->hba->ports[dev->port].inten = (1 << 5);
|
||||
dev->hba->ports[dev->port].intstatus = (1 << 5);
|
||||
dev->hba->ports[dev->port].inten = (1 << 2) | (1 << 5);
|
||||
dev->hba->ports[dev->port].intstatus = (1 << 2) | (1 << 5);
|
||||
dev->hba->ports[dev->port].command_issue |= 1;
|
||||
dev->hba->ports[dev->port].command |= 1;
|
||||
|
||||
|
@ -362,6 +371,7 @@ grub_ahci_readwrite (grub_ata_t disk,
|
|||
|
||||
grub_dprintf ("ahci", "AHCI command completed succesfully\n");
|
||||
dev->hba->ports[dev->port].command &= ~1;
|
||||
dev->hba->ports[dev->port].command_issue &= ~1;
|
||||
|
||||
if (!parms->write)
|
||||
grub_memcpy (parms->buffer, (char *) grub_dma_get_virt (bufc), parms->size);
|
||||
|
@ -379,10 +389,8 @@ grub_ahci_open (int id, int devnum, struct grub_ata *ata)
|
|||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an AHCI device");
|
||||
|
||||
FOR_LIST_ELEMENTS(dev, grub_ahci_devices)
|
||||
{
|
||||
if (dev->num == devnum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (! dev)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such AHCI device");
|
||||
|
|
Loading…
Reference in a new issue