X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/8c06c883e7b13c115d5ff207f79d4b68fccd5ad6..f89517343bf062d299d54408eea2f9387bfefb6d:/lunaix-os/hal/ahci/ahci.c diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index 33dc87e..5ff1cc2 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -14,16 +14,13 @@ #include #include -#include -#include +#include #include #include -#include #include -#include #include -#include +#include #include #include @@ -31,13 +28,13 @@ #define HBA_CLB_SIZE 1024 #define HBA_MY_IE (HBA_PxINTR_DHR | HBA_PxINTR_TFE | HBA_PxINTR_OF) -#define AHCI_DEVCLASS DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA) +#define AHCI_DEVCLASS DEVCLASS(LUNAIX, STORAGE, SATA) // #define DO_HBA_FULL_RESET LOG_MODULE("AHCI") -DEFINE_LLIST(ahcis); +static DEFINE_LLIST(ahcis); static char sata_ifs[][20] = { "Not detected", "SATA I (1.5Gbps)", @@ -49,9 +46,6 @@ static struct devclass ahci_class = AHCI_DEVCLASS; extern void ahci_fsexport(struct block_dev* bdev, void* fs_node); -extern void -__ahci_hba_isr(const isr_param* param); - extern void __ahci_blkio_handler(struct blkio_req* req); @@ -80,32 +74,17 @@ __hba_reset_port(hba_reg_t* port_reg) port_reg[HBA_RPxSCTL] &= ~0xf; } -int -ahci_driver_init(struct device_def* def, struct device* dev) +struct ahci_driver* +ahci_driver_init(struct ahci_driver_param* param) { - struct pci_device* ahci_dev = container_of(dev, struct pci_device, dev); - - struct pci_base_addr* bar6 = &ahci_dev->bar[5]; - assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO."); - - pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD); - - // 禁用传统中断(因为我们使用MSI),启用MMIO访问,允许PCI设备间访问 - cmd |= (PCI_RCMD_MM_ACCESS | PCI_RCMD_DISABLE_INTR | PCI_RCMD_BUS_MASTER); - - pci_write_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD, cmd); - - int iv = isrm_ivexalloc(__ahci_hba_isr); - pci_setup_msi(ahci_dev, iv); - isrm_set_payload(iv, (ptr_t)&ahcis); - struct ahci_driver* ahci_drv = vzalloc(sizeof(*ahci_drv)); struct ahci_hba* hba = &ahci_drv->hba; - ahci_drv->id = iv; + ahci_drv->id = param->irq->vector; + irq_set_payload(param->irq, &ahcis); llist_append(&ahcis, &ahci_drv->ahci_drvs); - hba->base = (hba_reg_t*)ioremap(bar6->start, bar6->size); + hba->base = (hba_reg_t*)ioremap(param->mmio_base, param->mmio_size); #ifdef DO_HBA_FULL_RESET // 重置HBA @@ -145,16 +124,19 @@ ahci_driver_init(struct device_def* def, struct device* dev) __hba_reset_port(port_regs); #endif + struct leaflet* leaflet; if (!clbp) { // 每页最多4个命令队列 - clb_pa = pmm_alloc_page(KERNEL_PID, PP_FGLOCKED); - clb_pg_addr = (ptr_t)ioremap(clb_pa, 0x1000); + leaflet = alloc_leaflet(0); + clb_pa = leaflet_addr(leaflet); + clb_pg_addr = vmap(leaflet, KERNEL_DATA); memset((void*)clb_pg_addr, 0, 0x1000); } if (!fisp) { // 每页最多16个FIS - fis_pa = pmm_alloc_page(KERNEL_PID, PP_FGLOCKED); - fis_pg_addr = (ptr_t)ioremap(fis_pa, 0x1000); + leaflet = alloc_leaflet(0); + fis_pa = leaflet_addr(leaflet); + fis_pg_addr = vmap(leaflet, KERNEL_DATA); memset((void*)fis_pg_addr, 0, 0x1000); } @@ -186,7 +168,7 @@ ahci_driver_init(struct device_def* def, struct device* dev) port_regs[HBA_RPxCMD] |= HBA_PxCMD_ST; if (!ahci_init_device(port)) { - kprintf(KERROR "init fail: 0x%x@p%d", port->regs[HBA_RPxSIG], i); + ERROR("init fail: 0x%x@p%d", port->regs[HBA_RPxSIG], i); continue; } @@ -200,8 +182,7 @@ ahci_driver_init(struct device_def* def, struct device* dev) ahci_register_device(hbadev); } - pci_bind_instance(ahci_dev, ahci_drv); - return 0; + return ahci_drv; } void @@ -272,6 +253,7 @@ hba_bind_vbuf(struct hba_cmdh* cmdh, struct hba_cmdt* cmdt, struct vecbuf* vbuf) do { assert_msg(i < HBA_MAX_PRDTE, "HBA: Too many PRDTEs"); assert_msg(pos->buf.size <= 0x400000U, "HBA: Buffer too big"); + assert_msg(pos->buf.size, "HBA: expect a non-zero buffer size"); cmdt->entries[i++] = (struct hba_prdte){ .data_base = vmm_v2p((ptr_t)pos->buf.buffer), @@ -427,6 +409,7 @@ int ahci_identify_device(struct hba_device* device) { // 用于重新识别设备(比如在热插拔的情况下) + // FIXME this is not right... vfree(device); return ahci_init_device(device->port); } @@ -441,12 +424,3 @@ achi_register_ops(struct hba_port* port) port->device->ops.submit = scsi_submit; } } - -static struct pci_device_def ahcidef = { - .dev_class = AHCI_HBA_CLASS, - .ident_mask = PCI_MATCH_ANY, - .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA), - .name = "Serial ATA Controller", - .bind = ahci_driver_init } -}; -EXPORT_PCI_DEVICE(ahci, &ahcidef); \ No newline at end of file