X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/8b3a34da459067723ad288b2eb51a14473e0944f..af8e873ae38b72a56a89485c62bb5ccd22a9f8a7:/lunaix-os/hal/ahci/ahci.c diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index aadb41b..a04bca7 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,7 @@ LOG_MODULE("AHCI") static struct ahci_hba hba; void -__ahci_hba_isr(isr_param param); +__ahci_hba_isr(const isr_param* param); int ahci_init_device(struct hba_port* port); @@ -160,8 +161,6 @@ ahci_init() // 需要通过全部置位去清空这些寄存器(相当的奇怪……) port_regs[HBA_RPxSERR] = -1; - port_regs[HBA_RPxIE] |= (HBA_PxINTR_DPS); - hba.ports[i] = port; if (!HBA_RPxSSTS_IF(port->ssts)) { @@ -175,6 +174,8 @@ ahci_init() if (!ahci_init_device(port)) { kprintf(KERROR "fail to init device"); } + + block_mount_disk(port->device); } } @@ -184,9 +185,10 @@ char sata_ifs[][20] = { "Not detected", "SATA III (6.0Gbps)" }; void -__ahci_hba_isr(isr_param param) +__ahci_hba_isr(const isr_param* param) { - // TODO: hba interrupt + // TODO: clear the interrupt status + // TODO: I/O-operation scheduler should be here kprintf(KDEBUG "HBA INTR\n"); } @@ -277,7 +279,7 @@ hba_prepare_cmd(struct hba_port* port, // 构建命令头(Command Header)和命令表(Command Table) struct hba_cmdh* cmd_header = &port->cmdlst[slot]; - struct hba_cmdt* cmd_table = vcalloc_dma(sizeof(struct hba_cmdt)); + struct hba_cmdt* cmd_table = vzalloc_dma(sizeof(struct hba_cmdt)); memset(cmd_header, 0, sizeof(*cmd_header)); @@ -290,7 +292,7 @@ hba_prepare_cmd(struct hba_port* port, cmd_header->prdt_len = 1; cmd_table->entries[0] = (struct hba_prdte){ .data_base = vmm_v2p(buffer), - .byte_count = (size - 1) | (0x80000000) }; + .byte_count = size - 1 }; } *cmdh = cmd_header; @@ -306,6 +308,9 @@ ahci_init_device(struct hba_port* port) struct hba_cmdt* cmd_table; struct hba_cmdh* cmd_header; + // mask DHR interrupt + port->regs[HBA_RPxIE] &= ~HBA_PxINTR_DHR; + // 确保端口是空闲的 wait_until(!(port->regs[HBA_RPxTFD] & (HBA_PxTFD_BSY))); @@ -316,7 +321,8 @@ ahci_init_device(struct hba_port* port) // 清空任何待响应的中断 port->regs[HBA_RPxIS] = 0; - port->device = vcalloc(sizeof(struct hba_device)); + port->device = vzalloc(sizeof(struct hba_device)); + port->device->port = port; // 在命令表中构建命令FIS struct sata_reg_fis* cmd_fis = (struct sata_reg_fis*)cmd_table->command_fis; @@ -398,6 +404,9 @@ ahci_init_device(struct hba_port* port) scsi_parse_capacity(port->device, (uint32_t*)data_in); done: + // reset interrupt status and unmask D2HR interrupt + port->regs[HBA_RPxIS] = -1; + port->regs[HBA_RPxIE] |= HBA_PxINTR_DHR; achi_register_ops(port); vfree_dma(data_in); @@ -406,6 +415,8 @@ done: return 1; fail: + port->regs[HBA_RPxIS] = -1; + port->regs[HBA_RPxIE] |= HBA_PxINTR_DHR; vfree_dma(data_in); vfree_dma(cmd_table); @@ -413,11 +424,11 @@ fail: } int -ahci_identify_device(struct hba_port* port) +ahci_identify_device(struct hba_device* device) { // 用于重新识别设备(比如在热插拔的情况下) - vfree(port->device); - return ahci_init_device(port); + vfree(device); + return ahci_init_device(device->port); } void