📄 mptspi.c
字号:
}static struct scsi_host_template mptspi_driver_template = { .module = THIS_MODULE, .proc_name = "mptspi", .proc_info = mptscsih_proc_info, .name = "MPT SPI Host", .info = mptscsih_info, .queuecommand = mptscsih_qcmd, .target_alloc = mptspi_target_alloc, .slave_alloc = mptspi_slave_alloc, .slave_configure = mptspi_slave_configure, .target_destroy = mptscsih_target_destroy, .slave_destroy = mptspi_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, .eh_abort_handler = mptscsih_abort, .eh_device_reset_handler = mptscsih_dev_reset, .eh_bus_reset_handler = mptscsih_bus_reset, .eh_host_reset_handler = mptscsih_host_reset, .bios_param = mptscsih_bios_param, .can_queue = MPT_SCSI_CAN_QUEUE, .this_id = -1, .sg_tablesize = MPT_SCSI_SG_DEPTH, .max_sectors = 8192, .cmd_per_lun = 7, .use_clustering = ENABLE_CLUSTERING,};static int mptspi_write_spi_device_pg1(struct scsi_target *starget, struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1){ struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; struct _MPT_ADAPTER *ioc = hd->ioc; struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1; dma_addr_t pg1_dma; int size; struct _x_config_parms cfg; struct _CONFIG_PAGE_HEADER hdr; int err = -EBUSY; /* don't allow updating nego parameters on RAID devices */ if (starget->channel == 0 && (hd->ioc->raid_data.isRaid & (1 << starget->id))) return -1; size = ioc->spi_data.sdp1length * 4; pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL); if (pg1 == NULL) { starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); return -EINVAL; } memset(&hdr, 0, sizeof(hdr)); hdr.PageVersion = ioc->spi_data.sdp1version; hdr.PageLength = ioc->spi_data.sdp1length; hdr.PageNumber = 1; hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; memset(&cfg, 0, sizeof(cfg)); cfg.cfghdr.hdr = &hdr; cfg.physAddr = pg1_dma; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.dir = 1; cfg.pageAddr = starget->id; memcpy(pg1, pass_pg1, size); pg1->Header.PageVersion = hdr.PageVersion; pg1->Header.PageLength = hdr.PageLength; pg1->Header.PageNumber = hdr.PageNumber; pg1->Header.PageType = hdr.PageType; if (mpt_config(ioc, &cfg)) { starget_printk(KERN_ERR, starget, "mpt_config failed\n"); goto out_free; } err = 0; out_free: dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma); return err;}static void mptspi_write_offset(struct scsi_target *starget, int offset){ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; u32 nego; if (offset < 0) offset = 0; if (offset > 255) offset = 255; if (spi_offset(starget) == -1) mptspi_read_parameters(starget); spi_offset(starget) = offset; nego = mptspi_getRP(starget); pg1.RequestedParameters = cpu_to_le32(nego); pg1.Reserved = 0; pg1.Configuration = 0; mptspi_write_spi_device_pg1(starget, &pg1);}static void mptspi_write_period(struct scsi_target *starget, int period){ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; u32 nego; if (period < 8) period = 8; if (period > 255) period = 255; if (spi_period(starget) == -1) mptspi_read_parameters(starget); if (period == 8) { spi_iu(starget) = 1; spi_dt(starget) = 1; } else if (period == 9) { spi_dt(starget) = 1; } spi_period(starget) = period; nego = mptspi_getRP(starget); pg1.RequestedParameters = cpu_to_le32(nego); pg1.Reserved = 0; pg1.Configuration = 0; mptspi_write_spi_device_pg1(starget, &pg1);}static void mptspi_write_dt(struct scsi_target *starget, int dt){ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; u32 nego; if (spi_period(starget) == -1) mptspi_read_parameters(starget); if (!dt && spi_period(starget) < 10) spi_period(starget) = 10; spi_dt(starget) = dt; nego = mptspi_getRP(starget); pg1.RequestedParameters = cpu_to_le32(nego); pg1.Reserved = 0; pg1.Configuration = 0; mptspi_write_spi_device_pg1(starget, &pg1);}static void mptspi_write_iu(struct scsi_target *starget, int iu){ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; u32 nego; if (spi_period(starget) == -1) mptspi_read_parameters(starget); if (!iu && spi_period(starget) < 9) spi_period(starget) = 9; spi_iu(starget) = iu; nego = mptspi_getRP(starget); pg1.RequestedParameters = cpu_to_le32(nego); pg1.Reserved = 0; pg1.Configuration = 0; mptspi_write_spi_device_pg1(starget, &pg1);}#define MPTSPI_SIMPLE_TRANSPORT_PARM(parm) \static void mptspi_write_##parm(struct scsi_target *starget, int parm)\{ \ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; \ u32 nego; \ \ spi_##parm(starget) = parm; \ \ nego = mptspi_getRP(starget); \ \ pg1.RequestedParameters = cpu_to_le32(nego); \ pg1.Reserved = 0; \ pg1.Configuration = 0; \ \ mptspi_write_spi_device_pg1(starget, &pg1); \}MPTSPI_SIMPLE_TRANSPORT_PARM(rd_strm)MPTSPI_SIMPLE_TRANSPORT_PARM(wr_flow)MPTSPI_SIMPLE_TRANSPORT_PARM(rti)MPTSPI_SIMPLE_TRANSPORT_PARM(hold_mcs)MPTSPI_SIMPLE_TRANSPORT_PARM(pcomp_en)static void mptspi_write_qas(struct scsi_target *starget, int qas){ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; VirtTarget *vtarget = starget->hostdata; u32 nego; if ((vtarget->negoFlags & MPT_TARGET_NO_NEGO_QAS) || hd->ioc->spi_data.noQas) spi_qas(starget) = 0; else spi_qas(starget) = qas; nego = mptspi_getRP(starget); pg1.RequestedParameters = cpu_to_le32(nego); pg1.Reserved = 0; pg1.Configuration = 0; mptspi_write_spi_device_pg1(starget, &pg1);}static void mptspi_write_width(struct scsi_target *starget, int width){ struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; u32 nego; if (!width) { spi_dt(starget) = 0; if (spi_period(starget) < 10) spi_period(starget) = 10; } spi_width(starget) = width; nego = mptspi_getRP(starget); pg1.RequestedParameters = cpu_to_le32(nego); pg1.Reserved = 0; pg1.Configuration = 0; mptspi_write_spi_device_pg1(starget, &pg1);}struct work_queue_wrapper { struct work_struct work; struct _MPT_SCSI_HOST *hd; int disk;};static void mpt_work_wrapper(void *data){ struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; struct _MPT_SCSI_HOST *hd = wqw->hd; struct Scsi_Host *shost = hd->ioc->sh; struct scsi_device *sdev; int disk = wqw->disk; struct _CONFIG_PAGE_IOC_3 *pg3; kfree(wqw); mpt_findImVolumes(hd->ioc); pg3 = hd->ioc->raid_data.pIocPg3; if (!pg3) return; shost_for_each_device(sdev,shost) { struct scsi_target *starget = scsi_target(sdev); VirtTarget *vtarget = starget->hostdata; /* only want to search RAID components */ if (sdev->channel != 1) continue; /* The target_id is the raid PhysDiskNum, even if * starget->id is the actual target address */ if(vtarget->target_id != disk) continue; starget_printk(KERN_INFO, vtarget->starget, "Integrated RAID requests DV of new device\n"); mptspi_dv_device(hd, sdev); } shost_printk(KERN_INFO, shost, "Integrated RAID detects new device %d\n", disk); scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1);}static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk){ struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); if (!wqw) { shost_printk(KERN_ERR, hd->ioc->sh, "Failed to act on RAID event for physical disk %d\n", disk); return; } INIT_WORK(&wqw->work, mpt_work_wrapper, wqw); wqw->hd = hd; wqw->disk = disk; schedule_work(&wqw->work);}static intmptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply){ u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; if (hd && event == MPI_EVENT_INTEGRATED_RAID) { int reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16; if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { int disk = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24; mpt_dv_raid(hd, disk); } } return mptscsih_event_process(ioc, pEvReply);}static intmptspi_deny_binding(struct scsi_target *starget){ struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) && starget->channel == 0) ? 1 : 0;}static struct spi_function_template mptspi_transport_functions = { .get_offset = mptspi_read_parameters, .set_offset = mptspi_write_offset, .show_offset = 1, .get_period = mptspi_read_parameters, .set_period = mptspi_write_period, .show_period = 1, .get_width = mptspi_read_parameters, .set_width = mptspi_write_width, .show_width = 1, .get_iu = mptspi_read_parameters, .set_iu = mptspi_write_iu, .show_iu = 1, .get_dt = mptspi_read_parameters, .set_dt = mptspi_write_dt, .show_dt = 1, .get_qas = mptspi_read_parameters, .set_qas = mptspi_write_qas, .show_qas = 1, .get_wr_flow = mptspi_read_parameters, .set_wr_flow = mptspi_write_wr_flow, .show_wr_flow = 1, .get_rd_strm = mptspi_read_parameters, .set_rd_strm = mptspi_write_rd_strm, .show_rd_strm = 1, .get_rti = mptspi_read_parameters, .set_rti = mptspi_write_rti, .show_rti = 1, .get_pcomp_en = mptspi_read_parameters, .set_pcomp_en = mptspi_write_pcomp_en, .show_pcomp_en = 1, .get_hold_mcs = mptspi_read_parameters, .set_hold_mcs = mptspi_write_hold_mcs, .show_hold_mcs = 1, .deny_binding = mptspi_deny_binding,};/**************************************************************************** * Supported hardware */static struct pci_device_id mptspi_pci_table[] = { { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -