mptbase.c
来自「linux 内核源代码」· C语言 代码 · 共 2,293 行 · 第 1/5 页
C
2,293 行
break; case MPI_MANUFACTPAGE_DEVID_SAS1068E: switch (revision) { case 0x00: product_str = "LSISAS1068E A0"; break; case 0x01: product_str = "LSISAS1068E B0"; break; case 0x02: product_str = "LSISAS1068E B1"; break; case 0x04: product_str = "LSISAS1068E B2"; break; case 0x08: product_str = "LSISAS1068E B3"; break; default: product_str = "LSISAS1068E"; break; } break; case MPI_MANUFACTPAGE_DEVID_SAS1078: switch (revision) { case 0x00: product_str = "LSISAS1078 A0"; break; case 0x01: product_str = "LSISAS1078 B0"; break; case 0x02: product_str = "LSISAS1078 C0"; break; case 0x03: product_str = "LSISAS1078 C1"; break; case 0x04: product_str = "LSISAS1078 C2"; break; default: product_str = "LSISAS1078"; break; } break; } out: if (product_str) sprintf(prod_name, "%s", product_str);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** * mpt_attach - Install a PCI intelligent MPT adapter. * @pdev: Pointer to pci_dev structure * @id: PCI device ID information * * This routine performs all the steps necessary to bring the IOC of * a MPT adapter to a OPERATIONAL state. This includes registering * memory regions, registering the interrupt, and allocating request * and reply memory pools. * * This routine also pre-fetches the LAN MAC address of a Fibre Channel * MPT adapter. * * Returns 0 for success, non-zero for failure. * * TODO: Add support for polled controllers */intmpt_attach(struct pci_dev *pdev, const struct pci_device_id *id){ MPT_ADAPTER *ioc; u8 __iomem *mem; u8 __iomem *pmem; unsigned long mem_phys; unsigned long port; u32 msize; u32 psize; int ii; u8 cb_idx; int r = -ENODEV; u8 revision; u8 pcixcmd; static int mpt_ids = 0;#ifdef CONFIG_PROC_FS struct proc_dir_entry *dent, *ent;#endif if (mpt_debug_level) printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); if (pci_enable_device(pdev)) return r; ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); if (ioc == NULL) { printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; } ioc->debug_level = mpt_debug_level; ioc->id = mpt_ids++; sprintf(ioc->name, "ioc%d", ioc->id); dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { dprintk(ioc, printk(MYIOC_s_INFO_FMT ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name)); } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n", ioc->name); kfree(ioc); return r; } if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { dprintk(ioc, printk(MYIOC_s_INFO_FMT ": Using 64 bit consistent mask\n", ioc->name)); } else { dprintk(ioc, printk(MYIOC_s_INFO_FMT ": Not using 64 bit consistent mask\n", ioc->name)); } ioc->alloc_total = sizeof(MPT_ADAPTER); ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->pcidev = pdev; ioc->diagPending = 0; spin_lock_init(&ioc->diagLock); spin_lock_init(&ioc->initializing_hba_lock); /* Initialize the event logging. */ ioc->eventTypes = 0; /* None */ ioc->eventContext = 0; ioc->eventLogSize = 0; ioc->events = NULL;#ifdef MFCNT ioc->mfcnt = 0;#endif ioc->cached_fw = NULL; /* Initilize SCSI Config Data structure */ memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); /* Initialize the running configQ head. */ INIT_LIST_HEAD(&ioc->configQ); /* Initialize the fc rport list head. */ INIT_LIST_HEAD(&ioc->fc_rports); /* Find lookup slot. */ INIT_LIST_HEAD(&ioc->list); mem_phys = msize = 0; port = psize = 0; for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { if (psize) continue; /* Get I/O space! */ port = pci_resource_start(pdev, ii); psize = pci_resource_len(pdev,ii); } else { if (msize) continue; /* Get memmap */ mem_phys = pci_resource_start(pdev, ii); msize = pci_resource_len(pdev,ii); } } ioc->mem_size = msize; mem = NULL; /* Get logical ptr for PciMem0 space */ /*mem = ioremap(mem_phys, msize);*/ mem = ioremap(mem_phys, msize); if (mem == NULL) { printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name); kfree(ioc); return -EINVAL; } ioc->memmap = mem; dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys)); dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", ioc->name, &ioc->facts, &ioc->pfacts[0])); ioc->mem_phys = mem_phys; ioc->chip = (SYSIF_REGS __iomem *)mem; /* Save Port IO values in case we need to do downloadboot */ ioc->pio_mem_phys = port; pmem = (u8 __iomem *)port; ioc->pio_chip = (SYSIF_REGS __iomem *)pmem; pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); switch (pdev->device) { case MPI_MANUFACTPAGE_DEVICEID_FC939X: case MPI_MANUFACTPAGE_DEVICEID_FC949X: ioc->errata_flag_1064 = 1; case MPI_MANUFACTPAGE_DEVICEID_FC909: case MPI_MANUFACTPAGE_DEVICEID_FC929: case MPI_MANUFACTPAGE_DEVICEID_FC919: case MPI_MANUFACTPAGE_DEVICEID_FC949E: ioc->bus_type = FC; break; case MPI_MANUFACTPAGE_DEVICEID_FC929X: if (revision < XL_929) { /* 929X Chip Fix. Set Split transactions level * for PCIX. Set MOST bits to zero. */ pci_read_config_byte(pdev, 0x6a, &pcixcmd); pcixcmd &= 0x8F; pci_write_config_byte(pdev, 0x6a, pcixcmd); } else { /* 929XL Chip Fix. Set MMRBC to 0x08. */ pci_read_config_byte(pdev, 0x6a, &pcixcmd); pcixcmd |= 0x08; pci_write_config_byte(pdev, 0x6a, pcixcmd); } ioc->bus_type = FC; break; case MPI_MANUFACTPAGE_DEVICEID_FC919X: /* 919X Chip Fix. Set Split transactions level * for PCIX. Set MOST bits to zero. */ pci_read_config_byte(pdev, 0x6a, &pcixcmd); pcixcmd &= 0x8F; pci_write_config_byte(pdev, 0x6a, pcixcmd); ioc->bus_type = FC; break; case MPI_MANUFACTPAGE_DEVID_53C1030: /* 1030 Chip Fix. Disable Split transactions * for PCIX. Set MOST bits to zero if Rev < C0( = 8). */ if (revision < C0_1030) { pci_read_config_byte(pdev, 0x6a, &pcixcmd); pcixcmd &= 0x8F; pci_write_config_byte(pdev, 0x6a, pcixcmd); } case MPI_MANUFACTPAGE_DEVID_1030_53C1035: ioc->bus_type = SPI; break; case MPI_MANUFACTPAGE_DEVID_SAS1064: case MPI_MANUFACTPAGE_DEVID_SAS1068: ioc->errata_flag_1064 = 1; case MPI_MANUFACTPAGE_DEVID_SAS1064E: case MPI_MANUFACTPAGE_DEVID_SAS1068E: case MPI_MANUFACTPAGE_DEVID_SAS1078: ioc->bus_type = SAS; } if (ioc->errata_flag_1064) pci_disable_io_access(pdev); spin_lock_init(&ioc->FreeQlock); /* Disable all! */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); /* Set lookup ptr. */ list_add_tail(&ioc->list, &ioc_list); /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. */ mpt_detect_bound_ports(ioc, pdev); if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0){ printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", ioc->name, r); list_del(&ioc->list); if (ioc->alt_ioc) ioc->alt_ioc->alt_ioc = NULL; iounmap(mem); kfree(ioc); pci_set_drvdata(pdev, NULL); return r; } /* call per device driver probe entry point */ for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { if(MptDeviceDriverHandlers[cb_idx] && MptDeviceDriverHandlers[cb_idx]->probe) { MptDeviceDriverHandlers[cb_idx]->probe(pdev,id); } }#ifdef CONFIG_PROC_FS /* * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter. */ dent = proc_mkdir(ioc->name, mpt_proc_root_dir); if (dent) { ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent); if (ent) { ent->read_proc = procmpt_iocinfo_read; ent->data = ioc; } ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent); if (ent) { ent->read_proc = procmpt_summary_read; ent->data = ioc; } }#endif return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** * mpt_detach - Remove a PCI intelligent MPT adapter. * @pdev: Pointer to pci_dev structure */voidmpt_detach(struct pci_dev *pdev){ MPT_ADAPTER *ioc = pci_get_drvdata(pdev); char pname[32]; u8 cb_idx; sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); remove_proc_entry(pname, NULL); sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name); remove_proc_entry(pname, NULL); sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name); remove_proc_entry(pname, NULL); /* call per device driver remove entry point */ for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { if(MptDeviceDriverHandlers[cb_idx] && MptDeviceDriverHandlers[cb_idx]->remove) { MptDeviceDriverHandlers[cb_idx]->remove(pdev); } } /* Disable interrupts! */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; synchronize_irq(pdev->irq); /* Clear any lingering interrupt */ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); CHIPREG_READ32(&ioc->chip->IntStatus); mpt_adapter_dispose(ioc); pci_set_drvdata(pdev, NULL);}/************************************************************************** * Power Management */#ifdef CONFIG_PM/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** * mpt_suspend - Fusion MPT base driver suspend routine. * @pdev: Pointer to pci_dev structure * @state: new state to enter */intmpt_suspend(struct pci_dev *pdev, pm_message_t state){ u32 device_state; MPT_ADAPTER *ioc = pci_get_drvdata(pdev); device_state=pci_choose_state(pdev, state); printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), device_state); pci_save_state(pdev); /* put ioc into READY_STATE */ if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) { printk(MYIOC_s_ERR_FMT "pci-suspend: IOC msg unit reset failed!\n", ioc->name); } /* disable interrupts */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; /* Clear any lingering interrupt */ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); pci_disable_device(pdev); pci_set_power_state(pdev, device_state); return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** * mpt_resume - Fusion MPT base driver resume routine. * @pdev: Pointer to pci_dev structure */intmpt_resume(struct pci_dev *pdev){ MPT_ADAPTER *ioc = pci_get_drvdata(pdev); u32 device_state = pdev->current_state; int recovery_state; int err; printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), device_state); pci_set_power_state(pdev, 0); pci_restore_state(pdev); err = pci_enable_device(pdev); if (err) return err; /* enable interrupts */ CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); ioc->active = 1; printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT), CHIPREG_READ32(&ioc->chip->Doorbell)); /* bring ioc to operational state */ if ((recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) { printk(MYIOC_s_INFO_FMT "pci-resume: Cannot recover, error:[%x]\n",
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?