From a1da5f4f1beb8cae83104a65f36afe527184a4ef Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 22 Jul 2007 10:41:39 +1000 Subject: Don't compile the PMU power driver on 64-bit PowerPC As reported by Stephen Rothwell, an allmodconfig build on 64-bit PowerPC reports these errors: ERROR: "pmu_batteries" [drivers/power/pmu_battery.ko] undefined! ERROR: "pmu_battery_count" [drivers/power/pmu_battery.ko] undefined! ERROR: "pmu_power_flags" [drivers/power/pmu_battery.ko] undefined! This fixes the problem by not building pmu_battery.ko on ppc64. There are no battery-powered ppc64 machines with an Apple PMU, and we can be reasonably confident there never will be. Signed-off-by: Paul Mackerras Signed-off-by: David Woodhouse --- drivers/power/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 3f6e176e6ea1..58c806e9c58a 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -38,7 +38,7 @@ config BATTERY_DS2760 config BATTERY_PMU tristate "Apple PMU battery" - depends on ADB_PMU + depends on PPC32 && ADB_PMU help Say Y here to expose battery information on Apple machines through the generic battery class. -- cgit v1.2.3 From 67effe8fff32f60bdf51cba484766ba6003005bb Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 26 Jul 2007 00:50:06 -0400 Subject: ACPI: add "acpi_no_auto_ssdt" bootparam "acpi_no_auto_ssdt" prevents Linux from automatically loading all the SSDTs listed in the RSDT/XSDT. This is needed for debugging. In particular, it allows a DSDT override to optionally be a DSDT+SSDT override. http://bugzilla.kernel.org/show_bug.cgi?id=3774 Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 2 ++ drivers/acpi/tables/tbxface.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fb80e9ffea68..379931e74334 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -166,6 +166,8 @@ and is between 256 and 4096 characters. It is defined in the file acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA Format: ,... + acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT + acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS Format: To spoof as Windows 98: ="Microsoft Windows" diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 5b302c4e293f..a9e3331fee5d 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -52,6 +52,8 @@ ACPI_MODULE_NAME("tbxface") /* Local prototypes */ static acpi_status acpi_tb_load_namespace(void); +static int no_auto_ssdt; + /******************************************************************************* * * FUNCTION: acpi_allocate_root_table @@ -536,6 +538,10 @@ static acpi_status acpi_tb_load_namespace(void) ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); acpi_tb_print_table_header(0, table); + + if (no_auto_ssdt == 0) { + printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\""); + } } status = @@ -577,6 +583,11 @@ static acpi_status acpi_tb_load_namespace(void) continue; } + if (no_auto_ssdt) { + printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n"); + continue; + } + /* Ignore errors while loading tables, get as many as possible */ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); @@ -622,3 +633,15 @@ acpi_status acpi_load_tables(void) } ACPI_EXPORT_SYMBOL(acpi_load_tables) + + +static int __init acpi_no_auto_ssdt_setup(char *s) { + + printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); + + no_auto_ssdt = 1; + + return 1; +} + +__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); -- cgit v1.2.3 From 7936a892e72498a05b9a7fb1fec6506d65c8e435 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sun, 29 Jul 2007 16:46:28 +0900 Subject: [SCSI] zfcp: convert to use the data buffer accessors - remove the unnecessary map_single path. - convert to use the new accessors for the sg lists and the parameters. Signed-off-by: FUJITA Tomonori Acked-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 5 +++-- drivers/s390/scsi/zfcp_qdio.c | 41 ++++++----------------------------------- 2 files changed, 9 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index b240800b78d7..99299976e891 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -4154,8 +4154,9 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) fcp_rsp_iu->fcp_resid, (int) zfcp_get_fcp_dl(fcp_cmnd_iu)); - scpnt->resid = fcp_rsp_iu->fcp_resid; - if (scpnt->request_bufflen - scpnt->resid < scpnt->underflow) + scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid); + if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) < + scpnt->underflow) set_host_byte(&scpnt->result, DID_ERROR); } diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index c408badd2ae9..81daa8204bfe 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -36,8 +36,6 @@ static void zfcp_qdio_sbale_fill (struct zfcp_fsf_req *, unsigned long, void *, int); static int zfcp_qdio_sbals_from_segment (struct zfcp_fsf_req *, unsigned long, void *, unsigned long); -static int zfcp_qdio_sbals_from_buffer - (struct zfcp_fsf_req *, unsigned long, void *, unsigned long, int); static qdio_handler_t zfcp_qdio_request_handler; static qdio_handler_t zfcp_qdio_response_handler; @@ -631,28 +629,6 @@ out: } -/** - * zfcp_qdio_sbals_from_buffer - fill SBALs from buffer - * @fsf_req: request to be processed - * @sbtype: SBALE flags - * @buffer: data buffer - * @length: length of buffer - * @max_sbals: upper bound for number of SBALs to be used - */ -static int -zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, - void *buffer, unsigned long length, int max_sbals) -{ - struct scatterlist sg_segment; - - zfcp_address_to_sg(buffer, &sg_segment); - sg_segment.length = length; - - return zfcp_qdio_sbals_from_sg(fsf_req, sbtype, &sg_segment, 1, - max_sbals); -} - - /** * zfcp_qdio_sbals_from_scsicmnd - fill SBALs from scsi command * @fsf_req: request to be processed @@ -664,18 +640,13 @@ int zfcp_qdio_sbals_from_scsicmnd(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, struct scsi_cmnd *scsi_cmnd) { - if (scsi_cmnd->use_sg) { + if (scsi_sg_count(scsi_cmnd)) return zfcp_qdio_sbals_from_sg(fsf_req, sbtype, - (struct scatterlist *) - scsi_cmnd->request_buffer, - scsi_cmnd->use_sg, - ZFCP_MAX_SBALS_PER_REQ); - } else { - return zfcp_qdio_sbals_from_buffer(fsf_req, sbtype, - scsi_cmnd->request_buffer, - scsi_cmnd->request_bufflen, - ZFCP_MAX_SBALS_PER_REQ); - } + scsi_sglist(scsi_cmnd), + scsi_sg_count(scsi_cmnd), + ZFCP_MAX_SBALS_PER_REQ); + else + return 0; } /** -- cgit v1.2.3 From ed3a3633b798a15281f9c9a89a7e74d4bdd02ebe Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 23 Jul 2007 09:28:39 +0900 Subject: [SCSI] ibmvscsi: remove unnecessary map_sg check No need to check use_sg since sg_tablesize is set appropriately in the scsi host template. Brian King's patch (2a7309372fe56ae46c499b772d811ad31c501dd9) did this cleanup but the data buffer accessors patch (written before the patch and merged after it) restored the check. Signed-off-by: FUJITA Tomonori Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5870866abc99..673526044e8b 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -393,12 +393,6 @@ static int map_sg_data(struct scsi_cmnd *cmd, return 1; else if (sg_mapped < 0) return 0; - else if (sg_mapped > SG_ALL) { - printk(KERN_ERR - "ibmvscsi: More than %d mapped sg entries, got %d\n", - SG_ALL, sg_mapped); - return 0; - } set_srp_direction(cmd, srp_cmd, sg_mapped); -- cgit v1.2.3 From 7603e02eac309626c0153ebddf277253ea7fe0e0 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 23 Jul 2007 09:28:40 +0900 Subject: [SCSI] ibmvscsi: use shost_priv Signed-off-by: FUJITA Tomonori Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 673526044e8b..5ecc63d1b436 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -702,8 +702,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, struct srp_cmd *srp_cmd; struct srp_event_struct *evt_struct; struct srp_indirect_buf *indirect; - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)&cmnd->device->host->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(cmnd->device->host); u16 lun = lun_from_dev(cmnd->device); u8 out_fmt, in_fmt; @@ -954,8 +953,7 @@ static void sync_completion(struct srp_event_struct *evt_struct) */ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) { - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)cmd->device->host->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host); struct srp_tsk_mgmt *tsk_mgmt; struct srp_event_struct *evt; struct srp_event_struct *tmp_evt, *found_evt; @@ -1078,9 +1076,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) */ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) { - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)cmd->device->host->hostdata; - + struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host); struct srp_tsk_mgmt *tsk_mgmt; struct srp_event_struct *evt; struct srp_event_struct *tmp_evt, *pos; @@ -1177,8 +1173,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) static int ibmvscsi_eh_host_reset_handler(struct scsi_cmnd *cmd) { unsigned long wait_switch = 0; - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)cmd->device->host->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host); dev_err(hostdata->dev, "Resetting connection due to error recovery\n"); @@ -1406,8 +1401,7 @@ static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth) static ssize_t show_host_srp_version(struct class_device *class_dev, char *buf) { struct Scsi_Host *shost = class_to_shost(class_dev); - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)shost->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(shost); int len; len = snprintf(buf, PAGE_SIZE, "%s\n", @@ -1427,8 +1421,7 @@ static ssize_t show_host_partition_name(struct class_device *class_dev, char *buf) { struct Scsi_Host *shost = class_to_shost(class_dev); - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)shost->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(shost); int len; len = snprintf(buf, PAGE_SIZE, "%s\n", @@ -1448,8 +1441,7 @@ static ssize_t show_host_partition_number(struct class_device *class_dev, char *buf) { struct Scsi_Host *shost = class_to_shost(class_dev); - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)shost->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(shost); int len; len = snprintf(buf, PAGE_SIZE, "%d\n", @@ -1468,8 +1460,7 @@ static struct class_device_attribute ibmvscsi_host_partition_number = { static ssize_t show_host_mad_version(struct class_device *class_dev, char *buf) { struct Scsi_Host *shost = class_to_shost(class_dev); - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)shost->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(shost); int len; len = snprintf(buf, PAGE_SIZE, "%d\n", @@ -1488,8 +1479,7 @@ static struct class_device_attribute ibmvscsi_host_mad_version = { static ssize_t show_host_os_type(struct class_device *class_dev, char *buf) { struct Scsi_Host *shost = class_to_shost(class_dev); - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)shost->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(shost); int len; len = snprintf(buf, PAGE_SIZE, "%d\n", hostdata->madapter_info.os_type); @@ -1507,8 +1497,7 @@ static struct class_device_attribute ibmvscsi_host_os_type = { static ssize_t show_host_config(struct class_device *class_dev, char *buf) { struct Scsi_Host *shost = class_to_shost(class_dev); - struct ibmvscsi_host_data *hostdata = - (struct ibmvscsi_host_data *)shost->hostdata; + struct ibmvscsi_host_data *hostdata = shost_priv(shost); /* returns null-terminated host config data */ if (ibmvscsi_do_host_config(hostdata, buf, PAGE_SIZE) == 0) @@ -1576,7 +1565,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto scsi_host_alloc_failed; } - hostdata = (struct ibmvscsi_host_data *)host->hostdata; + hostdata = shost_priv(host); memset(hostdata, 0x00, sizeof(*hostdata)); INIT_LIST_HEAD(&hostdata->sent); hostdata->host = host; -- cgit v1.2.3 From 8e9a8a0d56c5d9d87adbefbbc8c8728c529fd95a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 17 Jul 2007 05:25:17 -0400 Subject: [SCSI] gdth: remove redundant PCI stuff This patch * removes struct members that duplicate pci_dev members * replaces ha->stype usage with ha->pdev->device usage where feasible Signed-off-by: Jeff Garzik Acked-by: Christoph Hellwig Acked-by: Achim Leubner Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 48 ++++++++++++++++++++++-------------------------- drivers/scsi/gdth.h | 6 ------ 2 files changed, 22 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index d0b95ce0ba00..55e4d2dc2bbe 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -902,11 +902,6 @@ static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, return; /* GDT PCI controller found, resources are already in pdev */ pcistr[*cnt].pdev = pdev; - pcistr[*cnt].vendor_id = vendor; - pcistr[*cnt].device_id = device; - pcistr[*cnt].subdevice_id = pdev->subsystem_device; - pcistr[*cnt].bus = pdev->bus->number; - pcistr[*cnt].device_fn = pdev->devfn; pcistr[*cnt].irq = pdev->irq; base0 = pci_resource_flags(pdev, 0); base1 = pci_resource_flags(pdev, 1); @@ -926,7 +921,8 @@ static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, pcistr[*cnt].io = pci_resource_start(pdev, 1); } TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", - pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), + pcistr[*cnt].pdev->bus->number, + PCI_SLOT(pcistr[*cnt].pdev->devfn), pcistr[*cnt].irq, pcistr[*cnt].dpmem)); (*cnt)++; } @@ -946,20 +942,20 @@ static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) changed = FALSE; for (i = 0; i < cnt-1; ++i) { if (!reverse_scan) { - if ((pcistr[i].bus > pcistr[i+1].bus) || - (pcistr[i].bus == pcistr[i+1].bus && - PCI_SLOT(pcistr[i].device_fn) > - PCI_SLOT(pcistr[i+1].device_fn))) { + if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) || + (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && + PCI_SLOT(pcistr[i].pdev->devfn) > + PCI_SLOT(pcistr[i+1].pdev->devfn))) { temp = pcistr[i]; pcistr[i] = pcistr[i+1]; pcistr[i+1] = temp; changed = TRUE; } } else { - if ((pcistr[i].bus < pcistr[i+1].bus) || - (pcistr[i].bus == pcistr[i+1].bus && - PCI_SLOT(pcistr[i].device_fn) < - PCI_SLOT(pcistr[i+1].device_fn))) { + if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) || + (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && + PCI_SLOT(pcistr[i].pdev->devfn) < + PCI_SLOT(pcistr[i+1].pdev->devfn))) { temp = pcistr[i]; pcistr[i] = pcistr[i+1]; pcistr[i+1] = temp; @@ -1176,17 +1172,16 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) TRACE(("gdth_init_pci()\n")); - if (pcistr->vendor_id == PCI_VENDOR_ID_INTEL) + if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL) ha->oem_id = OEM_ID_INTEL; else ha->oem_id = OEM_ID_ICP; - ha->brd_phys = (pcistr->bus << 8) | (pcistr->device_fn & 0xf8); - ha->stype = (ulong32)pcistr->device_id; - ha->subdevice_id = pcistr->subdevice_id; + ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8); + ha->stype = (ulong32)pcistr->pdev->device; ha->irq = pcistr->irq; ha->pdev = pcistr->pdev; - if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ + if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6_dpram_str)); if (ha->brd == NULL) { @@ -1293,7 +1288,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) ha->dma64_support = 0; - } else if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */ + } else if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */ ha->plx = (gdt6c_plx_regs *)pcistr->io; TRACE2(("init_pci_new() dpmem %lx irq %d\n", pcistr->dpmem,ha->irq)); @@ -4601,7 +4596,8 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) } /* controller found and initialized */ printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", - pcistr[ctr].bus,PCI_SLOT(pcistr[ctr].device_fn),ha->irq); + pcistr[ctr].pdev->bus->number, + PCI_SLOT(pcistr[ctr].pdev->devfn), ha->irq); if (request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED|IRQF_SHARED, "gdth", ha)) @@ -4637,7 +4633,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) #endif ha->scratch_busy = FALSE; ha->req_first = NULL; - ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES; + ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; if (max_ids > 0 && max_ids < ha->tid_cnt) ha->tid_cnt = max_ids; for (i=0; itype == GDT_ISA) { return("GDT2000/2020"); } else if (ha->type == GDT_PCI) { - switch (ha->stype) { + switch (ha->pdev->device) { case PCI_DEVICE_ID_VORTEX_GDT60x0: return("GDT6000/6020/6050"); case PCI_DEVICE_ID_VORTEX_GDT6000B: @@ -5448,12 +5444,12 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, ctrt.type = (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe); if (ha->stype >= 0x300) - ctrt.ext_type = 0x6000 | ha->subdevice_id; + ctrt.ext_type = 0x6000 | ha->pdev->subsystem_device; else ctrt.ext_type = 0x6000 | ha->stype; } - ctrt.device_id = ha->stype; - ctrt.sub_device_id = ha->subdevice_id; + ctrt.device_id = ha->pdev->device; + ctrt.sub_device_id = ha->pdev->subsystem_device; } ctrt.info = ha->brd_phys; ctrt.oem_id = ha->oem_id; diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 8c29eafd51c5..37423300592e 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -845,11 +845,6 @@ typedef struct { /* PCI resources */ typedef struct { struct pci_dev *pdev; - ushort vendor_id; /* vendor (ICP, Intel, ..) */ - ushort device_id; /* device ID (0,..,9) */ - ushort subdevice_id; /* sub device ID */ - unchar bus; /* PCI bus */ - unchar device_fn; /* PCI device/function no. */ ulong dpmem; /* DPRAM address */ ulong io; /* IO address */ ulong io_mm; /* IO address mem. mapped */ @@ -862,7 +857,6 @@ typedef struct { ushort oem_id; /* OEM */ ushort type; /* controller class */ ulong32 stype; /* subtype (PCI: device ID) */ - ushort subdevice_id; /* sub device ID (PCI) */ ushort fw_vers; /* firmware version */ ushort cache_feat; /* feat. cache serv. (s/g,..)*/ ushort raw_feat; /* feat. raw service (s/g,..)*/ -- cgit v1.2.3 From 15617ff66c777b008e170f9c5b0e8a9854937648 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 28 Jul 2007 11:07:36 -0400 Subject: [SCSI] libsas: fix build dependencies on libata If you have the libsas with ATA support, it needs libata to function. The problem is that if you compile in libsas, you can't build libata as a module (however, vice versa you can). Signed-off-by: James Bottomley --- drivers/scsi/libsas/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig index 3a3c1ac9c6cd..c01a40d321d4 100644 --- a/drivers/scsi/libsas/Kconfig +++ b/drivers/scsi/libsas/Kconfig @@ -32,7 +32,8 @@ config SCSI_SAS_LIBSAS config SCSI_SAS_ATA bool "ATA support for libsas (requires libata)" - depends on SCSI_SAS_LIBSAS && ATA + depends on SCSI_SAS_LIBSAS + depends on ATA = y || ATA = SCSI_SAS_LIBSAS help Builds in ATA support into libsas. Will necessitate the loading of libata along with libsas. -- cgit v1.2.3 From db47c2d8d98a76083a88ec53f44cc74c48dfd1e8 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 28 Jul 2007 13:40:21 -0400 Subject: [SCSI] mpt fusion: make logging a global sysfs parameter Wire up the mpt_debug_level module parameter so you can write to the /sys/module/mptbase/parameters/mpt_debug_level and have it take effect in every ioc. Acked-by: "Moore, Eric" Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index e866dacde7e5..414c109f4cf5 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -88,7 +88,9 @@ module_param(mpt_channel_mapping, int, 0); MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); static int mpt_debug_level; -module_param(mpt_debug_level, int, 0); +static int mpt_set_debug_level(const char *val, struct kernel_param *kp); +module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int, + &mpt_debug_level, 0600); MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)"); #ifdef MFCNT @@ -220,6 +222,19 @@ pci_enable_io_access(struct pci_dev *pdev) pci_write_config_word(pdev, PCI_COMMAND, command_reg); } +static int mpt_set_debug_level(const char *val, struct kernel_param *kp) +{ + int ret = param_set_int(val, kp); + MPT_ADAPTER *ioc; + + if (ret) + return ret; + + list_for_each_entry(ioc, &ioc_list, list) + ioc->debug_level = mpt_debug_level; + return 0; +} + /* * Process turbo (context) reply... */ -- cgit v1.2.3 From 28f85009e0cf6a5232cd285131eac3dfe26d9e3a Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Sun, 29 Jul 2007 23:38:15 +0200 Subject: [SCSI] st: Use mutex instead of semaphore The SCSI Tape driver uses a semaphore as mutex. Use the mutex API instead of the (binary) semaphore. Signed-off-by: Matthias Kaehlcke Acked-by: Kai Makisara Signed-off-by: James Bottomley --- drivers/scsi/st.c | 16 ++++++++-------- drivers/scsi/st.h | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index a4f7b8465773..73c44cbdea47 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -1485,7 +1485,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) struct st_buffer *STbp; char *name = tape_name(STp); - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; retval = rw_checks(STp, filp, count); @@ -1736,7 +1736,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) if (SRpnt != NULL) st_release_request(SRpnt); release_buffering(STp, 0); - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -1942,7 +1942,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) struct st_buffer *STbp = STp->buffer; DEB( char *name = tape_name(STp); ) - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; retval = rw_checks(STp, filp, count); @@ -2069,7 +2069,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) release_buffering(STp, 1); STbp->buffer_bytes = 0; } - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -3226,7 +3226,7 @@ static int st_ioctl(struct inode *inode, struct file *file, char *name = tape_name(STp); void __user *p = (void __user *)arg; - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; DEB( @@ -3537,7 +3537,7 @@ static int st_ioctl(struct inode *inode, struct file *file, retval = (-EFAULT); goto out; } - up(&STp->lock); + mutex_unlock(&STp->lock); switch (cmd_in) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: @@ -3563,7 +3563,7 @@ static int st_ioctl(struct inode *inode, struct file *file, return retval; out: - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -4029,7 +4029,7 @@ static int st_probe(struct device *dev) tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; - init_MUTEX(&tpnt->lock); + mutex_init(&tpnt->lock); st_nr_dev++; write_unlock(&st_dev_arr_lock); diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 50f3deb1f9ed..6c8075712974 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -3,6 +3,7 @@ #define _ST_H #include +#include #include #include @@ -98,7 +99,7 @@ struct st_partstat { struct scsi_tape { struct scsi_driver *driver; struct scsi_device *device; - struct semaphore lock; /* For serialization */ + struct mutex lock; /* For serialization */ struct completion wait; /* For SCSI commands */ struct st_buffer *buffer; -- cgit v1.2.3 From 142009a3df39ecd4e96601d8bdabbe0c5f6e2f4e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 30 Jul 2007 09:52:25 -0500 Subject: [SCSI] aic7xxx: cap maxsync according to correct card limits Not doing this can cause cards less than u160 capable to send out PPR offers to devices they can't then deliver on ... causing some devices to get a bit confused. Fix by capping the start syncrate at the appropriate level according to the card capabilities. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_core.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 75733b09f27a..f350b5e89e76 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -1701,7 +1701,16 @@ ahc_find_syncrate(struct ahc_softc *ahc, u_int *period, if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0 && maxsync < AHC_SYNCRATE_ULTRA2) maxsync = AHC_SYNCRATE_ULTRA2; - + + /* Now set the maxsync based on the card capabilities + * DT is already done above */ + if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0 + && maxsync < AHC_SYNCRATE_ULTRA) + maxsync = AHC_SYNCRATE_ULTRA; + if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0 + && maxsync < AHC_SYNCRATE_FAST) + maxsync = AHC_SYNCRATE_FAST; + for (syncrate = &ahc_syncrates[maxsync]; syncrate->rate != NULL; syncrate++) { @@ -1765,6 +1774,17 @@ ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync) else scsirate &= SXFR; + /* now set maxsync based on card capabilities */ + if ((ahc->features & AHC_DT) == 0 && maxsync < AHC_SYNCRATE_ULTRA2) + maxsync = AHC_SYNCRATE_ULTRA2; + if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0 + && maxsync < AHC_SYNCRATE_ULTRA) + maxsync = AHC_SYNCRATE_ULTRA; + if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0 + && maxsync < AHC_SYNCRATE_FAST) + maxsync = AHC_SYNCRATE_FAST; + + syncrate = &ahc_syncrates[maxsync]; while (syncrate->rate != NULL) { -- cgit v1.2.3 From 53772a2cb40748ea0b26db8101d632ddb3875b51 Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Mon, 30 Jul 2007 11:01:07 -0700 Subject: [SCSI] qla2xxx: fix panic caused by previous patch - this patch will fix a panic caused by omitted memory allocation for the nvram. Signed-off-by: Seokmann Ju Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c488996cb958..93c0c7e4f08f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2154,6 +2154,19 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) } } + /* Get memory for cached NVRAM */ + ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL); + if (ha->nvram == NULL) { + /* error */ + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - nvram cache\n"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + /* Done all allocations without any error. */ status = 0; @@ -2266,6 +2279,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha) ha->fw_dump_reading = 0; vfree(ha->optrom_buffer); + kfree(ha->nvram); } /* -- cgit v1.2.3 From 55d9fcf57ba5ec427544fca7abc335cf3da78160 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 15:19:18 -0600 Subject: [SCSI] dpt_i2o: convert to SCSI hotplug model - Delete refereces to HOSTS_C - Switch to module_init/module_exit instead of detect/release - Don't pass around the host template and rename it to adpt_template - Switch from scsi_register/scsi_unregister to scsi_host_alloc, scsi_add_host, scsi_scan_host and scsi_host_put. Signed-off-by: Matthew Wilcox Acked-by: "Salyzyn, Mark" Signed-off-by: James Bottomley --- drivers/scsi/dpt_i2o.c | 132 ++++++++++++++++++++++++++----------------------- drivers/scsi/dpti.h | 9 +--- 2 files changed, 73 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 2e2362d787ca..502732ac270d 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -173,20 +173,20 @@ static struct pci_device_id dptids[] = { }; MODULE_DEVICE_TABLE(pci,dptids); -static int adpt_detect(struct scsi_host_template* sht) +static void adpt_exit(void); + +static int adpt_detect(void) { struct pci_dev *pDev = NULL; adpt_hba* pHba; - adpt_init(); - PINFO("Detecting Adaptec I2O RAID controllers...\n"); /* search for all Adatpec I2O RAID cards */ while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) { if(pDev->device == PCI_DPT_DEVICE_ID || pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){ - if(adpt_install_hba(sht, pDev) ){ + if(adpt_install_hba(pDev) ){ PERROR("Could not Init an I2O RAID device\n"); PERROR("Will not try to detect others.\n"); return hba_count-1; @@ -248,34 +248,33 @@ rebuild_sys_tab: } for (pHba = hba_chain; pHba; pHba = pHba->next) { - if( adpt_scsi_register(pHba,sht) < 0){ + if (adpt_scsi_register(pHba) < 0) { adpt_i2o_delete_hba(pHba); continue; } pHba->initialized = TRUE; pHba->state &= ~DPTI_STATE_RESET; + scsi_scan_host(pHba->host); } // Register our control device node // nodes will need to be created in /dev to access this // the nodes can not be created from within the driver if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) { - adpt_i2o_sys_shutdown(); + adpt_exit(); return 0; } return hba_count; } -/* - * scsi_unregister will be called AFTER we return. - */ -static int adpt_release(struct Scsi_Host *host) +static int adpt_release(adpt_hba *pHba) { - adpt_hba* pHba = (adpt_hba*) host->hostdata[0]; + struct Scsi_Host *shost = pHba->host; + scsi_remove_host(shost); // adpt_i2o_quiesce_hba(pHba); adpt_i2o_delete_hba(pHba); - scsi_unregister(host); + scsi_host_put(shost); return 0; } @@ -882,7 +881,7 @@ static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p) #endif -static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) +static int adpt_install_hba(struct pci_dev* pDev) { adpt_hba* pHba = NULL; @@ -1031,8 +1030,6 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) mutex_lock(&adpt_configuration_lock); - // scsi_unregister calls our adpt_release which - // does a quiese if(pHba->host){ free_irq(pHba->host->irq, pHba); } @@ -1084,17 +1081,6 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) } -static int adpt_init(void) -{ - printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); -#ifdef REBOOT_NOTIFIER - register_reboot_notifier(&adpt_reboot_notifier); -#endif - - return 0; -} - - static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun) { struct adpt_device* d; @@ -2180,37 +2166,6 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d } -static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) -{ - struct Scsi_Host *host = NULL; - - host = scsi_register(sht, sizeof(adpt_hba*)); - if (host == NULL) { - printk ("%s: scsi_register returned NULL\n",pHba->name); - return -1; - } - host->hostdata[0] = (unsigned long)pHba; - pHba->host = host; - - host->irq = pHba->pDev->irq; - /* no IO ports, so don't have to set host->io_port and - * host->n_io_port - */ - host->io_port = 0; - host->n_io_port = 0; - /* see comments in scsi_host.h */ - host->max_id = 16; - host->max_lun = 256; - host->max_channel = pHba->top_scsi_channel + 1; - host->cmd_per_lun = 1; - host->unique_id = (uint) pHba; - host->sg_tablesize = pHba->sg_tablesize; - host->can_queue = pHba->post_fifo_size; - - return 0; -} - - static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) { adpt_hba* pHba; @@ -3329,12 +3284,10 @@ static static void adpt_delay(int millisec) #endif -static struct scsi_host_template driver_template = { +static struct scsi_host_template adpt_template = { .name = "dpt_i2o", .proc_name = "dpt_i2o", .proc_info = adpt_proc_info, - .detect = adpt_detect, - .release = adpt_release, .info = adpt_info, .queuecommand = adpt_queue, .eh_abort_handler = adpt_abort, @@ -3348,5 +3301,62 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, }; -#include "scsi_module.c" + +static s32 adpt_scsi_register(adpt_hba* pHba) +{ + struct Scsi_Host *host; + + host = scsi_host_alloc(&adpt_template, sizeof(adpt_hba*)); + if (host == NULL) { + printk ("%s: scsi_host_alloc returned NULL\n",pHba->name); + return -1; + } + host->hostdata[0] = (unsigned long)pHba; + pHba->host = host; + + host->irq = pHba->pDev->irq; + /* no IO ports, so don't have to set host->io_port and + * host->n_io_port + */ + host->io_port = 0; + host->n_io_port = 0; + /* see comments in scsi_host.h */ + host->max_id = 16; + host->max_lun = 256; + host->max_channel = pHba->top_scsi_channel + 1; + host->cmd_per_lun = 1; + host->unique_id = (uint) pHba; + host->sg_tablesize = pHba->sg_tablesize; + host->can_queue = pHba->post_fifo_size; + + if (scsi_add_host(host, &pHba->pDev->dev)) { + scsi_host_put(host); + return -1; + } + + return 0; +} + +static int __init adpt_init(void) +{ + int count; + + printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); +#ifdef REBOOT_NOTIFIER + register_reboot_notifier(&adpt_reboot_notifier); +#endif + + count = adpt_detect(); + + return count > 0 ? 0 : -ENODEV; +} + +static void __exit adpt_exit(void) +{ + while (hba_chain) + adpt_release(hba_chain); +} + +module_init(adpt_init); +module_exit(adpt_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h index fd79068c5869..0892f6c70319 100644 --- a/drivers/scsi/dpti.h +++ b/drivers/scsi/dpti.h @@ -28,11 +28,9 @@ * SCSI interface function Prototypes */ -static int adpt_detect(struct scsi_host_template * sht); static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *)); static int adpt_abort(struct scsi_cmnd * cmd); static int adpt_reset(struct scsi_cmnd* cmd); -static int adpt_release(struct Scsi_Host *host); static int adpt_slave_configure(struct scsi_device *); static const char *adpt_info(struct Scsi_Host *pSHost); @@ -49,8 +47,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd); #define DPT_DRIVER_NAME "Adaptec I2O RAID" -#ifndef HOSTS_C - #include "dpt/sys_info.h" #include #include "dpt/dpti_i2o.h" @@ -289,7 +285,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba); static s32 adpt_i2o_hrt_get(adpt_hba* pHba); static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd); -static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht); +static s32 adpt_scsi_register(adpt_hba* pHba); static s32 adpt_hba_reset(adpt_hba* pHba); static s32 adpt_i2o_reset_hba(adpt_hba* pHba); static s32 adpt_rescan(adpt_hba* pHba); @@ -299,7 +295,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba); static void adpt_inquiry(adpt_hba* pHba); static void adpt_fail_posted_scbs(adpt_hba* pHba); static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun); -static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ; +static int adpt_install_hba(struct pci_dev* pDev) ; static int adpt_i2o_online_hba(adpt_hba* pHba); static void adpt_i2o_post_wait_complete(u32, int); static int adpt_i2o_systab_send(adpt_hba* pHba); @@ -343,5 +339,4 @@ static void adpt_i386_info(sysInfo_S* si); #define FW_DEBUG_BLED_OFFSET 8 #define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01 -#endif /* !HOSTS_C */ #endif /* _DPT_H */ -- cgit v1.2.3 From 96d32215d433c38f258159b8735f98158f6a2575 Mon Sep 17 00:00:00 2001 From: David Miller Date: Mon, 30 Jul 2007 16:19:20 -0700 Subject: [SCSI] ESP: Revert ESP_BUS_TIMEOUT back down to 250 This reverts d73f5222a618a91452d41c29f5996ce3d9c63673 The bug that made us increase ESP_BUS_TIMEOUT to 275 turned out to be a memset bug on 32-bit sparc. It is better to put this back at the correct timeout value than to leave it increased when there is no reason for doing so. Signed-off-by: David S. Miller Signed-off-by: James Bottomley --- drivers/scsi/esp_scsi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index 856e38b14861..d5576d54ce76 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -220,7 +220,7 @@ #define ESP_BUSID_RESELID 0x10 #define ESP_BUSID_CTR32BIT 0x40 -#define ESP_BUS_TIMEOUT 275 /* In milli-seconds */ +#define ESP_BUS_TIMEOUT 250 /* In milli-seconds */ #define ESP_TIMEO_CONST 8192 #define ESP_NEG_DEFP(mhz, cfact) \ ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact))) -- cgit v1.2.3 From 159e36fe996411a4a05added6b7b20b1c4490ebb Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 30 Jul 2007 11:10:07 -0600 Subject: [SCSI] mptsas: add SMP passthrough support via bsg This patch adds support for SAS Management Protocol (SMP) passthrough support via bsg. Signed-off-by: FUJITA Tomonori Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 126 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) (limited to 'drivers') diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 29add83da588..b9c69bff218c 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1312,11 +1312,137 @@ mptsas_get_bay_identifier(struct sas_rphy *rphy) return rc; } +static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, + struct request *req) +{ + MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc; + MPT_FRAME_HDR *mf; + SmpPassthroughRequest_t *smpreq; + struct request *rsp = req->next_rq; + int ret; + int flagsLength; + unsigned long timeleft; + char *psge; + dma_addr_t dma_addr_in = 0; + dma_addr_t dma_addr_out = 0; + u64 sas_address = 0; + + if (!rsp) { + printk(KERN_ERR "%s: the smp response space is missing\n", + __FUNCTION__); + return -EINVAL; + } + + /* do we need to support multiple segments? */ + if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { + printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n", + __FUNCTION__, req->bio->bi_vcnt, req->data_len, + rsp->bio->bi_vcnt, rsp->data_len); + return -EINVAL; + } + + ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex); + if (ret) + goto out; + + mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc); + if (!mf) { + ret = -ENOMEM; + goto out_unlock; + } + + smpreq = (SmpPassthroughRequest_t *)mf; + memset(smpreq, 0, sizeof(*smpreq)); + + smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4); + smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH; + + if (rphy) + sas_address = rphy->identify.sas_address; + else { + struct mptsas_portinfo *port_info; + + mutex_lock(&ioc->sas_topology_mutex); + port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); + if (port_info && port_info->phy_info) + sas_address = + port_info->phy_info[0].phy->identify.sas_address; + mutex_unlock(&ioc->sas_topology_mutex); + } + + *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address); + + psge = (char *) + (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4)); + + /* request */ + flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT | + MPI_SGE_FLAGS_END_OF_BUFFER | + MPI_SGE_FLAGS_DIRECTION | + mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT; + flagsLength |= (req->data_len - 4); + + dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio), + req->data_len, PCI_DMA_BIDIRECTIONAL); + if (!dma_addr_out) + goto put_mf; + mpt_add_sge(psge, flagsLength, dma_addr_out); + psge += (sizeof(u32) + sizeof(dma_addr_t)); + + /* response */ + flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; + flagsLength |= rsp->data_len + 4; + dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), + rsp->data_len, PCI_DMA_BIDIRECTIONAL); + if (!dma_addr_in) + goto unmap; + mpt_add_sge(psge, flagsLength, dma_addr_in); + + mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); + + timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); + if (!timeleft) { + printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__); + /* On timeout reset the board */ + mpt_HardResetHandler(ioc, CAN_SLEEP); + ret = -ETIMEDOUT; + goto unmap; + } + mf = NULL; + + if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) { + SmpPassthroughReply_t *smprep; + + smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; + memcpy(req->sense, smprep, sizeof(*smprep)); + req->sense_len = sizeof(*smprep); + } else { + printk(KERN_ERR "%s: smp passthru reply failed to be returned\n", + __FUNCTION__); + ret = -ENXIO; + } +unmap: + if (dma_addr_out) + pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len, + PCI_DMA_BIDIRECTIONAL); + if (dma_addr_in) + pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len, + PCI_DMA_BIDIRECTIONAL); +put_mf: + if (mf) + mpt_free_msg_frame(ioc, mf); +out_unlock: + mutex_unlock(&ioc->sas_mgmt.mutex); +out: + return ret; +} + static struct sas_function_template mptsas_transport_functions = { .get_linkerrors = mptsas_get_linkerrors, .get_enclosure_identifier = mptsas_get_enclosure_identifier, .get_bay_identifier = mptsas_get_bay_identifier, .phy_reset = mptsas_phy_reset, + .smp_handler = mptsas_smp_handler, }; static struct scsi_transport_template *mptsas_transport_template; -- cgit v1.2.3 From c000c43cf12090972fad0fbb621d78c2100d0373 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 1 Aug 2007 08:40:27 +0900 Subject: [SCSI] initialize shost_data to zero It's better to initialize host->shost_data to zero like target->starget_data and device->sdev_data. Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- drivers/scsi/hosts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index bd8e7f323c69..96bc31266c98 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -220,7 +220,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) get_device(&shost->shost_gendev); if (shost->transportt->host_size && - (shost->shost_data = kmalloc(shost->transportt->host_size, + (shost->shost_data = kzalloc(shost->transportt->host_size, GFP_KERNEL)) == NULL) goto out_del_classdev; -- cgit v1.2.3 From a58cbd5212fff2d4bba0bf58e778f02069597294 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:09:43 -0400 Subject: [SCSI] lpfc 8.2.2 : Error messages and debugfs updates Error messages and debugfs updates: - Fix up GID_FT error messages - Enhance debugfs with slow_ring_trace, dumpslim and nodelist information - Add log type (and messages) for vport state changes - Enhance log messages when retries ELS fail Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 6 +- drivers/scsi/lpfc/lpfc_crtn.h | 2 + drivers/scsi/lpfc/lpfc_ct.c | 26 ++- drivers/scsi/lpfc/lpfc_debugfs.c | 443 +++++++++++++++++++++++++++++++++++---- drivers/scsi/lpfc/lpfc_debugfs.h | 2 +- drivers/scsi/lpfc/lpfc_els.c | 11 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 9 + drivers/scsi/lpfc/lpfc_sli.c | 37 ++++ drivers/scsi/lpfc/lpfc_vport.c | 10 +- 9 files changed, 488 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index f8f64d6485cd..3f64c4b81b0c 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -335,7 +335,7 @@ struct lpfc_vport { struct dentry *debug_disc_trc; struct dentry *debug_nodelist; struct dentry *vport_debugfs_root; - struct lpfc_disc_trc *disc_trc; + struct lpfc_debugfs_trc *disc_trc; atomic_t disc_trc_cnt; #endif }; @@ -547,6 +547,10 @@ struct lpfc_hba { #ifdef CONFIG_LPFC_DEBUG_FS struct dentry *hba_debugfs_root; atomic_t debugfs_vport_count; + struct dentry *debug_dumpslim; + struct dentry *debug_slow_ring_trc; + struct lpfc_debugfs_trc *slow_ring_trc; + atomic_t slow_ring_trc_cnt; #endif /* Fields used for heart beat. */ diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e19d1a746586..f9fdc862028a 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -271,6 +271,8 @@ extern void lpfc_debugfs_initialize(struct lpfc_vport *); extern void lpfc_debugfs_terminate(struct lpfc_vport *); extern void lpfc_debugfs_disc_trc(struct lpfc_vport *, int, char *, uint32_t, uint32_t, uint32_t); +extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t, + uint32_t, uint32_t); /* Interface exported by fabric iocb scheduler */ int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index ae9d6f385a6c..edbebffa26cf 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -607,7 +607,25 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } else if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { /* NameServer Rsp Error */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, + if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ) + && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) { + lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, + "%d (%d):0269 No NameServer Entries " + "Data: x%x x%x x%x x%x\n", + phba->brd_no, vport->vpi, + CTrsp->CommandResponse.bits.CmdRsp, + (uint32_t) CTrsp->ReasonCode, + (uint32_t) CTrsp->Explanation, + vport->fc_flag); + + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, + "GID_FT no entry cmd:x%x rsn:x%x exp:x%x", + (uint32_t)CTrsp->CommandResponse.bits.CmdRsp, + (uint32_t) CTrsp->ReasonCode, + (uint32_t) CTrsp->Explanation); + } + else { + lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d (%d):0240 NameServer Rsp Error " "Data: x%x x%x x%x x%x\n", phba->brd_no, vport->vpi, @@ -616,11 +634,13 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, (uint32_t) CTrsp->Explanation, vport->fc_flag); - lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, "GID_FT rsp err1 cmd:x%x rsn:x%x exp:x%x", (uint32_t)CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation); + } + } else { /* NameServer Rsp Error */ @@ -696,7 +716,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if ((fbits & FC4_FEATURE_INIT) && !(fbits & FC4_FEATURE_TARGET)) { lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0245 Skip x%x GFF " + "%d (%d):0270 Skip x%x GFF " "NameServer Rsp Data: (init) " "x%x x%x\n", phba->brd_no, vport->vpi, did, fbits, diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 673cfe11cc2b..2310a2d1d8ce 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -75,11 +75,18 @@ static int lpfc_debugfs_enable = 0; module_param(lpfc_debugfs_enable, int, 0); MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); -static int lpfc_debugfs_max_disc_trc = 0; /* This MUST be a power of 2 */ +/* This MUST be a power of 2 */ +static int lpfc_debugfs_max_disc_trc = 0; module_param(lpfc_debugfs_max_disc_trc, int, 0); MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, "Set debugfs discovery trace depth"); +/* This MUST be a power of 2 */ +static int lpfc_debugfs_max_slow_ring_trc = 0; +module_param(lpfc_debugfs_max_slow_ring_trc, int, 0); +MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, + "Set debugfs slow ring trace depth"); + static int lpfc_debugfs_mask_disc_trc = 0; module_param(lpfc_debugfs_mask_disc_trc, int, 0); MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, @@ -87,19 +94,22 @@ MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, #include -/* size of discovery_trace output line */ -#define LPFC_DISC_TRC_ENTRY_SIZE 80 +/* size of output line, for discovery_trace and slow_ring_trace */ +#define LPFC_DEBUG_TRC_ENTRY_SIZE 100 /* nodelist output buffer size */ #define LPFC_NODELIST_SIZE 8192 #define LPFC_NODELIST_ENTRY_SIZE 120 +/* dump_slim output buffer size */ +#define LPFC_DUMPSLIM_SIZE 4096 + struct lpfc_debug { char *buffer; int len; }; -atomic_t lpfc_debugfs_disc_trc_cnt = ATOMIC_INIT(0); +atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); unsigned long lpfc_debugfs_start_time = 0L; static int @@ -107,8 +117,8 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) { int i, index, len, enable; uint32_t ms; - struct lpfc_disc_trc *dtp; - char buffer[80]; + struct lpfc_debugfs_trc *dtp; + char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; enable = lpfc_debugfs_enable; @@ -122,7 +132,8 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) if (!dtp->fmt) continue; ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); - snprintf(buffer, 80, "%010d:%010d ms:%s\n", + snprintf(buffer, + LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", dtp->seq_cnt, ms, dtp->fmt); len += snprintf(buf+len, size-len, buffer, dtp->data1, dtp->data2, dtp->data3); @@ -132,7 +143,50 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) if (!dtp->fmt) continue; ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); - snprintf(buffer, 80, "%010d:%010d ms:%s\n", + snprintf(buffer, + LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", + dtp->seq_cnt, ms, dtp->fmt); + len += snprintf(buf+len, size-len, buffer, + dtp->data1, dtp->data2, dtp->data3); + } + + lpfc_debugfs_enable = enable; + return len; +} + +static int +lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) +{ + int i, index, len, enable; + uint32_t ms; + struct lpfc_debugfs_trc *dtp; + char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; + + + enable = lpfc_debugfs_enable; + lpfc_debugfs_enable = 0; + + len = 0; + index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) & + (lpfc_debugfs_max_slow_ring_trc - 1); + for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) { + dtp = phba->slow_ring_trc + i; + if (!dtp->fmt) + continue; + ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); + snprintf(buffer, + LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", + dtp->seq_cnt, ms, dtp->fmt); + len += snprintf(buf+len, size-len, buffer, + dtp->data1, dtp->data2, dtp->data3); + } + for (i = 0; i < index; i++) { + dtp = phba->slow_ring_trc + i; + if (!dtp->fmt) + continue; + ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); + snprintf(buffer, + LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", dtp->seq_cnt, ms, dtp->fmt); len += snprintf(buf+len, size-len, buffer, dtp->data1, dtp->data2, dtp->data3); @@ -142,6 +196,95 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) return len; } +static int +lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size) +{ + int len = 0; + int cnt, i, off; + uint32_t word0, word1, word2, word3; + uint32_t *ptr; + struct lpfc_pgp *pgpp; + struct lpfc_sli *psli = &phba->sli; + struct lpfc_sli_ring *pring; + + cnt = LPFC_DUMPSLIM_SIZE; + off = 0; + spin_lock_irq(&phba->hbalock); + + len += snprintf(buf+len, size-len, "SLIM Mailbox\n"); + ptr = (uint32_t *)phba->slim2p; + i = sizeof(MAILBOX_t); + while (i > 0) { + len += snprintf(buf+len, size-len, + "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), + *(ptr+5), *(ptr+6), *(ptr+7)); + ptr += 8; + i -= (8 * sizeof(uint32_t)); + off += (8 * sizeof(uint32_t)); + } + + len += snprintf(buf+len, size-len, "SLIM PCB\n"); + ptr = (uint32_t *)&phba->slim2p->pcb; + i = sizeof(PCB_t); + while (i > 0) { + len += snprintf(buf+len, size-len, + "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), + *(ptr+5), *(ptr+6), *(ptr+7)); + ptr += 8; + i -= (8 * sizeof(uint32_t)); + off += (8 * sizeof(uint32_t)); + } + + pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port; + pring = &psli->ring[0]; + len += snprintf(buf+len, size-len, + "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + pgpp++; + + pring = &psli->ring[1]; + len += snprintf(buf+len, size-len, + "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + pgpp++; + + pring = &psli->ring[2]; + len += snprintf(buf+len, size-len, + "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + pgpp++; + + pring = &psli->ring[3]; + len += snprintf(buf+len, size-len, + "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + + + ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get; + word0 = readl(phba->HAregaddr); + word1 = readl(phba->CAregaddr); + word2 = readl(phba->HSregaddr); + word3 = readl(phba->HCregaddr); + len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n", + word0, word1, word2, word3); + spin_unlock_irq(&phba->hbalock); + return len; +} + static int lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) { @@ -204,7 +347,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", ndlp->nlp_rpi, ndlp->nlp_flag); if (!ndlp->nlp_type) - len += snprintf(buf+len, size-len, "UNKNOWN_TYPE"); + len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); if (ndlp->nlp_type & NLP_FC_NODE) len += snprintf(buf+len, size-len, "FC_NODE "); if (ndlp->nlp_type & NLP_FABRIC) @@ -213,7 +356,9 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ", ndlp->nlp_sid); if (ndlp->nlp_type & NLP_FCP_INITIATOR) - len += snprintf(buf+len, size-len, "FCP_INITIATOR"); + len += snprintf(buf+len, size-len, "FCP_INITIATOR "); + len += snprintf(buf+len, size-len, "refcnt:%x", + atomic_read(&ndlp->kref.refcount)); len += snprintf(buf+len, size-len, "\n"); } spin_unlock_irq(shost->host_lock); @@ -227,7 +372,7 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, uint32_t data1, uint32_t data2, uint32_t data3) { #ifdef CONFIG_LPFC_DEBUG_FS - struct lpfc_disc_trc *dtp; + struct lpfc_debugfs_trc *dtp; int index; if (!(lpfc_debugfs_mask_disc_trc & mask)) @@ -244,7 +389,32 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, dtp->data1 = data1; dtp->data2 = data2; dtp->data3 = data3; - dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_disc_trc_cnt); + dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); + dtp->jif = jiffies; +#endif + return; +} + +inline void +lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, + uint32_t data1, uint32_t data2, uint32_t data3) +{ +#ifdef CONFIG_LPFC_DEBUG_FS + struct lpfc_debugfs_trc *dtp; + int index; + + if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc || + !phba || !phba->slow_ring_trc) + return; + + index = atomic_inc_return(&phba->slow_ring_trc_cnt) & + (lpfc_debugfs_max_slow_ring_trc - 1); + dtp = phba->slow_ring_trc + index; + dtp->fmt = fmt; + dtp->data1 = data1; + dtp->data2 = data2; + dtp->data3 = data3; + dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); dtp->jif = jiffies; #endif return; @@ -269,7 +439,7 @@ lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) goto out; /* Round to page boundry */ - size = (lpfc_debugfs_max_disc_trc * LPFC_DISC_TRC_ENTRY_SIZE); + size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); size = PAGE_ALIGN(size); debug->buffer = kmalloc(size, GFP_KERNEL); @@ -286,6 +456,68 @@ out: return rc; } +static int +lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) +{ + struct lpfc_hba *phba = inode->i_private; + struct lpfc_debug *debug; + int size; + int rc = -ENOMEM; + + if (!lpfc_debugfs_max_slow_ring_trc) { + rc = -ENOSPC; + goto out; + } + + debug = kmalloc(sizeof(*debug), GFP_KERNEL); + if (!debug) + goto out; + + /* Round to page boundry */ + size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); + size = PAGE_ALIGN(size); + + debug->buffer = kmalloc(size, GFP_KERNEL); + if (!debug->buffer) { + kfree(debug); + goto out; + } + + debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size); + file->private_data = debug; + + rc = 0; +out: + return rc; +} + +static int +lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file) +{ + struct lpfc_hba *phba = inode->i_private; + struct lpfc_debug *debug; + int rc = -ENOMEM; + + debug = kmalloc(sizeof(*debug), GFP_KERNEL); + if (!debug) + goto out; + + /* Round to page boundry */ + debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL); + if (!debug->buffer) { + kfree(debug); + goto out; + } + + debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer, + LPFC_DUMPSLIM_SIZE); + file->private_data = debug; + + rc = 0; +out: + return rc; +} + static int lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) { @@ -372,6 +604,24 @@ static struct file_operations lpfc_debugfs_op_nodelist = { .release = lpfc_debugfs_release, }; +#undef lpfc_debugfs_op_dumpslim +static struct file_operations lpfc_debugfs_op_dumpslim = { + .owner = THIS_MODULE, + .open = lpfc_debugfs_dumpslim_open, + .llseek = lpfc_debugfs_lseek, + .read = lpfc_debugfs_read, + .release = lpfc_debugfs_release, +}; + +#undef lpfc_debugfs_op_slow_ring_trc +static struct file_operations lpfc_debugfs_op_slow_ring_trc = { + .owner = THIS_MODULE, + .open = lpfc_debugfs_slow_ring_trc_open, + .llseek = lpfc_debugfs_lseek, + .read = lpfc_debugfs_read, + .release = lpfc_debugfs_release, +}; + static struct dentry *lpfc_debugfs_root = NULL; static atomic_t lpfc_debugfs_hba_count; #endif @@ -387,60 +637,142 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) if (!lpfc_debugfs_enable) return; - if (lpfc_debugfs_max_disc_trc) { - num = lpfc_debugfs_max_disc_trc - 1; - if (num & lpfc_debugfs_max_disc_trc) { - /* Change to be a power of 2 */ - num = lpfc_debugfs_max_disc_trc; - i = 0; - while (num > 1) { - num = num >> 1; - i++; - } - lpfc_debugfs_max_disc_trc = (1 << i); - printk(KERN_ERR - "lpfc_debugfs_max_disc_trc changed to %d\n", - lpfc_debugfs_max_disc_trc); - } - } - + /* Setup lpfc root directory */ if (!lpfc_debugfs_root) { lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); atomic_set(&lpfc_debugfs_hba_count, 0); - if (!lpfc_debugfs_root) + if (!lpfc_debugfs_root) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cannot create debugfs root (lpfc)", + phba->brd_no); goto debug_failed; + } } + if (!lpfc_debugfs_start_time) + lpfc_debugfs_start_time = jiffies; + + /* Setup lpfcX directory for specific HBA */ snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); if (!phba->hba_debugfs_root) { phba->hba_debugfs_root = debugfs_create_dir(name, lpfc_debugfs_root); - if (!phba->hba_debugfs_root) + if (!phba->hba_debugfs_root) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cannot create debugfs hba (lpfc%d)", + phba->brd_no, phba->brd_no); goto debug_failed; + } atomic_inc(&lpfc_debugfs_hba_count); atomic_set(&phba->debugfs_vport_count, 0); + + /* Setup dumpslim */ + snprintf(name, sizeof(name), "dumpslim"); + phba->debug_dumpslim = + debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, + phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_dumpslim); + if (!phba->debug_dumpslim) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cannot create debugfs dumpslim (lpfc%d)", + phba->brd_no, phba->brd_no); + goto debug_failed; + } + + /* Setup slow ring trace */ + if (lpfc_debugfs_max_slow_ring_trc) { + num = lpfc_debugfs_max_slow_ring_trc - 1; + if (num & lpfc_debugfs_max_slow_ring_trc) { + /* Change to be a power of 2 */ + num = lpfc_debugfs_max_slow_ring_trc; + i = 0; + while (num > 1) { + num = num >> 1; + i++; + } + lpfc_debugfs_max_slow_ring_trc = (1 << i); + printk(KERN_ERR + "lpfc_debugfs_max_slow_ring_trc change to %d\n", + lpfc_debugfs_max_slow_ring_trc); + } + } + + + snprintf(name, sizeof(name), "slow_ring_trace"); + phba->debug_slow_ring_trc = + debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, + phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_slow_ring_trc); + if (!phba->debug_slow_ring_trc) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cannot create debugfs " + "slow_ring_trace (lpfc%d)", + phba->brd_no, phba->brd_no); + goto debug_failed; + } + if (!phba->slow_ring_trc) { + phba->slow_ring_trc = kmalloc( + (sizeof(struct lpfc_debugfs_trc) * + lpfc_debugfs_max_slow_ring_trc), + GFP_KERNEL); + if (!phba->slow_ring_trc) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cannot create debugfs " + "slow_ring buffer (lpfc%d)", + phba->brd_no, phba->brd_no); + goto debug_failed; + } + atomic_set(&phba->slow_ring_trc_cnt, 0); + memset(phba->slow_ring_trc, 0, + (sizeof(struct lpfc_debugfs_trc) * + lpfc_debugfs_max_slow_ring_trc)); + } } snprintf(name, sizeof(name), "vport%d", vport->vpi); if (!vport->vport_debugfs_root) { vport->vport_debugfs_root = debugfs_create_dir(name, phba->hba_debugfs_root); - if (!vport->vport_debugfs_root) + if (!vport->vport_debugfs_root) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cant create debugfs vport%d (lpfc%d)", + phba->brd_no, vport->vpi, phba->brd_no); goto debug_failed; + } atomic_inc(&phba->debugfs_vport_count); } - if (!lpfc_debugfs_start_time) - lpfc_debugfs_start_time = jiffies; + if (lpfc_debugfs_max_disc_trc) { + num = lpfc_debugfs_max_disc_trc - 1; + if (num & lpfc_debugfs_max_disc_trc) { + /* Change to be a power of 2 */ + num = lpfc_debugfs_max_disc_trc; + i = 0; + while (num > 1) { + num = num >> 1; + i++; + } + lpfc_debugfs_max_disc_trc = (1 << i); + printk(KERN_ERR + "lpfc_debugfs_max_disc_trc changed to %d\n", + lpfc_debugfs_max_disc_trc); + } + } vport->disc_trc = kmalloc( - (sizeof(struct lpfc_disc_trc) * lpfc_debugfs_max_disc_trc), + (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), GFP_KERNEL); - if (!vport->disc_trc) + if (!vport->disc_trc) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "%d:0409 Cannot create debugfs " + "vport%d disc trace buffer (lpfc%d)", + phba->brd_no, vport->vpi, phba->brd_no); goto debug_failed; + } + atomic_set(&vport->disc_trc_cnt, 0); memset(vport->disc_trc, 0, - (sizeof(struct lpfc_disc_trc) * lpfc_debugfs_max_disc_trc)); + (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc)); snprintf(name, sizeof(name), "discovery_trace"); vport->debug_disc_trc = @@ -449,8 +781,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport, &lpfc_debugfs_op_disc_trc); if (!vport->debug_disc_trc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs", - phba->brd_no); + "%d:0409 Cannot create debugfs " + "vport%d discovery_trace (lpfc%d)", + phba->brd_no, vport->vpi, phba->brd_no); goto debug_failed; } snprintf(name, sizeof(name), "nodelist"); @@ -460,8 +793,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport, &lpfc_debugfs_op_nodelist); if (!vport->debug_nodelist) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs", - phba->brd_no); + "%d:0409 Cant create debugfs vport%d nodelist (lpfc%d)", + phba->brd_no, vport->vpi, phba->brd_no); goto debug_failed; } debug_failed: @@ -488,21 +821,41 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) debugfs_remove(vport->debug_nodelist); /* nodelist */ vport->debug_nodelist = NULL; } + if (vport->vport_debugfs_root) { debugfs_remove(vport->vport_debugfs_root); /* vportX */ vport->vport_debugfs_root = NULL; atomic_dec(&phba->debugfs_vport_count); } if (atomic_read(&phba->debugfs_vport_count) == 0) { - debugfs_remove(vport->phba->hba_debugfs_root); /* lpfcX */ - vport->phba->hba_debugfs_root = NULL; - atomic_dec(&lpfc_debugfs_hba_count); + + if (phba->debug_dumpslim) { + debugfs_remove(phba->debug_dumpslim); /* dumpslim */ + phba->debug_dumpslim = NULL; + } + if (phba->slow_ring_trc) { + kfree(phba->slow_ring_trc); + phba->slow_ring_trc = NULL; + } + if (phba->debug_slow_ring_trc) { + /* slow_ring_trace */ + debugfs_remove(phba->debug_slow_ring_trc); + phba->debug_slow_ring_trc = NULL; + } + + if (phba->hba_debugfs_root) { + debugfs_remove(phba->hba_debugfs_root); /* lpfcX */ + phba->hba_debugfs_root = NULL; + atomic_dec(&lpfc_debugfs_hba_count); + } + if (atomic_read(&lpfc_debugfs_hba_count) == 0) { debugfs_remove(lpfc_debugfs_root); /* lpfc */ lpfc_debugfs_root = NULL; } } #endif + return; } diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h index fffb678426a4..31e86a55391d 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.h +++ b/drivers/scsi/lpfc/lpfc_debugfs.h @@ -22,7 +22,7 @@ #define _H_LPFC_DEBUG_FS #ifdef CONFIG_LPFC_DEBUG_FS -struct lpfc_disc_trc { +struct lpfc_debugfs_trc { char *fmt; uint32_t data1; uint32_t data2; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 33fbc1666946..68fc975d4e52 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2033,12 +2033,11 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } /* No retry ELS command to remote NPORT */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0108 No retry ELS command x%x to remote " - "NPORT x%x Data: x%x\n", - phba->brd_no, vport->vpi, - cmd, did, cmdiocb->retry); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0108 No retry ELS command x%x to remote " + "NPORT x%x Retried:%d Error:x%x/%x\n", + cmd, did, cmdiocb->retry, irsp->ulpStatus, + irsp->un.ulpWord[4]); return 0; } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f2f4639eab59..ea27bbb81552 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -426,10 +426,19 @@ lpfc_work_done(struct lpfc_hba *phba) spin_lock_irq(&phba->hbalock); control = readl(phba->HCregaddr); if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) { + lpfc_debugfs_slow_ring_trc(phba, + "WRK Enable ring: cntl:x%x hacopy:x%x", + control, ha_copy, 0); + control |= (HC_R0INT_ENA << LPFC_ELS_RING); writel(control, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ } + else { + lpfc_debugfs_slow_ring_trc(phba, + "WRK Ring ok: cntl:x%x hacopy:x%x", + control, ha_copy, 0); + } spin_unlock_irq(&phba->hbalock); } lpfc_work_list_done(phba); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f4d5a6b00fde..14fe6b000b59 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -395,6 +395,14 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, */ nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag : 0; + if (pring->ringno == LPFC_ELS_RING) { + lpfc_debugfs_slow_ring_trc(phba, + "IOCB cmd ring: wd4:x%08x wd6:x%08x wd7:x%08x", + *(((uint32_t *) &nextiocb->iocb) + 4), + *(((uint32_t *) &nextiocb->iocb) + 6), + *(((uint32_t *) &nextiocb->iocb) + 7)); + } + /* * Issue iocb command to adapter */ @@ -1542,6 +1550,14 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, if (++pring->rspidx >= portRspMax) pring->rspidx = 0; + if (pring->ringno == LPFC_ELS_RING) { + lpfc_debugfs_slow_ring_trc(phba, + "IOCB rsp ring: wd4:x%08x wd6:x%08x wd7:x%08x", + *(((uint32_t *) irsp) + 4), + *(((uint32_t *) irsp) + 6), + *(((uint32_t *) irsp) + 7)); + } + writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx); if (list_empty(&(pring->iocb_continueq))) { @@ -3850,12 +3866,33 @@ lpfc_intr_handler(int irq, void *dev_id) if (status & HA_RXMASK) { spin_lock(&phba->hbalock); control = readl(phba->HCregaddr); + + lpfc_debugfs_slow_ring_trc(phba, + "ISR slow ring: ctl:x%x stat:x%x isrcnt:x%x", + control, status, + (uint32_t)phba->sli.slistat.sli_intr); + if (control & (HC_R0INT_ENA << LPFC_ELS_RING)) { + lpfc_debugfs_slow_ring_trc(phba, + "ISR Disable ring:" + "pwork:x%x hawork:x%x wait:x%x", + phba->work_ha, work_ha_copy, + (uint32_t)((unsigned long) + phba->work_wait)); + control &= ~(HC_R0INT_ENA << LPFC_ELS_RING); writel(control, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ } + else { + lpfc_debugfs_slow_ring_trc(phba, + "ISR slow ring: pwork:" + "x%x hawork:x%x wait:x%x", + phba->work_ha, work_ha_copy, + (uint32_t)((unsigned long) + phba->work_wait)); + } spin_unlock(&phba->hbalock); } } diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 85797dbf5478..c5918a643014 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -326,6 +326,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) rc = VPORT_OK; out: + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1825 Vport Created.\n"); lpfc_host_attrib_init(lpfc_shost_from_vport(vport)); error_out: return rc; @@ -371,6 +373,8 @@ disable_vport(struct fc_vport *fc_vport) lpfc_mbx_unreg_vpi(vport); lpfc_vport_set_state(vport, FC_VPORT_DISABLED); + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1826 Vport Disabled.\n"); return VPORT_OK; } @@ -408,7 +412,8 @@ enable_vport(struct fc_vport *fc_vport) } else { lpfc_vport_set_state(vport, FC_VPORT_FAILED); } - + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1827 Vport Enabled.\n"); return VPORT_OK; } @@ -511,7 +516,8 @@ skip_logo: spin_lock_irq(&phba->hbalock); list_del_init(&vport->listentry); spin_unlock_irq(&phba->hbalock); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1828 Vport Deleted.\n"); rc = VPORT_OK; out: scsi_host_put(shost); -- cgit v1.2.3 From 549e55cd2a1b83ea45ac17fb6c309654a3d371a4 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:09:51 -0400 Subject: [SCSI] lpfc 8.2.2 : Fix locking around HBA's port_list Cleans up a lot of bad behaviors that have been in this area a while Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 9 ++- drivers/scsi/lpfc/lpfc_attr.c | 21 ++++-- drivers/scsi/lpfc/lpfc_crtn.h | 2 + drivers/scsi/lpfc/lpfc_ct.c | 12 +-- drivers/scsi/lpfc/lpfc_els.c | 61 ++++++++++++--- drivers/scsi/lpfc/lpfc_hbadisc.c | 157 +++++++++++++++++---------------------- drivers/scsi/lpfc/lpfc_init.c | 134 ++++++++++++++++++--------------- drivers/scsi/lpfc/lpfc_scsi.c | 92 +++++++++++------------ drivers/scsi/lpfc/lpfc_vport.c | 41 +++++++++- drivers/scsi/lpfc/lpfc_vport.h | 2 + 10 files changed, 308 insertions(+), 223 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 3f64c4b81b0c..6127635e6275 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -528,10 +528,11 @@ struct lpfc_hba { struct fc_host_statistics link_stats; struct list_head port_list; - struct lpfc_vport *pport; /* physical lpfc_vport pointer */ - uint16_t max_vpi; /* Maximum virtual nports */ -#define LPFC_MAX_VPI 100 /* Max number of VPorts supported */ - unsigned long *vpi_bmask; /* vpi allocation table */ + struct lpfc_vport *pport; /* physical lpfc_vport pointer */ + uint16_t max_vpi; /* Maximum virtual nports */ +#define LPFC_MAX_VPI 100 /* Max number of VPI supported */ +#define LPFC_MAX_VPORTS (LPFC_MAX_VPI+1)/* Max number of VPorts supported */ + unsigned long *vpi_bmask; /* vpi allocation table */ /* Data structure used by fabric iocb scheduler */ struct list_head fabric_iocb_list; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 860a52c090f4..dbced066a361 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1060,19 +1060,24 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val) static void lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) { - struct lpfc_vport *vport; + struct lpfc_vport **vports; struct Scsi_Host *shost; struct lpfc_nodelist *ndlp; + int i; - list_for_each_entry(vport, &phba->port_list, listentry) { - shost = lpfc_shost_from_vport(vport); - spin_lock_irq(shost->host_lock); - list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + shost = lpfc_shost_from_vport(vports[i]); + spin_lock_irq(shost->host_lock); + list_for_each_entry(ndlp, &vports[i]->fc_nodes, + nlp_listp) if (ndlp->rport) ndlp->rport->dev_loss_tmo = - phba->cfg_devloss_tmo; - spin_unlock_irq(shost->host_lock); - } + phba->cfg_devloss_tmo; + spin_unlock_irq(shost->host_lock); + } + lpfc_destroy_vport_work_array(vports); } static int diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index f9fdc862028a..6689d6f85adc 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -40,6 +40,7 @@ void lpfc_reg_vpi(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *); void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); +struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); int lpfc_linkdown(struct lpfc_hba *); void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -117,6 +118,7 @@ void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, int lpfc_els_handle_rscn(struct lpfc_vport *); void lpfc_els_flush_rscn(struct lpfc_vport *); int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t); +void lpfc_els_flush_all_cmd(struct lpfc_hba *); void lpfc_els_flush_cmd(struct lpfc_vport *); int lpfc_els_disc_adisc(struct lpfc_vport *); int lpfc_els_disc_plogi(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index edbebffa26cf..43e2e33f9a07 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -390,17 +390,19 @@ lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, return 0; } -static struct lpfc_vport * +struct lpfc_vport * lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) { - struct lpfc_vport *vport_curr; + unsigned long flags; + spin_lock_irqsave(&phba->hbalock, flags); list_for_each_entry(vport_curr, &phba->port_list, listentry) { - if ((vport_curr->fc_myDID) && - (vport_curr->fc_myDID == did)) + if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) { + spin_unlock_irqrestore(&phba->hbalock, flags); return vport_curr; + } } - + spin_unlock_irqrestore(&phba->hbalock, flags); return NULL; } diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 68fc975d4e52..b8e048a467d2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2800,7 +2800,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; struct lpfc_dmabuf *pcmd; - struct lpfc_vport *next_vport; uint32_t *lp, *datap; IOCB_t *icmd; uint32_t payload_len, length, nportid, *cmd; @@ -2850,13 +2849,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, nportid = ((be32_to_cpu(nportid)) & Mask_DID); i -= sizeof(uint32_t); rscn_id++; - list_for_each_entry(next_vport, &phba->port_list, - listentry) { - if (nportid == next_vport->fc_myDID) { - hba_id++; - break; - } - } + if (lpfc_find_vport_by_did(phba, nportid)) + hba_id++; } if (rscn_id == hba_id) { /* ALL NPortIDs in RSCN are on HBA */ @@ -3740,6 +3734,50 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) return; } +void +lpfc_els_flush_all_cmd(struct lpfc_hba *phba) +{ + LIST_HEAD(completions); + struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; + struct lpfc_iocbq *tmp_iocb, *piocb; + IOCB_t *cmd = NULL; + + lpfc_fabric_abort_hba(phba); + spin_lock_irq(&phba->hbalock); + list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { + cmd = &piocb->iocb; + if (piocb->iocb_flag & LPFC_IO_LIBDFC) + continue; + /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */ + if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN || + cmd->ulpCommand == CMD_QUE_RING_BUF64_CN || + cmd->ulpCommand == CMD_CLOSE_XRI_CN || + cmd->ulpCommand == CMD_ABORT_XRI_CN) + continue; + list_move_tail(&piocb->list, &completions); + pring->txq_cnt--; + } + list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { + if (piocb->iocb_flag & LPFC_IO_LIBDFC) + continue; + lpfc_sli_issue_abort_iotag(phba, pring, piocb); + } + spin_unlock_irq(&phba->hbalock); + while (!list_empty(&completions)) { + piocb = list_get_first(&completions, struct lpfc_iocbq, list); + cmd = &piocb->iocb; + list_del_init(&piocb->list); + if (!piocb->iocb_cmpl) + lpfc_sli_release_iocbq(phba, piocb); + else { + cmd->ulpStatus = IOSTAT_LOCAL_REJECT; + cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + (piocb->iocb_cmpl) (phba, piocb, piocb); + } + } + return; +} + static void lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) @@ -4009,11 +4047,16 @@ static struct lpfc_vport * lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) { struct lpfc_vport *vport; + unsigned long flags; + spin_lock_irqsave(&phba->hbalock, flags); list_for_each_entry(vport, &phba->port_list, listentry) { - if (vport->vpi == vpi) + if (vport->vpi == vpi) { + spin_unlock_irqrestore(&phba->hbalock, flags); return vport; + } } + spin_unlock_irqrestore(&phba->hbalock, flags); return NULL; } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index ea27bbb81552..556d55fc9456 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -349,7 +349,8 @@ lpfc_work_done(struct lpfc_hba *phba) { struct lpfc_sli_ring *pring; uint32_t ha_copy, status, control, work_port_events; - struct lpfc_vport *vport; + struct lpfc_vport **vports; + int i; spin_lock_irq(&phba->hbalock); ha_copy = phba->work_ha; @@ -364,48 +365,31 @@ lpfc_work_done(struct lpfc_hba *phba) if (ha_copy & HA_LATT) lpfc_handle_latt(phba); - - spin_lock_irq(&phba->hbalock); - list_for_each_entry(vport, &phba->port_list, listentry) { - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - - if (!scsi_host_get(shost)) { - continue; + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + work_port_events = vports[i]->work_port_events; + if (work_port_events & WORKER_DISC_TMO) + lpfc_disc_timeout_handler(vports[i]); + if (work_port_events & WORKER_ELS_TMO) + lpfc_els_timeout_handler(vports[i]); + if (work_port_events & WORKER_HB_TMO) + lpfc_hb_timeout_handler(phba); + if (work_port_events & WORKER_MBOX_TMO) + lpfc_mbox_timeout_handler(phba); + if (work_port_events & WORKER_FABRIC_BLOCK_TMO) + lpfc_unblock_fabric_iocbs(phba); + if (work_port_events & WORKER_FDMI_TMO) + lpfc_fdmi_timeout_handler(vports[i]); + if (work_port_events & WORKER_RAMP_DOWN_QUEUE) + lpfc_ramp_down_queue_handler(phba); + if (work_port_events & WORKER_RAMP_UP_QUEUE) + lpfc_ramp_up_queue_handler(phba); + spin_lock_irq(&vports[i]->work_port_lock); + vports[i]->work_port_events &= ~work_port_events; + spin_unlock_irq(&vports[i]->work_port_lock); } - spin_unlock_irq(&phba->hbalock); - work_port_events = vport->work_port_events; - - if (work_port_events & WORKER_DISC_TMO) - lpfc_disc_timeout_handler(vport); - - if (work_port_events & WORKER_ELS_TMO) - lpfc_els_timeout_handler(vport); - - if (work_port_events & WORKER_HB_TMO) - lpfc_hb_timeout_handler(phba); - - if (work_port_events & WORKER_MBOX_TMO) - lpfc_mbox_timeout_handler(phba); - - if (work_port_events & WORKER_FABRIC_BLOCK_TMO) - lpfc_unblock_fabric_iocbs(phba); - - if (work_port_events & WORKER_FDMI_TMO) - lpfc_fdmi_timeout_handler(vport); - - if (work_port_events & WORKER_RAMP_DOWN_QUEUE) - lpfc_ramp_down_queue_handler(phba); - - if (work_port_events & WORKER_RAMP_UP_QUEUE) - lpfc_ramp_up_queue_handler(phba); - - spin_lock_irq(&vport->work_port_lock); - vport->work_port_events &= ~work_port_events; - spin_unlock_irq(&vport->work_port_lock); - scsi_host_put(shost); - spin_lock_irq(&phba->hbalock); - } - spin_unlock_irq(&phba->hbalock); + lpfc_destroy_vport_work_array(vports); pring = &phba->sli.ring[LPFC_ELS_RING]; status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); @@ -448,32 +432,22 @@ static int check_work_wait_done(struct lpfc_hba *phba) { struct lpfc_vport *vport; - struct lpfc_sli_ring *pring; + struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; int rc = 0; spin_lock_irq(&phba->hbalock); list_for_each_entry(vport, &phba->port_list, listentry) { if (vport->work_port_events) { rc = 1; - goto exit; + break; } } - - if (phba->work_ha || (!list_empty(&phba->work_list)) || - kthread_should_stop()) { - rc = 1; - goto exit; - } - - pring = &phba->sli.ring[LPFC_ELS_RING]; - if (pring->flag & LPFC_DEFERRED_RING_EVENT) + if (rc || phba->work_ha || (!list_empty(&phba->work_list)) || + kthread_should_stop() || pring->flag & LPFC_DEFERRED_RING_EVENT) { rc = 1; -exit: - if (rc) phba->work_found++; - else + } else phba->work_found = 0; - spin_unlock_irq(&phba->hbalock); return rc; } @@ -601,7 +575,6 @@ lpfc_linkdown_port(struct lpfc_vport *vport) /* free any ndlp's on unused list */ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) - /* free any ndlp's in unused state */ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) lpfc_drop_node(vport, ndlp); @@ -614,8 +587,9 @@ lpfc_linkdown(struct lpfc_hba *phba) { struct lpfc_vport *vport = phba->pport; struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_vport *port_iterator; + struct lpfc_vport **vports; LPFC_MBOXQ_t *mb; + int i; if (phba->link_state == LPFC_LINK_DOWN) { return 0; @@ -626,13 +600,13 @@ lpfc_linkdown(struct lpfc_hba *phba) phba->pport->fc_flag &= ~FC_LBIT; } spin_unlock_irq(&phba->hbalock); - - list_for_each_entry(port_iterator, &phba->port_list, listentry) { - - /* Issue a LINK DOWN event to all nodes */ - lpfc_linkdown_port(port_iterator); - } - + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + /* Issue a LINK DOWN event to all nodes */ + lpfc_linkdown_port(vports[i]); + } + lpfc_destroy_vport_work_array(vports); /* Clean up any firmware default rpi's */ mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (mb) { @@ -733,7 +707,8 @@ lpfc_linkup_port(struct lpfc_vport *vport) static int lpfc_linkup(struct lpfc_hba *phba) { - struct lpfc_vport *vport; + struct lpfc_vport **vports; + int i; phba->link_state = LPFC_LINK_UP; @@ -741,9 +716,11 @@ lpfc_linkup(struct lpfc_hba *phba) clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); del_timer_sync(&phba->fabric_block_timer); - list_for_each_entry(vport, &phba->port_list, listentry) { - lpfc_linkup_port(vport); - } + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) + lpfc_linkup_port(vports[i]); + lpfc_destroy_vport_work_array(vports); if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) lpfc_issue_clear_la(phba, phba->pport); @@ -1298,15 +1275,15 @@ void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { struct lpfc_vport *vport = pmb->vport; - struct lpfc_vport *next_vport; MAILBOX_t *mb = &pmb->mb; struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); struct lpfc_nodelist *ndlp; - ndlp = (struct lpfc_nodelist *) pmb->context2; + struct lpfc_vport **vports; + int i; + ndlp = (struct lpfc_nodelist *) pmb->context2; pmb->context1 = NULL; pmb->context2 = NULL; - if (mb->mbxStatus) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); @@ -1337,21 +1314,27 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ if (vport->port_state == LPFC_FABRIC_CFG_LINK) { - list_for_each_entry(next_vport, &phba->port_list, listentry) { - if (next_vport->port_type == LPFC_PHYSICAL_PORT) - continue; - - if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) - lpfc_initial_fdisc(next_vport); - else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { - lpfc_vport_set_state(vport, - FC_VPORT_NO_FABRIC_SUPP); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0259 No NPIV Fabric " - "support\n", - phba->brd_no, vport->vpi); + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; + i < LPFC_MAX_VPORTS && vports[i] != NULL; + i++) { + if (vports[i]->port_type == LPFC_PHYSICAL_PORT) + continue; + if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) + lpfc_initial_fdisc(vports[i]); + else if (phba->sli3_options & + LPFC_SLI3_NPIV_ENABLED) { + lpfc_vport_set_state(vports[i], + FC_VPORT_NO_FABRIC_SUPP); + lpfc_printf_log(phba, KERN_ERR, LOG_ELS, + "%d (%d):0259 No NPIV " + "Fabric support\n", + phba->brd_no, + vports[i]->vpi); + } } - } + lpfc_destroy_vport_work_array(vports); lpfc_do_scr_ns_plogi(phba, vport); } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 07bd0dcdf0d6..484070c82974 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -437,16 +437,18 @@ lpfc_config_port_post(struct lpfc_hba *phba) int lpfc_hba_down_prep(struct lpfc_hba *phba) { - struct lpfc_vport *vport = phba->pport; + struct lpfc_vport **vports; + int i; /* Disable interrupts */ writel(0, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ - list_for_each_entry(vport, &phba->port_list, listentry) { - lpfc_cleanup_discovery_resources(vport); - } - + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) + lpfc_cleanup_discovery_resources(vports[i]); + lpfc_destroy_vport_work_array(vports); return 0; } @@ -615,9 +617,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba) struct lpfc_vport *vport = phba->pport; struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; - struct lpfc_vport *port_iterator; + struct lpfc_vport **vports; uint32_t event_data; struct Scsi_Host *shost; + int i; /* If the pci channel is offline, ignore possible errors, * since we cannot communicate with the pci card anyway. */ @@ -632,14 +635,17 @@ lpfc_handle_eratt(struct lpfc_hba *phba) "Data: x%x x%x x%x\n", phba->brd_no, phba->work_hs, phba->work_status[0], phba->work_status[1]); - list_for_each_entry(port_iterator, &phba->port_list, - listentry) { - shost = lpfc_shost_from_vport(port_iterator); - - spin_lock_irq(shost->host_lock); - port_iterator->fc_flag |= FC_ESTABLISH_LINK; - spin_unlock_irq(shost->host_lock); - } + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; + i < LPFC_MAX_VPORTS && vports[i] != NULL; + i++){ + shost = lpfc_shost_from_vport(vports[i]); + spin_lock_irq(shost->host_lock); + vports[i]->fc_flag |= FC_ESTABLISH_LINK; + spin_unlock_irq(shost->host_lock); + } + lpfc_destroy_vport_work_array(vports); spin_lock_irq(&phba->hbalock); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(&phba->hbalock); @@ -708,7 +714,6 @@ lpfc_handle_latt(struct lpfc_hba *phba) { struct lpfc_vport *vport = phba->pport; struct lpfc_sli *psli = &phba->sli; - struct lpfc_vport *port_iterator; LPFC_MBOXQ_t *pmb; volatile uint32_t control; struct lpfc_dmabuf *mp; @@ -729,8 +734,7 @@ lpfc_handle_latt(struct lpfc_hba *phba) rc = -EIO; /* Cleanup any outstanding ELS commands */ - list_for_each_entry(port_iterator, &phba->port_list, listentry) - lpfc_els_flush_cmd(port_iterator); + lpfc_els_flush_all_cmd(phba); psli->slistat.link_event++; lpfc_read_la(phba, pmb, mp); @@ -1313,22 +1317,26 @@ static void lpfc_establish_link_tmo(unsigned long ptr) { struct lpfc_hba *phba = (struct lpfc_hba *) ptr; - struct lpfc_vport *vport = phba->pport; + struct lpfc_vport **vports; unsigned long iflag; + int i; /* Re-establishing Link, timer expired */ lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, "%d:1300 Re-establishing Link, timer expired " "Data: x%x x%x\n", - phba->brd_no, vport->fc_flag, - vport->port_state); - list_for_each_entry(vport, &phba->port_list, listentry) { - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - - spin_lock_irqsave(shost->host_lock, iflag); - vport->fc_flag &= ~FC_ESTABLISH_LINK; - spin_unlock_irqrestore(shost->host_lock, iflag); - } + phba->brd_no, phba->pport->fc_flag, + phba->pport->port_state); + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + struct Scsi_Host *shost; + shost = lpfc_shost_from_vport(vports[i]); + spin_lock_irqsave(shost->host_lock, iflag); + vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; + spin_unlock_irqrestore(shost->host_lock, iflag); + } + lpfc_destroy_vport_work_array(vports); } void @@ -1343,12 +1351,16 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport) static void lpfc_stop_phba_timers(struct lpfc_hba *phba) { - struct lpfc_vport *vport; + struct lpfc_vport **vports; + int i; del_timer_sync(&phba->fcp_poll_timer); del_timer_sync(&phba->fc_estabtmo); - list_for_each_entry(vport, &phba->port_list, listentry) - lpfc_stop_vport_timers(vport); + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) + lpfc_stop_vport_timers(vports[i]); + lpfc_destroy_vport_work_array(vports); del_timer_sync(&phba->sli.mbox_tmo); del_timer_sync(&phba->fabric_block_timer); phba->hb_outstanding = 0; @@ -1360,6 +1372,8 @@ int lpfc_online(struct lpfc_hba *phba) { struct lpfc_vport *vport = phba->pport; + struct lpfc_vport **vports; + int i; if (!phba) return 0; @@ -1383,14 +1397,18 @@ lpfc_online(struct lpfc_hba *phba) return 1; } - list_for_each_entry(vport, &phba->port_list, listentry) { - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_OFFLINE_MODE; - if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) - vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; - spin_unlock_irq(shost->host_lock); - } + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + struct Scsi_Host *shost; + shost = lpfc_shost_from_vport(vports[i]); + spin_lock_irq(shost->host_lock); + vports[i]->fc_flag &= ~FC_OFFLINE_MODE; + if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) + vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + spin_unlock_irq(shost->host_lock); + } + lpfc_destroy_vport_work_array(vports); lpfc_unblock_mgmt_io(phba); return 0; @@ -1440,39 +1458,35 @@ lpfc_offline_prep(struct lpfc_hba * phba) void lpfc_offline(struct lpfc_hba *phba) { - struct lpfc_vport *vport = phba->pport; - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_vport *port_iterator; + struct Scsi_Host *shost; + struct lpfc_vport **vports; + int i; - if (vport->fc_flag & FC_OFFLINE_MODE) + if (phba->pport->fc_flag & FC_OFFLINE_MODE) return; /* stop all timers associated with this hba */ lpfc_stop_phba_timers(phba); - list_for_each_entry(port_iterator, &phba->port_list, listentry) { - port_iterator->work_port_events = 0; - } - lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "%d:0460 Bring Adapter offline\n", phba->brd_no); - /* Bring down the SLI Layer and cleanup. The HBA is offline now. */ lpfc_sli_hba_down(phba); spin_lock_irq(&phba->hbalock); phba->work_ha = 0; - vport->fc_flag |= FC_OFFLINE_MODE; spin_unlock_irq(&phba->hbalock); - list_for_each_entry(port_iterator, &phba->port_list, listentry) { - shost = lpfc_shost_from_vport(port_iterator); - - lpfc_cleanup(port_iterator); - spin_lock_irq(shost->host_lock); - vport->work_port_events = 0; - vport->fc_flag |= FC_OFFLINE_MODE; - spin_unlock_irq(shost->host_lock); - } + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + shost = lpfc_shost_from_vport(vports[i]); + lpfc_cleanup(vports[i]); + spin_lock_irq(shost->host_lock); + vports[i]->work_port_events = 0; + vports[i]->fc_flag |= FC_OFFLINE_MODE; + spin_unlock_irq(shost->host_lock); + } + lpfc_destroy_vport_work_array(vports); } /****************************************************************************** @@ -1509,7 +1523,6 @@ lpfc_scsi_free(struct lpfc_hba *phba) return 0; } - struct lpfc_vport * lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) { @@ -1570,7 +1583,9 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) if (error) goto out_put_shost; + spin_lock_irq(&phba->hbalock); list_add_tail(&vport->listentry, &phba->port_list); + spin_unlock_irq(&phba->hbalock); return vport; out_put_shost: @@ -1990,8 +2005,10 @@ lpfc_pci_remove_one(struct pci_dev *pdev) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct lpfc_vport *port_iterator; + spin_lock_irq(&phba->hbalock); list_for_each_entry(port_iterator, &phba->port_list, listentry) port_iterator->load_flag |= FC_UNLOADING; + spin_unlock_irq(&phba->hbalock); kfree(vport->vname); lpfc_free_sysfs_attr(vport); @@ -2012,7 +2029,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) list_del_init(&vport->listentry); spin_unlock_irq(&phba->hbalock); - lpfc_debugfs_terminate(vport); lpfc_cleanup(vport); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 8f45bbc42126..0284ded96bad 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -119,42 +119,40 @@ lpfc_rampup_queue_depth(struct lpfc_hba *phba, void lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) { - struct lpfc_vport *vport; - struct Scsi_Host *host; + struct lpfc_vport **vports; + struct Scsi_Host *shost; struct scsi_device *sdev; unsigned long new_queue_depth; unsigned long num_rsrc_err, num_cmd_success; + int i; num_rsrc_err = atomic_read(&phba->num_rsrc_err); num_cmd_success = atomic_read(&phba->num_cmd_success); - spin_lock_irq(&phba->hbalock); - list_for_each_entry(vport, &phba->port_list, listentry) { - host = lpfc_shost_from_vport(vport); - if (!scsi_host_get(host)) - continue; - - spin_unlock_irq(&phba->hbalock); - - shost_for_each_device(sdev, host) { - new_queue_depth = sdev->queue_depth * num_rsrc_err / - (num_rsrc_err + num_cmd_success); - if (!new_queue_depth) - new_queue_depth = sdev->queue_depth - 1; - else + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + shost = lpfc_shost_from_vport(vports[i]); + shost_for_each_device(sdev, shost) { new_queue_depth = - sdev->queue_depth - new_queue_depth; - - if (sdev->ordered_tags) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - new_queue_depth); - else - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, - new_queue_depth); + sdev->queue_depth * num_rsrc_err / + (num_rsrc_err + num_cmd_success); + if (!new_queue_depth) + new_queue_depth = sdev->queue_depth - 1; + else + new_queue_depth = sdev->queue_depth - + new_queue_depth; + if (sdev->ordered_tags) + scsi_adjust_queue_depth(sdev, + MSG_ORDERED_TAG, + new_queue_depth); + else + scsi_adjust_queue_depth(sdev, + MSG_SIMPLE_TAG, + new_queue_depth); + } } - spin_lock_irq(&phba->hbalock); - scsi_host_put(host); - } + lpfc_destroy_vport_work_array(vports); spin_unlock_irq(&phba->hbalock); atomic_set(&phba->num_rsrc_err, 0); atomic_set(&phba->num_cmd_success, 0); @@ -163,29 +161,27 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) void lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) { - struct lpfc_vport *vport; - struct Scsi_Host *host; + struct lpfc_vport **vports; + struct Scsi_Host *shost; struct scsi_device *sdev; - - spin_lock_irq(&phba->hbalock); - list_for_each_entry(vport, &phba->port_list, listentry) { - host = lpfc_shost_from_vport(vport); - if (!scsi_host_get(host)) - continue; - - spin_unlock_irq(&phba->hbalock); - shost_for_each_device(sdev, host) { - if (sdev->ordered_tags) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - sdev->queue_depth+1); - else - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, - sdev->queue_depth+1); + int i; + + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { + shost = lpfc_shost_from_vport(vports[i]); + shost_for_each_device(sdev, shost) { + if (sdev->ordered_tags) + scsi_adjust_queue_depth(sdev, + MSG_ORDERED_TAG, + sdev->queue_depth+1); + else + scsi_adjust_queue_depth(sdev, + MSG_SIMPLE_TAG, + sdev->queue_depth+1); + } } - spin_lock_irq(&phba->hbalock); - scsi_host_put(host); - } - spin_unlock_irq(&phba->hbalock); + lpfc_destroy_vport_work_array(vports); atomic_set(&phba->num_rsrc_err, 0); atomic_set(&phba->num_cmd_success, 0); } diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index c5918a643014..e066855b0783 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -176,16 +176,21 @@ static int lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport) { struct lpfc_vport *vport; + unsigned long flags; + spin_lock_irqsave(&phba->hbalock, flags); list_for_each_entry(vport, &phba->port_list, listentry) { if (vport == new_vport) continue; /* If they match, return not unique */ if (memcmp(&vport->fc_sparam.portName, - &new_vport->fc_sparam.portName, - sizeof(struct lpfc_name)) == 0) + &new_vport->fc_sparam.portName, + sizeof(struct lpfc_name)) == 0) { + spin_unlock_irqrestore(&phba->hbalock, flags); return 0; + } } + spin_unlock_irqrestore(&phba->hbalock, flags); return 1; } @@ -524,6 +529,36 @@ out: return rc; } - EXPORT_SYMBOL(lpfc_vport_create); EXPORT_SYMBOL(lpfc_vport_delete); + +struct lpfc_vport ** +lpfc_create_vport_work_array(struct lpfc_hba *phba) +{ + struct lpfc_vport *port_iterator; + struct lpfc_vport **vports; + int index = 0; + vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *), + GFP_KERNEL); + if (vports == NULL) + return NULL; + spin_lock_irq(&phba->hbalock); + list_for_each_entry(port_iterator, &phba->port_list, listentry) { + if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) + continue; + vports[index++] = port_iterator; + } + spin_unlock_irq(&phba->hbalock); + return vports; +} + +void +lpfc_destroy_vport_work_array(struct lpfc_vport **vports) +{ + int i; + if (vports == NULL) + return; + for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++) + scsi_host_put(lpfc_shost_from_vport(vports[i])); + kfree(vports); +} diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h index f223550f8cba..91da17751a37 100644 --- a/drivers/scsi/lpfc/lpfc_vport.h +++ b/drivers/scsi/lpfc/lpfc_vport.h @@ -88,6 +88,8 @@ int lpfc_vport_create(struct fc_vport *, bool); int lpfc_vport_delete(struct fc_vport *); int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); +struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); +void lpfc_destroy_vport_work_array(struct lpfc_vport **); /* * queuecommand VPORT-specific return codes. Specified in the host byte code. -- cgit v1.2.3 From 3de2a653a127c468284c48e233719dc39769e354 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:09:59 -0400 Subject: [SCSI] lpfc 8.2.2 : Attribute and Parameter splits for vport and physical port - Split attributes up into vport and non-vport attributes. - Move vport specific cfg params to vport Many of the vport-specific behaviors were still global attributes on the physical port. Move them to the vport itself. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 34 ++-- drivers/scsi/lpfc/lpfc_attr.c | 354 ++++++++++++++++++++++++++++--------- drivers/scsi/lpfc/lpfc_crtn.h | 5 +- drivers/scsi/lpfc/lpfc_ct.c | 6 +- drivers/scsi/lpfc/lpfc_els.c | 10 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 4 +- drivers/scsi/lpfc/lpfc_init.c | 22 +-- drivers/scsi/lpfc/lpfc_nportdisc.c | 13 +- drivers/scsi/lpfc/lpfc_scsi.c | 49 +++-- drivers/scsi/lpfc/lpfc_vport.c | 6 +- 10 files changed, 354 insertions(+), 149 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 6127635e6275..fb56ff9d5da2 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -338,6 +338,20 @@ struct lpfc_vport { struct lpfc_debugfs_trc *disc_trc; atomic_t disc_trc_cnt; #endif + /* Vport Config Parameters */ + uint32_t cfg_scan_down; + uint32_t cfg_lun_queue_depth; + uint32_t cfg_nodev_tmo; + uint32_t cfg_devloss_tmo; + uint32_t cfg_restrict_login; + uint32_t cfg_peer_port_login; + uint32_t cfg_fcp_class; + uint32_t cfg_use_adisc; + uint32_t cfg_fdmi_on; + uint32_t cfg_discovery_threads; + uint32_t cfg_max_luns; + + uint32_t dev_loss_tmo_changed; }; struct hbq_s { @@ -413,28 +427,16 @@ struct lpfc_hba { uint8_t wwpn[8]; uint32_t RandomData[7]; - uint32_t cfg_log_verbose; - uint32_t cfg_lun_queue_depth; - uint32_t cfg_nodev_tmo; - uint32_t cfg_devloss_tmo; - uint32_t cfg_hba_queue_depth; - uint32_t cfg_peer_port_login; - uint32_t cfg_vport_restrict_login; - uint32_t cfg_npiv_enable; - uint32_t cfg_fcp_class; - uint32_t cfg_use_adisc; + /* HBA Config Parameters */ uint32_t cfg_ack0; + uint32_t cfg_npiv_enable; uint32_t cfg_topology; - uint32_t cfg_scan_down; uint32_t cfg_link_speed; uint32_t cfg_cr_delay; uint32_t cfg_cr_count; uint32_t cfg_multi_ring_support; uint32_t cfg_multi_ring_rctl; uint32_t cfg_multi_ring_type; - uint32_t cfg_fdmi_on; - uint32_t cfg_discovery_threads; - uint32_t cfg_max_luns; uint32_t cfg_poll; uint32_t cfg_poll_tmo; uint32_t cfg_use_msi; @@ -442,8 +444,10 @@ struct lpfc_hba { uint32_t cfg_sg_dma_buf_size; uint64_t cfg_soft_wwnn; uint64_t cfg_soft_wwpn; + uint32_t cfg_hba_queue_depth; - uint32_t dev_loss_tmo_changed; + /* Config paramters that should be in the vport */ + uint32_t cfg_log_verbose; lpfc_vpd_t vpd; /* vital product data */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index dbced066a361..61d251b1b03b 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -734,6 +734,77 @@ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ return -EINVAL;\ } +#define lpfc_vport_param_show(attr) \ +static ssize_t \ +lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +{ \ + struct Scsi_Host *shost = class_to_shost(cdev);\ + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ + int val = 0;\ + val = vport->cfg_##attr;\ + return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\ +} + +#define lpfc_vport_param_hex_show(attr) \ +static ssize_t \ +lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +{ \ + struct Scsi_Host *shost = class_to_shost(cdev);\ + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ + int val = 0;\ + val = vport->cfg_##attr;\ + return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\ +} + +#define lpfc_vport_param_init(attr, default, minval, maxval) \ +static int \ +lpfc_##attr##_init(struct lpfc_vport *vport, int val) \ +{ \ + if (val >= minval && val <= maxval) {\ + vport->cfg_##attr = val;\ + return 0;\ + }\ + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, \ + "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", \ + vport->phba->brd_no, val); \ + vport->cfg_##attr = default;\ + return -EINVAL;\ +} + +#define lpfc_vport_param_set(attr, default, minval, maxval) \ +static int \ +lpfc_##attr##_set(struct lpfc_vport *vport, int val) \ +{ \ + if (val >= minval && val <= maxval) {\ + vport->cfg_##attr = val;\ + return 0;\ + }\ + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, \ + "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", \ + vport->phba->brd_no, val); \ + return -EINVAL;\ +} + +#define lpfc_vport_param_store(attr) \ +static ssize_t \ +lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ +{ \ + struct Scsi_Host *shost = class_to_shost(cdev);\ + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ + int val=0;\ + if (!isdigit(buf[0]))\ + return -EINVAL;\ + if (sscanf(buf, "%i", &val) != 1)\ + return -EINVAL;\ + if (lpfc_##attr##_set(vport, val) == 0) \ + return strlen(buf);\ + else \ + return -EINVAL;\ +} + + #define LPFC_ATTR(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ module_param(lpfc_##name, int, 0);\ @@ -778,6 +849,50 @@ lpfc_param_store(name)\ static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ lpfc_##name##_show, lpfc_##name##_store) +#define LPFC_VPORT_ATTR(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_vport_param_init(name, defval, minval, maxval) + +#define LPFC_VPORT_ATTR_R(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_vport_param_show(name)\ +lpfc_vport_param_init(name, defval, minval, maxval)\ +static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) + +#define LPFC_VPORT_ATTR_RW(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_vport_param_show(name)\ +lpfc_vport_param_init(name, defval, minval, maxval)\ +lpfc_vport_param_set(name, defval, minval, maxval)\ +lpfc_vport_param_store(name)\ +static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) + +#define LPFC_VPORT_ATTR_HEX_R(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_vport_param_hex_show(name)\ +lpfc_vport_param_init(name, defval, minval, maxval)\ +static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) + +#define LPFC_VPORT_ATTR_HEX_RW(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_vport_param_hex_show(name)\ +lpfc_vport_param_init(name, defval, minval, maxval)\ +lpfc_vport_param_set(name, defval, minval, maxval)\ +lpfc_vport_param_store(name)\ +static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) + static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL); static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); @@ -1019,53 +1134,48 @@ lpfc_nodev_tmo_show(struct class_device *cdev, char *buf) { struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; int val = 0; - val = phba->cfg_devloss_tmo; - return snprintf(buf, PAGE_SIZE, "%d\n", - phba->cfg_devloss_tmo); + val = vport->cfg_devloss_tmo; + return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); } static int -lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val) -{ - static int warned; - if (phba->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) { - phba->cfg_nodev_tmo = phba->cfg_devloss_tmo; - if (!warned && val != LPFC_DEF_DEVLOSS_TMO) { - warned = 1; - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0402 Ignoring nodev_tmo module " - "parameter because devloss_tmo is" +lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) +{ + if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) { + vport->cfg_nodev_tmo = vport->cfg_devloss_tmo; + if (val != LPFC_DEF_DEVLOSS_TMO) + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d (%d):0402 Ignoring nodev_tmo module" + " parameter because devloss_tmo is" " set.\n", - phba->brd_no); - } + vport->phba->brd_no, vport->vpi); return 0; } if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { - phba->cfg_nodev_tmo = val; - phba->cfg_devloss_tmo = val; + vport->cfg_nodev_tmo = val; + vport->cfg_devloss_tmo = val; return 0; } - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0400 lpfc_nodev_tmo attribute cannot be set to %d, " - "allowed range is [%d, %d]\n", - phba->brd_no, val, + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d (%d):0400 lpfc_nodev_tmo attribute cannot be set to" + " %d, allowed range is [%d, %d]\n", + vport->phba->brd_no, vport->vpi, val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); - phba->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO; + vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO; return -EINVAL; } static void -lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) +lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport) { struct lpfc_vport **vports; struct Scsi_Host *shost; struct lpfc_nodelist *ndlp; int i; - vports = lpfc_create_vport_work_array(phba); + vports = lpfc_create_vport_work_array(vport->phba); if (vports != NULL) for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { shost = lpfc_shost_from_vport(vports[i]); @@ -1074,40 +1184,38 @@ lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) nlp_listp) if (ndlp->rport) ndlp->rport->dev_loss_tmo = - phba->cfg_devloss_tmo; + vport->cfg_devloss_tmo; spin_unlock_irq(shost->host_lock); } lpfc_destroy_vport_work_array(vports); } static int -lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) +lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val) { - if (phba->dev_loss_tmo_changed || - (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0401 Ignoring change to nodev_tmo " + if (vport->dev_loss_tmo_changed || + (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) { + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d (%d):0401 Ignoring change to nodev_tmo " "because devloss_tmo is set.\n", - phba->brd_no); + vport->phba->brd_no, vport->vpi); return 0; } - if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { - phba->cfg_nodev_tmo = val; - phba->cfg_devloss_tmo = val; - lpfc_update_rport_devloss_tmo(phba); + vport->cfg_nodev_tmo = val; + vport->cfg_devloss_tmo = val; + lpfc_update_rport_devloss_tmo(vport); return 0; } - - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0403 lpfc_nodev_tmo attribute cannot be set to %d, " - "allowed range is [%d, %d]\n", - phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO, - LPFC_MAX_DEVLOSS_TMO); + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d (%d):0403 lpfc_nodev_tmo attribute cannot be set to" + "%d, allowed range is [%d, %d]\n", + vport->phba->brd_no, vport->vpi, val, + LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); return -EINVAL; } -lpfc_param_store(nodev_tmo) +lpfc_vport_param_store(nodev_tmo) static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR, lpfc_nodev_tmo_show, lpfc_nodev_tmo_store); @@ -1121,29 +1229,29 @@ module_param(lpfc_devloss_tmo, int, 0); MODULE_PARM_DESC(lpfc_devloss_tmo, "Seconds driver will hold I/O waiting " "for a device to come back"); -lpfc_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO, - LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO) -lpfc_param_show(devloss_tmo) +lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO, + LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO) +lpfc_vport_param_show(devloss_tmo) static int -lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val) +lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val) { if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { - phba->cfg_nodev_tmo = val; - phba->cfg_devloss_tmo = val; - phba->dev_loss_tmo_changed = 1; - lpfc_update_rport_devloss_tmo(phba); + vport->cfg_nodev_tmo = val; + vport->cfg_devloss_tmo = val; + vport->dev_loss_tmo_changed = 1; + lpfc_update_rport_devloss_tmo(vport); return 0; } - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, "%d:0404 lpfc_devloss_tmo attribute cannot be set to" " %d, allowed range is [%d, %d]\n", - phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO, + vport->phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); return -EINVAL; } -lpfc_param_store(devloss_tmo) +lpfc_vport_param_store(devloss_tmo) static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, lpfc_devloss_tmo_show, lpfc_devloss_tmo_store); @@ -1171,8 +1279,8 @@ LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); # lun_queue_depth: This parameter is used to limit the number of outstanding # commands per FCP LUN. Value range is [1,128]. Default value is 30. */ -LPFC_ATTR_R(lun_queue_depth, 30, 1, 128, - "Max number of FCP commands we can queue to a specific LUN"); +LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 128, + "Max number of FCP commands we can queue to a specific LUN"); /* # hba_queue_depth: This parameter is used to limit the number of outstanding @@ -1193,12 +1301,12 @@ LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192, # are allowed to login to each other. # Default value of this parameter is 0. */ -LPFC_ATTR_R(peer_port_login, 0, 0, 1, - "Allow peer ports on the same physical port to login to each " - "other."); +LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1, + "Allow peer ports on the same physical port to login to each " + "other."); /* -# vport_restrict_login: This parameter allows/prevents logins +# restrict_login: This parameter allows/prevents logins # between Virtual Ports and remote initiators. # When this parameter is not set (0) Virtual Ports will accept PLOGIs from # other initiators and will attempt to PLOGI all remote ports. @@ -1208,8 +1316,56 @@ LPFC_ATTR_R(peer_port_login, 0, 0, 1, # This parameter does not restrict logins to Fabric resident remote ports. # Default value of this parameter is 1. */ -LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1, - "Restrict virtual ports login to remote initiators."); +static int lpfc_restrict_login = 1; +module_param(lpfc_restrict_login, int, 0); +MODULE_PARM_DESC(lpfc_restrict_login, + "Restrict virtual ports login to remote initiators."); +lpfc_vport_param_show(restrict_login); + +static int +lpfc_restrict_login_init(struct lpfc_vport *vport, int val) +{ + if (val < 0 || val > 1) { + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d:0449 lpfc_restrict_login attribute cannot " + "be set to %d, allowed range is [0, 1]\n", + vport->phba->brd_no, val); + vport->cfg_restrict_login = 1; + return -EINVAL; + } + if (vport->port_type == LPFC_PHYSICAL_PORT) { + vport->cfg_restrict_login = 0; + return 0; + } + vport->cfg_restrict_login = val; + return 0; +} + +static int +lpfc_restrict_login_set(struct lpfc_vport *vport, int val) +{ + if (val < 0 || val > 1) { + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d:0450 lpfc_restrict_login attribute cannot " + "be set to %d, allowed range is [0, 1]\n", + vport->phba->brd_no, val); + vport->cfg_restrict_login = 1; + return -EINVAL; + } + if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) { + lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, + "%d:0468 lpfc_restrict_login must be 0 for " + "Physical ports.\n", + vport->phba->brd_no); + vport->cfg_restrict_login = 0; + return 0; + } + vport->cfg_restrict_login = val; + return 0; +} +lpfc_vport_param_store(restrict_login); +static CLASS_DEVICE_ATTR(lpfc_restrict_login, S_IRUGO | S_IWUSR, + lpfc_restrict_login_show, lpfc_restrict_login_store); /* # Some disk devices have a "select ID" or "select Target" capability. @@ -1228,8 +1384,8 @@ LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1, # and will not work across a fabric. Also this parameter will take # effect only in the case when ALPA map is not available.) */ -LPFC_ATTR_R(scan_down, 1, 0, 1, - "Start scanning for devices from highest ALPA to lowest"); +LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1, + "Start scanning for devices from highest ALPA to lowest"); /* # lpfc_topology: link topology for init link @@ -1260,15 +1416,15 @@ LPFC_ATTR_R(link_speed, 0, 0, 8, "Select link speed"); # lpfc_fcp_class: Determines FC class to use for the FCP protocol. # Value range is [2,3]. Default value is 3. */ -LPFC_ATTR_R(fcp_class, 3, 2, 3, - "Select Fibre Channel class of service for FCP sequences"); +LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3, + "Select Fibre Channel class of service for FCP sequences"); /* # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range # is [0,1]. Default value is 0. */ -LPFC_ATTR_RW(use_adisc, 0, 0, 1, - "Use ADISC on rediscovery to authenticate FCP devices"); +LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1, + "Use ADISC on rediscovery to authenticate FCP devices"); /* # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value @@ -1320,13 +1476,13 @@ LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1, # 2 = support FDMI with attribute of hostname # Value range [0,2]. Default value is 0. */ -LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support"); +LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support"); /* # Specifies the maximum number of ELS cmds we can have outstanding (for # discovery). Value range is [1,64]. Default value = 32. */ -LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " +LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " "during discovery"); /* @@ -1334,8 +1490,7 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " # Value range is [0,65535]. Default value is 255. # NOTE: The SCSI layer might probe all allowed LUN on some old targets. */ -LPFC_ATTR_R(max_luns, 255, 0, 65535, - "Maximum allowed LUN"); +LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN"); /* # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. @@ -1372,7 +1527,6 @@ struct class_device_attribute *lpfc_hba_attrs[] = { &class_device_attr_lpfc_lun_queue_depth, &class_device_attr_lpfc_hba_queue_depth, &class_device_attr_lpfc_peer_port_login, - &class_device_attr_lpfc_vport_restrict_login, &class_device_attr_lpfc_nodev_tmo, &class_device_attr_lpfc_devloss_tmo, &class_device_attr_lpfc_fcp_class, @@ -1409,6 +1563,29 @@ struct class_device_attribute *lpfc_hba_attrs[] = { NULL, }; +struct class_device_attribute *lpfc_vport_attrs[] = { + &class_device_attr_info, + &class_device_attr_state, + &class_device_attr_num_discovered_ports, + &class_device_attr_lpfc_drvr_version, + + &class_device_attr_lpfc_log_verbose, + &class_device_attr_lpfc_lun_queue_depth, + &class_device_attr_lpfc_nodev_tmo, + &class_device_attr_lpfc_devloss_tmo, + &class_device_attr_lpfc_hba_queue_depth, + &class_device_attr_lpfc_peer_port_login, + &class_device_attr_lpfc_restrict_login, + &class_device_attr_lpfc_fcp_class, + &class_device_attr_lpfc_use_adisc, + &class_device_attr_lpfc_fdmi_on, + &class_device_attr_lpfc_max_luns, + &class_device_attr_nport_evt_cnt, + &class_device_attr_management_version, + &class_device_attr_npiv_info, + NULL, +}; + static ssize_t sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -2264,33 +2441,20 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl); lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type); - lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); - lpfc_fcp_class_init(phba, lpfc_fcp_class); - lpfc_use_adisc_init(phba, lpfc_use_adisc); lpfc_ack0_init(phba, lpfc_ack0); lpfc_topology_init(phba, lpfc_topology); - lpfc_scan_down_init(phba, lpfc_scan_down); lpfc_link_speed_init(phba, lpfc_link_speed); - lpfc_fdmi_on_init(phba, lpfc_fdmi_on); - lpfc_discovery_threads_init(phba, lpfc_discovery_threads); - lpfc_max_luns_init(phba, lpfc_max_luns); lpfc_poll_tmo_init(phba, lpfc_poll_tmo); - lpfc_peer_port_login_init(phba, lpfc_peer_port_login); lpfc_npiv_enable_init(phba, lpfc_npiv_enable); - lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login); lpfc_use_msi_init(phba, lpfc_use_msi); - lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); - lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); phba->cfg_poll = lpfc_poll; phba->cfg_soft_wwnn = 0L; phba->cfg_soft_wwpn = 0L; - /* * The total number of segments is the configuration value plus 2 * since the IOCB need a command and response bde. */ phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2; - /* * Since the sg_tablesize is module parameter, the sg_dma_buf_size * used to create the sg_dma_buf_pool must be dynamically calculated @@ -2298,9 +2462,23 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) + (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64)); - - lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); + return; +} +void +lpfc_get_vport_cfgparam(struct lpfc_vport *vport) +{ + lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth); + lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo); + lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo); + lpfc_peer_port_login_init(vport, lpfc_peer_port_login); + lpfc_restrict_login_init(vport, lpfc_restrict_login); + lpfc_fcp_class_init(vport, lpfc_fcp_class); + lpfc_use_adisc_init(vport, lpfc_use_adisc); + lpfc_fdmi_on_init(vport, lpfc_fdmi_on); + lpfc_discovery_threads_init(vport, lpfc_discovery_threads); + lpfc_max_luns_init(vport, lpfc_max_luns); + lpfc_scan_down_init(vport, lpfc_scan_down); return; } diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 6689d6f85adc..ef86345ced6e 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -250,10 +250,13 @@ const char* lpfc_info(struct Scsi_Host *); int lpfc_scan_finished(struct Scsi_Host *, unsigned long); void lpfc_get_cfgparam(struct lpfc_hba *); +void lpfc_get_vport_cfgparam(struct lpfc_vport *); int lpfc_alloc_sysfs_attr(struct lpfc_vport *); void lpfc_free_sysfs_attr(struct lpfc_vport *); extern struct class_device_attribute *lpfc_hba_attrs[]; +extern struct class_device_attribute *lpfc_vport_attrs[]; extern struct scsi_host_template lpfc_template; +extern struct scsi_host_template lpfc_vport_template; extern struct fc_function_template lpfc_transport_functions; extern struct fc_function_template lpfc_vport_transport_functions; extern int lpfc_sli_mode; @@ -262,7 +265,7 @@ int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); void lpfc_terminate_rport_io(struct fc_rport *); void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); -struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct fc_vport *); +struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *); int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable); void lpfc_mbx_unreg_vpi(struct lpfc_vport *); void destroy_port(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 43e2e33f9a07..8b7e90eac5c3 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -451,10 +451,10 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) */ if ((Did != vport->fc_myDID) && ((lpfc_find_vport_by_did(phba, Did) == NULL) || - phba->cfg_peer_port_login)) { + vport->cfg_peer_port_login)) { if ((vport->port_type != LPFC_NPIV_PORT) || (vport->fc_flag & FC_RFF_NOT_SUPPORTED) || - (!phba->cfg_vport_restrict_login)) { + (!vport->cfg_restrict_login)) { ndlp = lpfc_setup_disc_node(vport, Did); if (ndlp) { lpfc_debugfs_disc_trc(vport, @@ -1471,7 +1471,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) pab->ab.EntryCnt++; size += FOURBYTES + len; - if (phba->cfg_fdmi_on == 2) { + if (vport->cfg_fdmi_on == 2) { /* #6 Port attribute entry */ ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b8e048a467d2..4aed0cffe92f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -518,7 +518,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * alpa map would take too long otherwise. */ if (phba->alpa_map[0] == 0) { - phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; + vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; } /* FLOGI failure */ @@ -2640,7 +2640,7 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) sentadisc++; vport->num_disc_nodes++; if (vport->num_disc_nodes >= - vport->phba->cfg_discovery_threads) { + vport->cfg_discovery_threads) { spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_NLP_MORE; spin_unlock_irq(shost->host_lock); @@ -2675,7 +2675,7 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport) sentplogi++; vport->num_disc_nodes++; if (vport->num_disc_nodes >= - vport->phba->cfg_discovery_threads) { + vport->cfg_discovery_threads) { spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_NLP_MORE; spin_unlock_irq(shost->host_lock); @@ -2841,7 +2841,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, * just ACC and ignore it. */ if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && - !(phba->cfg_peer_port_login)) { + !(vport->cfg_peer_port_login)) { i = payload_len; datap = lp; while (i > 0) { @@ -4170,7 +4170,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } - if (phba->cfg_fdmi_on) { + if (vport->cfg_fdmi_on) { ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); if (ndlp_fdmi) { diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 556d55fc9456..914e74ac11e5 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -2200,7 +2200,7 @@ lpfc_disc_list_loopmap(struct lpfc_vport *vport) /* If cfg_scan_down is set, start from highest * ALPA (0xef) to lowest (0x1). */ - if (phba->cfg_scan_down) + if (vport->cfg_scan_down) index = j; else index = FC_MAXLOOP - j - 1; @@ -2749,7 +2749,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) * fdmi-on=2 (supporting RPA/hostnmae) */ - if (phba->cfg_fdmi_on == 1) + if (vport->cfg_fdmi_on == 1) lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); else mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 484070c82974..83855a5a1826 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1524,13 +1524,18 @@ lpfc_scsi_free(struct lpfc_hba *phba) } struct lpfc_vport * -lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) +lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) { struct lpfc_vport *vport; struct Scsi_Host *shost; int error = 0; - shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport)); + if (dev != &phba->pcidev->dev) + shost = scsi_host_alloc(&lpfc_vport_template, + sizeof(struct lpfc_vport)); + else + shost = scsi_host_alloc(&lpfc_template, + sizeof(struct lpfc_vport)); if (!shost) goto out; @@ -1540,9 +1545,10 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) vport->load_flag |= FC_LOADING; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + lpfc_get_vport_cfgparam(vport); shost->unique_id = instance; shost->max_id = LPFC_MAX_TARGET; - shost->max_lun = phba->cfg_max_luns; + shost->max_lun = vport->cfg_max_luns; shost->this_id = -1; shost->max_cmd_len = 16; /* @@ -1551,7 +1557,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) * max xri value determined in hba setup. */ shost->can_queue = phba->cfg_hba_queue_depth - 10; - if (fc_vport != NULL) { + if (dev != &phba->pcidev->dev) { shost->transportt = lpfc_vport_transport_template; vport->port_type = LPFC_NPIV_PORT; } else { @@ -1575,11 +1581,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.data = (unsigned long)vport; - if (fc_vport != NULL) { - error = scsi_add_host(shost, &fc_vport->dev); - } else { - error = scsi_add_host(shost, &phba->pcidev->dev); - } + error = scsi_add_host(shost, dev); if (error) goto out_put_shost; @@ -1895,7 +1897,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) /* Initialize list of fabric iocbs */ INIT_LIST_HEAD(&phba->fabric_iocb_list); - vport = lpfc_create_port(phba, phba->brd_no, NULL); + vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); if (!vport) goto out_kthread_stop; diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index bca2f5c9b4ba..9c159a8e6e8c 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -304,7 +304,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, ndlp->nlp_rpi); - if (phba->cfg_fcp_class == 2 && sp->cls2.classValid) + if (vport->cfg_fcp_class == 2 && sp->cls2.classValid) ndlp->nlp_fcp_info |= CLASS2; else ndlp->nlp_fcp_info |= CLASS3; @@ -392,7 +392,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } if ((vport->port_type == LPFC_NPIV_PORT && - phba->cfg_vport_restrict_login)) { + vport->cfg_restrict_login)) { /* In order to preserve RPIs, we want to cleanup * the default RPI the firmware created to rcv @@ -564,10 +564,9 @@ static uint32_t lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_hba *phba = vport->phba; /* Check config parameter use-adisc or FCP-2 */ - if ((phba->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || + if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_NPR_ADISC; @@ -787,7 +786,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, ndlp->nlp_rpi); - if (phba->cfg_fcp_class == 2 && (sp->cls2.classValid)) + if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid)) ndlp->nlp_fcp_info |= CLASS2; else ndlp->nlp_fcp_info |= CLASS3; @@ -1358,7 +1357,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, irsp = &rspiocb->iocb; if (irsp->ulpStatus) { if ((vport->port_type == LPFC_NPIV_PORT) && - phba->cfg_vport_restrict_login) { + vport->cfg_restrict_login) { goto out; } ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; @@ -1380,7 +1379,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } if (!(ndlp->nlp_type & NLP_FCP_TARGET) && (vport->port_type == LPFC_NPIV_PORT) && - phba->cfg_vport_restrict_login) { + vport->cfg_restrict_login) { out: spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_TARGET_REMOVE; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 0284ded96bad..78666c62330e 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -84,22 +84,21 @@ lpfc_adjust_queue_depth(struct lpfc_hba *phba) * SCSI command completion. */ static inline void -lpfc_rampup_queue_depth(struct lpfc_hba *phba, +lpfc_rampup_queue_depth(struct lpfc_vport *vport, struct scsi_device *sdev) { unsigned long flags; + struct lpfc_hba *phba = vport->phba; atomic_inc(&phba->num_cmd_success); - if (phba->cfg_lun_queue_depth <= sdev->queue_depth) + if (vport->cfg_lun_queue_depth <= sdev->queue_depth) return; - spin_lock_irqsave(&phba->hbalock, flags); if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) || ((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) { spin_unlock_irqrestore(&phba->hbalock, flags); return; } - phba->last_ramp_up_time = jiffies; spin_unlock_irqrestore(&phba->hbalock, flags); @@ -627,16 +626,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, if (!result) - lpfc_rampup_queue_depth(phba, sdev); + lpfc_rampup_queue_depth(vport, sdev); if (!result && pnode != NULL && ((jiffies - pnode->last_ramp_up_time) > LPFC_Q_RAMP_UP_INTERVAL * HZ) && ((jiffies - pnode->last_q_full_time) > LPFC_Q_RAMP_UP_INTERVAL * HZ) && - (phba->cfg_lun_queue_depth > sdev->queue_depth)) { + (vport->cfg_lun_queue_depth > sdev->queue_depth)) { shost_for_each_device(tmp_sdev, sdev->host) { - if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) { + if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){ if (tmp_sdev->id != sdev->id) continue; if (tmp_sdev->ordered_tags) @@ -1099,7 +1098,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); if (++loop_count - > (2 * phba->cfg_devloss_tmo)/LPFC_ABORT_WAIT) + > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT) break; } @@ -1154,7 +1153,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) loopcnt++; rdata = cmnd->device->hostdata; if (!rdata || - (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) { + (loopcnt > ((vport->cfg_devloss_tmo * 2) + 1))){ lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d (%d):0721 LUN Reset rport " "failure: cnt x%x rdata x%p\n", @@ -1230,7 +1229,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); if (++loopcnt - > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) + > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT) break; cnt = lpfc_sli_sum_iocb(phba, @@ -1339,7 +1338,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); if (++loopcnt - > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) + > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT) break; cnt = lpfc_sli_sum_iocb(phba, @@ -1386,7 +1385,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) * extra. This list of scsi bufs exists for the lifetime of the driver. */ total = phba->total_scsi_bufs; - num_to_alloc = phba->cfg_lun_queue_depth + 2; + num_to_alloc = vport->cfg_lun_queue_depth + 2; /* Allow some exchanges to be available always to complete discovery */ if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) { @@ -1435,9 +1434,9 @@ lpfc_slave_configure(struct scsi_device *sdev) struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) - scsi_activate_tcq(sdev, phba->cfg_lun_queue_depth); + scsi_activate_tcq(sdev, vport->cfg_lun_queue_depth); else - scsi_deactivate_tcq(sdev, phba->cfg_lun_queue_depth); + scsi_deactivate_tcq(sdev, vport->cfg_lun_queue_depth); /* * Initialize the fc transport attributes for the target @@ -1445,7 +1444,7 @@ lpfc_slave_configure(struct scsi_device *sdev) * target pointer is stored in the starget_data for the * driver's sysfs entry point functions. */ - rport->dev_loss_tmo = phba->cfg_devloss_tmo; + rport->dev_loss_tmo = vport->cfg_devloss_tmo; if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { lpfc_sli_poll_fcp_ring(phba); @@ -1483,3 +1482,23 @@ struct scsi_host_template lpfc_template = { .shost_attrs = lpfc_hba_attrs, .max_sectors = 0xFFFF, }; + +struct scsi_host_template lpfc_vport_template = { + .module = THIS_MODULE, + .name = LPFC_DRIVER_NAME, + .info = lpfc_info, + .queuecommand = lpfc_queuecommand, + .eh_abort_handler = lpfc_abort_handler, + .eh_device_reset_handler= lpfc_device_reset_handler, + .eh_bus_reset_handler = lpfc_bus_reset_handler, + .slave_alloc = lpfc_slave_alloc, + .slave_configure = lpfc_slave_configure, + .slave_destroy = lpfc_slave_destroy, + .scan_finished = lpfc_scan_finished, + .this_id = -1, + .sg_tablesize = LPFC_SG_SEG_CNT, + .cmd_per_lun = LPFC_CMD_PER_LUN, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = lpfc_vport_attrs, + .max_sectors = 0xFFFF, +}; diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index e066855b0783..70e1bc34fd48 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -198,8 +198,8 @@ int lpfc_vport_create(struct fc_vport *fc_vport, bool disable) { struct lpfc_nodelist *ndlp; - struct lpfc_vport *pport = - (struct lpfc_vport *) fc_vport->shost->hostdata; + struct Scsi_Host *shost = fc_vport->shost; + struct lpfc_vport *pport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = pport->phba; struct lpfc_vport *vport = NULL; int instance; @@ -237,7 +237,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) goto error_out; } - vport = lpfc_create_port(phba, instance, fc_vport); + vport = lpfc_create_port(phba, instance, &fc_vport->dev); if (!vport) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, "%d:1811 Create VPORT failed: vpi x%x\n", -- cgit v1.2.3 From e8b62011d88d6fdba585fb2bb77c9274a63cadab Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:10:09 -0400 Subject: [SCSI] lpfc 8.2.2 : Rework the lpfc_printf_log() macro Rework the lpfc_printf_log() macro so that logging is enabled on a per-vport basis. Used to be on a physical-port basis, thus logging with large numbers of vports became a mess. Required redefinition of the macro, and an update of every use. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 3 +- drivers/scsi/lpfc/lpfc_attr.c | 110 ++++---- drivers/scsi/lpfc/lpfc_ct.c | 190 ++++++------- drivers/scsi/lpfc/lpfc_debugfs.c | 62 ++--- drivers/scsi/lpfc/lpfc_els.c | 533 +++++++++++++++---------------------- drivers/scsi/lpfc/lpfc_hbadisc.c | 310 ++++++++++----------- drivers/scsi/lpfc/lpfc_init.c | 74 ++--- drivers/scsi/lpfc/lpfc_logmsg.h | 10 +- drivers/scsi/lpfc/lpfc_mbox.c | 12 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 118 ++++---- drivers/scsi/lpfc/lpfc_scsi.c | 246 ++++++++--------- drivers/scsi/lpfc/lpfc_sli.c | 248 +++++++---------- drivers/scsi/lpfc/lpfc_vport.c | 73 +++-- 13 files changed, 852 insertions(+), 1137 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index fb56ff9d5da2..5a76d2b4253b 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -349,6 +349,7 @@ struct lpfc_vport { uint32_t cfg_use_adisc; uint32_t cfg_fdmi_on; uint32_t cfg_discovery_threads; + uint32_t cfg_log_verbose; uint32_t cfg_max_luns; uint32_t dev_loss_tmo_changed; @@ -446,8 +447,6 @@ struct lpfc_hba { uint64_t cfg_soft_wwpn; uint32_t cfg_hba_queue_depth; - /* Config paramters that should be in the vport */ - uint32_t cfg_log_verbose; lpfc_vpd_t vpd; /* vital product data */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 61d251b1b03b..c1cedc3d1b70 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -319,9 +319,8 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) if (cnt++ > 3000) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, - "%d:0466 Outstanding IO when " - "bringing Adapter offline\n", - phba->brd_no); + "0466 Outstanding IO when " + "bringing Adapter offline\n"); break; } } @@ -694,9 +693,8 @@ lpfc_##attr##_init(struct lpfc_hba *phba, int val) \ return 0;\ }\ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \ - "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\ - "allowed range is ["#minval", "#maxval"]\n", \ - phba->brd_no, val); \ + "0449 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", val); \ phba->cfg_##attr = default;\ return -EINVAL;\ } @@ -710,9 +708,8 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ return 0;\ }\ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \ - "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\ - "allowed range is ["#minval", "#maxval"]\n", \ - phba->brd_no, val); \ + "0450 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", val); \ return -EINVAL;\ } @@ -764,10 +761,9 @@ lpfc_##attr##_init(struct lpfc_vport *vport, int val) \ vport->cfg_##attr = val;\ return 0;\ }\ - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, \ - "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\ - "allowed range is ["#minval", "#maxval"]\n", \ - vport->phba->brd_no, val); \ + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ + "0449 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", val); \ vport->cfg_##attr = default;\ return -EINVAL;\ } @@ -780,10 +776,9 @@ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \ vport->cfg_##attr = val;\ return 0;\ }\ - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, \ - "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\ - "allowed range is ["#minval", "#maxval"]\n", \ - vport->phba->brd_no, val); \ + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ + "0450 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", val); \ return -EINVAL;\ } @@ -1023,17 +1018,15 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (stat1) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0463 lpfc_soft_wwpn attribute set failed to reinit " - "adapter - %d\n", phba->brd_no, stat1); - + "0463 lpfc_soft_wwpn attribute set failed to " + "reinit adapter - %d\n", stat1); init_completion(&online_compl); lpfc_workq_post_event(phba, &stat2, &online_compl, LPFC_EVT_ONLINE); wait_for_completion(&online_compl); if (stat2) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0464 lpfc_soft_wwpn attribute set failed to reinit " - "adapter - %d\n", phba->brd_no, stat2); - + "0464 lpfc_soft_wwpn attribute set failed to " + "reinit adapter - %d\n", stat2); return (stat1 || stat2) ? -EIO : count; } static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ @@ -1145,11 +1138,10 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) { vport->cfg_nodev_tmo = vport->cfg_devloss_tmo; if (val != LPFC_DEF_DEVLOSS_TMO) - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d (%d):0402 Ignoring nodev_tmo module" - " parameter because devloss_tmo is" - " set.\n", - vport->phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0402 Ignoring nodev_tmo module " + "parameter because devloss_tmo is " + "set.\n"); return 0; } @@ -1158,11 +1150,10 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) vport->cfg_devloss_tmo = val; return 0; } - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d (%d):0400 lpfc_nodev_tmo attribute cannot be set to" - " %d, allowed range is [%d, %d]\n", - vport->phba->brd_no, vport->vpi, val, - LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0400 lpfc_nodev_tmo attribute cannot be set to" + " %d, allowed range is [%d, %d]\n", + val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO; return -EINVAL; } @@ -1195,10 +1186,9 @@ lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val) { if (vport->dev_loss_tmo_changed || (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) { - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d (%d):0401 Ignoring change to nodev_tmo " - "because devloss_tmo is set.\n", - vport->phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0401 Ignoring change to nodev_tmo " + "because devloss_tmo is set.\n"); return 0; } if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { @@ -1207,11 +1197,10 @@ lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val) lpfc_update_rport_devloss_tmo(vport); return 0; } - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d (%d):0403 lpfc_nodev_tmo attribute cannot be set to" - "%d, allowed range is [%d, %d]\n", - vport->phba->brd_no, vport->vpi, val, - LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0403 lpfc_nodev_tmo attribute cannot be set to" + "%d, allowed range is [%d, %d]\n", + val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); return -EINVAL; } @@ -1243,11 +1232,10 @@ lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val) return 0; } - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d:0404 lpfc_devloss_tmo attribute cannot be set to" - " %d, allowed range is [%d, %d]\n", - vport->phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO, - LPFC_MAX_DEVLOSS_TMO); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0404 lpfc_devloss_tmo attribute cannot be set to" + " %d, allowed range is [%d, %d]\n", + val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); return -EINVAL; } @@ -1273,7 +1261,8 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, # LOG_LIBDFC 0x2000 LIBDFC events # LOG_ALL_MSG 0xffff LOG all messages */ -LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); +LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, + "Verbose logging bit-mask"); /* # lun_queue_depth: This parameter is used to limit the number of outstanding @@ -1326,10 +1315,10 @@ static int lpfc_restrict_login_init(struct lpfc_vport *vport, int val) { if (val < 0 || val > 1) { - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d:0449 lpfc_restrict_login attribute cannot " - "be set to %d, allowed range is [0, 1]\n", - vport->phba->brd_no, val); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0449 lpfc_restrict_login attribute cannot " + "be set to %d, allowed range is [0, 1]\n", + val); vport->cfg_restrict_login = 1; return -EINVAL; } @@ -1345,18 +1334,17 @@ static int lpfc_restrict_login_set(struct lpfc_vport *vport, int val) { if (val < 0 || val > 1) { - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d:0450 lpfc_restrict_login attribute cannot " - "be set to %d, allowed range is [0, 1]\n", - vport->phba->brd_no, val); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0450 lpfc_restrict_login attribute cannot " + "be set to %d, allowed range is [0, 1]\n", + val); vport->cfg_restrict_login = 1; return -EINVAL; } if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) { - lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, - "%d:0468 lpfc_restrict_login must be 0 for " - "Physical ports.\n", - vport->phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0468 lpfc_restrict_login must be 0 for " + "Physical ports.\n"); vport->cfg_restrict_login = 0; return 0; } @@ -2435,7 +2423,6 @@ struct fc_function_template lpfc_vport_transport_functions = { void lpfc_get_cfgparam(struct lpfc_hba *phba) { - lpfc_log_verbose_init(phba, lpfc_log_verbose); lpfc_cr_delay_init(phba, lpfc_cr_delay); lpfc_cr_count_init(phba, lpfc_cr_count); lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); @@ -2469,6 +2456,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) void lpfc_get_vport_cfgparam(struct lpfc_vport *vport) { + lpfc_log_verbose_init(vport, lpfc_log_verbose); lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth); lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo); lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 8b7e90eac5c3..ad7f33a31567 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -341,11 +341,11 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, } /* Issue GEN REQ IOCB for NPORT */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0119 Issue GEN REQ IOCB to NPORT x%x " - "Data: x%x x%x\n", phba->brd_no, vport->vpi, - ndlp->nlp_DID, icmd->ulpIoTag, - vport->port_state); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0119 Issue GEN REQ IOCB to NPORT x%x " + "Data: x%x x%x\n", + ndlp->nlp_DID, icmd->ulpIoTag, + vport->port_state); geniocb->iocb_cmpl = cmpl; geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; geniocb->vport = vport; @@ -464,14 +464,13 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) Did, ndlp->nlp_flag, vport->fc_flag); - lpfc_printf_log(phba, KERN_INFO, + lpfc_printf_vlog(vport, + KERN_INFO, LOG_DISCOVERY, - "%d (%d):0238 Process " + "0238 Process " "x%x NameServer Rsp" "Data: x%x x%x x%x\n", - phba->brd_no, - vport->vpi, Did, - ndlp->nlp_flag, + Did, ndlp->nlp_flag, vport->fc_flag, vport->fc_rscn_id_cnt); } else { @@ -482,14 +481,13 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) Did, vport->fc_flag, vport->fc_rscn_id_cnt); - lpfc_printf_log(phba, KERN_INFO, + lpfc_printf_vlog(vport, + KERN_INFO, LOG_DISCOVERY, - "%d (%d):0239 Skip x%x " + "0239 Skip x%x " "NameServer Rsp Data: " "x%x x%x\n", - phba->brd_no, - vport->vpi, Did, - vport->fc_flag, + Did, vport->fc_flag, vport->fc_rscn_id_cnt); } @@ -516,14 +514,13 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) Did, vport->fc_flag, vport->fc_rscn_id_cnt); - lpfc_printf_log(phba, KERN_INFO, + lpfc_printf_vlog(vport, + KERN_INFO, LOG_DISCOVERY, - "%d (%d):0245 Skip x%x " + "0245 Skip x%x " "NameServer Rsp Data: " "x%x x%x\n", - phba->brd_no, - vport->vpi, Did, - vport->fc_flag, + Did, vport->fc_flag, vport->fc_rscn_id_cnt); } } @@ -570,9 +567,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0216 Link event during NS query\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0216 Link event during NS query\n"); lpfc_vport_set_state(vport, FC_VPORT_FAILED); goto out; } @@ -590,20 +586,17 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; } lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0257 GID_FT Query error: 0x%x 0x%x\n", - phba->brd_no, vport->vpi, irsp->ulpStatus, - vport->fc_ns_retry); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0257 GID_FT Query error: 0x%x 0x%x\n", + irsp->ulpStatus, vport->fc_ns_retry); } else { /* Good status, continue checking */ CTrsp = (struct lpfc_sli_ct_request *) outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0208 NameServer Rsp " - "Data: x%x\n", - phba->brd_no, vport->vpi, - vport->fc_flag); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0208 NameServer Rsp Data: x%x\n", + vport->fc_flag); lpfc_ns_rsp(vport, outp, (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); } else if (CTrsp->CommandResponse.bits.CmdRsp == @@ -611,10 +604,10 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* NameServer Rsp Error */ if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ) && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0269 No NameServer Entries " + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY, + "0269 No NameServer Entries " "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation, @@ -625,12 +618,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, (uint32_t)CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation); - } - else { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0240 NameServer Rsp Error " + } else { + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY, + "0240 NameServer Rsp Error " "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation, @@ -646,10 +638,9 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } else { /* NameServer Rsp Error */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0241 NameServer Rsp Error " + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0241 NameServer Rsp Error " "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation, @@ -717,40 +708,37 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { if ((fbits & FC4_FEATURE_INIT) && !(fbits & FC4_FEATURE_TARGET)) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0270 Skip x%x GFF " - "NameServer Rsp Data: (init) " - "x%x x%x\n", phba->brd_no, - vport->vpi, did, fbits, - vport->fc_rscn_id_cnt); + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY, + "0270 Skip x%x GFF " + "NameServer Rsp Data: (init) " + "x%x x%x\n", did, fbits, + vport->fc_rscn_id_cnt); goto out; } } } else { - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0267 NameServer GFF Rsp" - " x%x Error (%d %d) Data: x%x x%x\n", - phba->brd_no, vport->vpi, did, - irsp->ulpStatus, irsp->un.ulpWord[4], - vport->fc_flag, vport->fc_rscn_id_cnt) + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0267 NameServer GFF Rsp " + "x%x Error (%d %d) Data: x%x x%x\n", + did, irsp->ulpStatus, irsp->un.ulpWord[4], + vport->fc_flag, vport->fc_rscn_id_cnt) } /* This is a target port, unregistered port, or the GFF_ID failed */ ndlp = lpfc_setup_disc_node(vport, did); if (ndlp) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0242 Process x%x GFF " - "NameServer Rsp Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, - did, ndlp->nlp_flag, vport->fc_flag, - vport->fc_rscn_id_cnt); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0242 Process x%x GFF " + "NameServer Rsp Data: x%x x%x x%x\n", + did, ndlp->nlp_flag, vport->fc_flag, + vport->fc_rscn_id_cnt); } else { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0243 Skip x%x GFF " - "NameServer Rsp Data: x%x x%x\n", - phba->brd_no, vport->vpi, did, - vport->fc_flag, vport->fc_rscn_id_cnt); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0243 Skip x%x GFF " + "NameServer Rsp Data: x%x x%x\n", did, + vport->fc_flag, vport->fc_rscn_id_cnt); } out: /* Link up / RSCN discovery */ @@ -806,22 +794,21 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, latt = lpfc_els_chk_latt(vport); /* RFT request completes status CmdRsp */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0209 RFT request completes, latt %d, " - "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", - phba->brd_no, vport->vpi, latt, irsp->ulpStatus, - CTrsp->CommandResponse.bits.CmdRsp, - cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0209 RFT request completes, latt %d, " + "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", + latt, irsp->ulpStatus, + CTrsp->CommandResponse.bits.CmdRsp, + cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, "CT cmd cmpl: status:x%x/x%x cmd:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode); if (irsp->ulpStatus) { - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0268 NS cmd %x Error (%d %d)\n", - phba->brd_no, vport->vpi, cmdcode, - irsp->ulpStatus, irsp->un.ulpWord[4]); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0268 NS cmd %x Error (%d %d)\n", + cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]); if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) || @@ -833,9 +820,8 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; retry++; - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0216 Retrying NS cmd %x\n", - phba->brd_no, vport->vpi, cmdcode); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0216 Retrying NS cmd %x\n", cmdcode); rc = lpfc_ns_cmd(vport, cmdcode, retry, 0); if (rc == 0) goto out; @@ -979,10 +965,9 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, } /* NameServer Req */ - lpfc_printf_log(phba, KERN_INFO ,LOG_DISCOVERY, - "%d (%d):0236 NameServer Req Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, cmdcode, vport->fc_flag, - vport->fc_rscn_id_cnt); + lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY, + "0236 NameServer Req Data: x%x x%x x%x\n", + cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt); bpl = (struct ulp_bde64 *) bmp->virt; memset(bpl, 0, sizeof(struct ulp_bde64)); @@ -1099,10 +1084,9 @@ ns_cmd_free_mpvirt: ns_cmd_free_mp: kfree(mp); ns_cmd_exit: - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0266 Issue NameServer Req x%x err %d Data: x%x x%x\n", - phba->brd_no, vport->vpi, cmdcode, rc, vport->fc_flag, - vport->fc_rscn_id_cnt); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0266 Issue NameServer Req x%x err %d Data: x%x x%x\n", + cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt); return 1; } @@ -1128,12 +1112,11 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4], latt); if (latt || irsp->ulpStatus) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0229 FDMI cmd %04x failed, latt = %d " - "ulpStatus: x%x, rid x%x\n", - phba->brd_no, vport->vpi, - be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, - irsp->un.ulpWord[4]); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0229 FDMI cmd %04x failed, latt = %d " + "ulpStatus: x%x, rid x%x\n", + be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, + irsp->un.ulpWord[4]); lpfc_ct_free_iocb(phba, cmdiocb); return; } @@ -1141,10 +1124,9 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp = lpfc_findnode_did(vport, FDMI_DID); if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0220 FDMI rsp failed Data: x%x\n", - phba->brd_no, vport->vpi, - be16_to_cpu(fdmi_cmd)); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0220 FDMI rsp failed Data: x%x\n", + be16_to_cpu(fdmi_cmd)); } switch (be16_to_cpu(fdmi_cmd)) { @@ -1207,11 +1189,9 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) INIT_LIST_HEAD(&bmp->list); /* FDMI request */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0218 FDMI Request Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->fc_flag, - vport->port_state, cmdcode); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0218 FDMI Request Data: x%x x%x x%x\n", + vport->fc_flag, vport->port_state, cmdcode); CtReq = (struct lpfc_sli_ct_request *) mp->virt; memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); @@ -1534,9 +1514,9 @@ fdmi_cmd_free_mp: kfree(mp); fdmi_cmd_exit: /* Issue FDMI request failed */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0244 Issue FDMI request failed Data: x%x\n", - phba->brd_no, vport->vpi, cmdcode); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0244 Issue FDMI request failed Data: x%x\n", + cmdcode); return 1; } diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 2310a2d1d8ce..dc7b858b95fa 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -642,13 +642,11 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); atomic_set(&lpfc_debugfs_hba_count, 0); if (!lpfc_debugfs_root) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs root (lpfc)", - phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs root\n"); goto debug_failed; } } - if (!lpfc_debugfs_start_time) lpfc_debugfs_start_time = jiffies; @@ -658,9 +656,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba->hba_debugfs_root = debugfs_create_dir(name, lpfc_debugfs_root); if (!phba->hba_debugfs_root) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs hba (lpfc%d)", - phba->brd_no, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs hba\n"); goto debug_failed; } atomic_inc(&lpfc_debugfs_hba_count); @@ -673,9 +670,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba->hba_debugfs_root, phba, &lpfc_debugfs_op_dumpslim); if (!phba->debug_dumpslim) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs dumpslim (lpfc%d)", - phba->brd_no, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs dumpslim\n"); goto debug_failed; } @@ -692,8 +688,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } lpfc_debugfs_max_slow_ring_trc = (1 << i); printk(KERN_ERR - "lpfc_debugfs_max_slow_ring_trc change to %d\n", - lpfc_debugfs_max_slow_ring_trc); + "lpfc_debugfs_max_disc_trc changed to " + "%d\n", lpfc_debugfs_max_disc_trc); } } @@ -704,10 +700,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba->hba_debugfs_root, phba, &lpfc_debugfs_op_slow_ring_trc); if (!phba->debug_slow_ring_trc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs " - "slow_ring_trace (lpfc%d)", - phba->brd_no, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs " + "slow_ring_trace\n"); goto debug_failed; } if (!phba->slow_ring_trc) { @@ -716,10 +711,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) lpfc_debugfs_max_slow_ring_trc), GFP_KERNEL); if (!phba->slow_ring_trc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs " - "slow_ring buffer (lpfc%d)", - phba->brd_no, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs " + "slow_ring buffer\n"); goto debug_failed; } atomic_set(&phba->slow_ring_trc_cnt, 0); @@ -734,9 +728,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport->vport_debugfs_root = debugfs_create_dir(name, phba->hba_debugfs_root); if (!vport->vport_debugfs_root) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cant create debugfs vport%d (lpfc%d)", - phba->brd_no, vport->vpi, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cant create debugfs"); goto debug_failed; } atomic_inc(&phba->debugfs_vport_count); @@ -754,8 +747,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } lpfc_debugfs_max_disc_trc = (1 << i); printk(KERN_ERR - "lpfc_debugfs_max_disc_trc changed to %d\n", - lpfc_debugfs_max_disc_trc); + "lpfc_debugfs_max_disc_trc changed to %d\n", + lpfc_debugfs_max_disc_trc); } } @@ -764,10 +757,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) GFP_KERNEL); if (!vport->disc_trc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs " - "vport%d disc trace buffer (lpfc%d)", - phba->brd_no, vport->vpi, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs disc trace " + "buffer\n"); goto debug_failed; } atomic_set(&vport->disc_trc_cnt, 0); @@ -780,10 +772,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport->vport_debugfs_root, vport, &lpfc_debugfs_op_disc_trc); if (!vport->debug_disc_trc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cannot create debugfs " - "vport%d discovery_trace (lpfc%d)", - phba->brd_no, vport->vpi, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs " + "discovery_trace\n"); goto debug_failed; } snprintf(name, sizeof(name), "nodelist"); @@ -792,9 +783,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport->vport_debugfs_root, vport, &lpfc_debugfs_op_nodelist); if (!vport->debug_nodelist) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0409 Cant create debugfs vport%d nodelist (lpfc%d)", - phba->brd_no, vport->vpi, phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cant create debugfs nodelist"); goto debug_failed; } debug_failed: diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4aed0cffe92f..9365e19696e2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -63,10 +63,10 @@ lpfc_els_chk_latt(struct lpfc_vport *vport) return 0; /* Pending Link Event during Discovery */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0237 Pending Link Event during " - "Discovery: State x%x\n", - phba->brd_no, vport->vpi, phba->pport->port_state); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0237 Pending Link Event during " + "Discovery: State x%x\n", + phba->pport->port_state); /* CLEAR_LA should re-enable link attention events and * we should then imediately take a LATT event. The @@ -208,23 +208,21 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, if (prsp) { list_add(&prsp->list, &pcmd->list); } - if (expectRsp) { /* Xmit ELS command to remote NPORT */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0116 Xmit ELS command x%x to remote " - "NPORT x%x I/O tag: x%x, port state: x%x\n", - phba->brd_no, vport->vpi, elscmd, did, - elsiocb->iotag, vport->port_state); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0116 Xmit ELS command x%x to remote " + "NPORT x%x I/O tag: x%x, port state: x%x\n", + elscmd, did, elsiocb->iotag, + vport->port_state); } else { /* Xmit ELS response to remote NPORT */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0117 Xmit ELS response x%x to remote " - "NPORT x%x I/O tag: x%x, size: x%x\n", - phba->brd_no, vport->vpi, elscmd, - ndlp->nlp_DID, elsiocb->iotag, cmdSize); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0117 Xmit ELS response x%x to remote " + "NPORT x%x I/O tag: x%x, size: x%x\n", + elscmd, ndlp->nlp_DID, elsiocb->iotag, + cmdSize); } - return elsiocb; } @@ -285,9 +283,8 @@ fail_free_mbox: fail: lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0249 Cannot issue Register Fabric login\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0249 Cannot issue Register Fabric login\n"); return -ENXIO; } @@ -340,20 +337,19 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { if (sp->cmn.response_multiple_NPort) { - lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_VPORT, - "%d:1816 FLOGI NPIV supported, " - "response data 0x%x\n", - phba->brd_no, - sp->cmn.response_multiple_NPort); + lpfc_printf_vlog(vport, KERN_WARNING, + LOG_ELS | LOG_VPORT, + "1816 FLOGI NPIV supported, " + "response data 0x%x\n", + sp->cmn.response_multiple_NPort); phba->link_flag |= LS_NPIV_FAB_SUPPORTED; - } else { /* Because we asked f/w for NPIV it still expects us - to call reg_vnpid atleast for the physcial host */ - lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_VPORT, - "%d:1817 Fabric does not support NPIV " - "- configuring single port mode.\n", - phba->brd_no); + to call reg_vnpid atleast for the physcial host */ + lpfc_printf_vlog(vport, KERN_WARNING, + LOG_ELS | LOG_VPORT, + "1817 Fabric does not support NPIV " + "- configuring single port mode.\n"); phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; } } @@ -522,12 +518,11 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } /* FLOGI failure */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0100 FLOGI failure Data: x%x x%x " - "x%x\n", - phba->brd_no, vport->vpi, - irsp->ulpStatus, irsp->un.ulpWord[4], - irsp->ulpTimeout); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0100 FLOGI failure Data: x%x x%x " + "x%x\n", + irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->ulpTimeout); goto flogifail; } @@ -540,12 +535,11 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, sp = prsp->virt + sizeof(uint32_t); /* FLOGI completes successfully */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0101 FLOGI completes sucessfully " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - irsp->un.ulpWord[4], sp->cmn.e_d_tov, - sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0101 FLOGI completes sucessfully " + "Data: x%x x%x x%x x%x\n", + irsp->un.ulpWord[4], sp->cmn.e_d_tov, + sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); if (vport->port_state == LPFC_FLOGI) { /* @@ -662,8 +656,8 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) /* Abort outstanding I/O on NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d:0201 Abort outstanding I/O on NPort x%x\n", - phba->brd_no, Fabric_DID); + "0201 Abort outstanding I/O on NPort x%x\n", + Fabric_DID); pring = &phba->sli.ring[LPFC_ELS_RING]; @@ -736,18 +730,16 @@ static void lpfc_more_plogi(struct lpfc_vport *vport) { int sentplogi; - struct lpfc_hba *phba = vport->phba; if (vport->num_disc_nodes) vport->num_disc_nodes--; /* Continue discovery with PLOGIs to go */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0232 Continue discovery with %d PLOGIs to go " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->num_disc_nodes, - vport->fc_plogi_cnt, vport->fc_flag, vport->port_state); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0232 Continue discovery with %d PLOGIs to go " + "Data: x%x x%x x%x\n", + vport->num_disc_nodes, vport->fc_plogi_cnt, + vport->fc_flag, vport->port_state); /* Check to see if there are more PLOGIs to be sent */ if (vport->fc_flag & FC_NLP_MORE) /* go thru NPR nodes and issue any remaining ELS PLOGIs */ @@ -833,11 +825,12 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); if (!ndlp) { - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0136 PLOGI completes to NPort x%x " - "with no ndlp. Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, irsp->un.elsreq64.remoteID, - irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpIoTag); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0136 PLOGI completes to NPort x%x " + "with no ndlp. Data: x%x x%x x%x\n", + irsp->un.elsreq64.remoteID, + irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->ulpIoTag); goto out; } @@ -851,13 +844,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, rc = 0; /* PLOGI completes to NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0102 PLOGI completes to NPort x%x " - "Data: x%x x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, - irsp->ulpStatus, irsp->un.ulpWord[4], - irsp->ulpTimeout, disc, vport->num_disc_nodes); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0102 PLOGI completes to NPort x%x " + "Data: x%x x%x x%x x%x x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->ulpTimeout, disc, vport->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(vport)) { spin_lock_irq(shost->host_lock); @@ -881,17 +872,14 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } goto out; } - /* PLOGI failed */ if (ndlp->nlp_DID == NameServer_DID) { lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0250 Nameserver login error: " - "0x%x / 0x%x\n", - phba->brd_no, vport->vpi, - irsp->ulpStatus, irsp->un.ulpWord[4]); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0250 Nameserver login error: " + "0x%x / 0x%x\n", + irsp->ulpStatus, irsp->un.ulpWord[4]); } - /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (lpfc_error_lost_link(irsp)) { rc = NLP_STE_FREED_NODE; @@ -1017,14 +1005,12 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "PRLI cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); - /* PRLI completes to NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0103 PRLI completes to NPort x%x " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, - irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, - vport->num_disc_nodes); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0103 PRLI completes to NPort x%x " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->ulpTimeout, vport->num_disc_nodes); vport->fc_prli_sent--; /* Check to see if link went down during discovery */ @@ -1129,18 +1115,15 @@ static void lpfc_more_adisc(struct lpfc_vport *vport) { int sentadisc; - struct lpfc_hba *phba = vport->phba; if (vport->num_disc_nodes) vport->num_disc_nodes--; - /* Continue discovery with ADISCs to go */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0210 Continue discovery with %d ADISCs to go " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->num_disc_nodes, - vport->fc_adisc_cnt, vport->fc_flag, vport->port_state); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0210 Continue discovery with %d ADISCs to go " + "Data: x%x x%x x%x\n", + vport->num_disc_nodes, vport->fc_adisc_cnt, + vport->fc_flag, vport->port_state); /* Check to see if there are more ADISCs to be sent */ if (vport->fc_flag & FC_NLP_MORE) { lpfc_set_disctmo(vport); @@ -1206,15 +1189,12 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC); spin_unlock_irq(shost->host_lock); - /* ADISC completes to NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0104 ADISC completes to NPort x%x " - "Data: x%x x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, - irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, - disc, vport->num_disc_nodes); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0104 ADISC completes to NPort x%x " + "Data: x%x x%x x%x x%x x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->ulpTimeout, disc, vport->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(vport)) { spin_lock_irq(shost->host_lock); @@ -1374,15 +1354,12 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "LOGO cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); - /* LOGO completes to NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0105 LOGO completes to NPort x%x " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, - irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, - vport->num_disc_nodes); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0105 LOGO completes to NPort x%x " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->ulpTimeout, vport->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(vport)) goto out; @@ -1488,15 +1465,11 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "ELS cmd cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.elsreq64.remoteID); - /* ELS cmd tag completes */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0106 ELS cmd tag x%x completes Data: x%x x%x " - "x%x\n", - phba->brd_no, vport->vpi, - irsp->ulpIoTag, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n", + irsp->ulpIoTag, irsp->ulpStatus, + irsp->un.ulpWord[4], irsp->ulpTimeout); /* Check to see if link went down during discovery */ lpfc_els_chk_latt(vport); lpfc_els_free_iocb(phba, cmdiocb); @@ -1831,9 +1804,9 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, case IOERR_ILLEGAL_COMMAND: if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) && (cmd == ELS_CMD_FDISC)) { - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0124 FDISC failed (3/6) retrying...\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0124 FDISC failed (3/6) " + "retrying...\n"); lpfc_mbx_unreg_vpi(vport); retry = 1; /* Always retry for this case */ @@ -1898,10 +1871,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && (cmd == ELS_CMD_FDISC) && (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){ - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0125 FDISC Failed (x%x)." - " Fabric out of resources\n", - phba->brd_no, vport->vpi, stat.un.lsRjtError); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0125 FDISC Failed (x%x). " + "Fabric out of resources\n", + stat.un.lsRjtError); lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_RSCS); } @@ -1926,10 +1899,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ((stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_PNAME) || (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID)) ) { - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0123 FDISC Failed (x%x)." - " Fabric Detected Bad WWN\n", - phba->brd_no, vport->vpi, stat.un.lsRjtError); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0123 FDISC Failed (x%x). " + "Fabric Detected Bad WWN\n", + stat.un.lsRjtError); lpfc_vport_set_state(vport, FC_VPORT_FABRIC_REJ_WWN); } @@ -1959,11 +1932,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (retry) { /* Retry ELS command to remote NPORT */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0107 Retry ELS command x%x to remote " - "NPORT x%x Data: x%x x%x\n", - phba->brd_no, vport->vpi, - cmd, did, cmdiocb->retry, delay); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0107 Retry ELS command x%x to remote " + "NPORT x%x Data: x%x x%x\n", + cmd, did, cmdiocb->retry, delay); if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) && ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || @@ -2031,7 +2003,6 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return 1; } } - /* No retry ELS command to remote NPORT */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "0108 No retry ELS command x%x to remote " @@ -2086,14 +2057,12 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, "ACC LOGO cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); - /* ACC to LOGO completes to NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0109 ACC to LOGO completes to NPort x%x " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0109 ACC to LOGO completes to NPort x%x " + "Data: x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); switch (ndlp->nlp_state) { case NLP_STE_UNUSED_NODE: /* node is just allocated */ lpfc_drop_node(vport, ndlp); @@ -2155,17 +2124,14 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "ACC cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.rcvels.remoteID); - /* ELS response tag completes */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0110 ELS response tag x%x completes " - "Data: x%x x%x x%x x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, - rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, - ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, - ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0110 ELS response tag x%x completes " + "Data: x%x x%x x%x x%x x%x x%x x%x\n", + cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, + rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); if (mbox) { if ((rspiocb->iocb.ulpStatus == 0) && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { @@ -2309,15 +2275,13 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, lpfc_nlp_put(ndlp); elsiocb->context1 = NULL; } - /* Xmit ELS ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0128 Xmit ELS ACC response tag x%x, XRI: x%x, " - "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n", - phba->brd_no, vport->vpi, elsiocb->iotag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0128 Xmit ELS ACC response tag x%x, XRI: x%x, " + "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n", + elsiocb->iotag, elsiocb->iocb.ulpContext, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); if (ndlp->nlp_flag & NLP_LOGO_ACC) { spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_LOGO_ACC; @@ -2375,14 +2339,13 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, } /* Xmit ELS RJT response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0129 Xmit ELS RJT x%x response tag x%x " - "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, " - "rpi x%x\n", - phba->brd_no, vport->vpi, rejectError, elsiocb->iotag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0129 Xmit ELS RJT x%x response tag x%x " + "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, " + "rpi x%x\n", + rejectError, elsiocb->iotag, + elsiocb->iocb.ulpContext, ndlp->nlp_DID, + ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, "Issue LS_RJT: did:x%x flg:x%x err:x%x", ndlp->nlp_DID, ndlp->nlp_flag, rejectError); @@ -2422,13 +2385,12 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, icmd->ulpContext = oldcmd->ulpContext; /* Xri */ /* Xmit ADISC ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0130 Xmit ADISC ACC response iotag x%x xri: " - "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n", - phba->brd_no, vport->vpi, elsiocb->iotag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0130 Xmit ADISC ACC response iotag x%x xri: " + "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n", + elsiocb->iotag, elsiocb->iocb.ulpContext, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; @@ -2482,15 +2444,13 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - /* Xmit PRLI ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0131 Xmit PRLI ACC response tag x%x xri x%x, " - "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", - phba->brd_no, vport->vpi, elsiocb->iotag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0131 Xmit PRLI ACC response tag x%x xri x%x, " + "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", + elsiocb->iotag, elsiocb->iocb.ulpContext, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)); @@ -2564,16 +2524,11 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - /* Xmit RNID ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0132 Xmit RNID ACC response tag x%x " - "xri x%x\n", - phba->brd_no, vport->vpi, elsiocb->iotag, - elsiocb->iocb.ulpContext); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0132 Xmit RNID ACC response tag x%x xri x%x\n", + elsiocb->iotag, elsiocb->iocb.ulpContext); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); - *((uint32_t *) (pcmd)) = ELS_CMD_ACC; pcmd += sizeof(uint32_t); @@ -2716,7 +2671,6 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) D_ID rscn_did; uint32_t *lp; uint32_t payload_len, i; - struct lpfc_hba *phba = vport->phba; ns_did.un.word = did; @@ -2751,12 +2705,10 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) break; default: /* Unknown Identifier in RSCN node */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0217 Unknown " - "Identifier in RSCN payload " - "Data: x%x\n", - phba->brd_no, vport->vpi, - rscn_did.un.word); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0217 Unknown Identifier in " + "RSCN payload Data: x%x\n", + rscn_did.un.word); case 3: /* Whole Fabric effected */ return did; } @@ -2813,13 +2765,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK); payload_len -= sizeof(uint32_t); /* take off word 0 */ - /* RSCN received */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0214 RSCN received Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->fc_flag, payload_len, - *lp, rscn_cnt); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0214 RSCN received Data: x%x x%x x%x x%x\n", + vport->fc_flag, payload_len, *lp, rscn_cnt); for (i = 0; i < payload_len/sizeof(uint32_t); i++) fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_RSCN, lp[i]); @@ -2854,11 +2803,11 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, } if (rscn_id == hba_id) { /* ALL NPortIDs in RSCN are on HBA */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0214 Ignore RSCN Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->fc_flag, payload_len, - *lp, rscn_cnt); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0214 Ignore RSCN " + "Data: x%x x%x x%x x%x\n", + vport->fc_flag, payload_len, + *lp, rscn_cnt); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, "RCV RSCN vport: did:x%x/ste:x%x flg:x%x", ndlp->nlp_DID, vport->port_state, @@ -2904,23 +2853,21 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, } /* Deferred RSCN */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0235 Deferred RSCN " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, - vport->fc_rscn_id_cnt, vport->fc_flag, - vport->port_state); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0235 Deferred RSCN " + "Data: x%x x%x x%x\n", + vport->fc_rscn_id_cnt, vport->fc_flag, + vport->port_state); } else { spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_RSCN_DISCOVERY; spin_unlock_irq(shost->host_lock); /* ReDiscovery RSCN */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0234 ReDiscovery RSCN " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, - vport->fc_rscn_id_cnt, vport->fc_flag, - vport->port_state); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0234 ReDiscovery RSCN " + "Data: x%x x%x x%x\n", + vport->fc_rscn_id_cnt, vport->fc_flag, + vport->port_state); } /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, @@ -2973,11 +2920,10 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) lpfc_set_disctmo(vport); /* RSCN processed */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0215 RSCN processed Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - vport->fc_flag, 0, vport->fc_rscn_id_cnt, - vport->port_state); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0215 RSCN processed Data: x%x x%x x%x x%x\n", + vport->fc_flag, 0, vport->fc_rscn_id_cnt, + vport->port_state); /* To process RSCN, first compare RSCN data with NameServer */ vport->fc_ns_retry = 0; @@ -3045,10 +2991,10 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, /* An FLOGI ELS command was received from DID in Loop Mode */ - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0113 An FLOGI ELS command x%x was " - "received from DID x%x in Loop Mode\n", - phba->brd_no, vport->vpi, cmd, did); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0113 An FLOGI ELS command x%x was " + "received from DID x%x in Loop Mode\n", + cmd, did); return 1; } @@ -3219,16 +3165,13 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt); rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord); rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt); - /* Xmit ELS RPS ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0118 Xmit ELS RPS ACC response tag x%x " - "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, " - "rpi x%x\n", - phba->brd_no, ndlp->vport->vpi, elsiocb->iotag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, + "0118 Xmit ELS RPS ACC response tag x%x xri x%x, " + "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", + elsiocb->iotag, elsiocb->iocb.ulpContext, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; phba->fc_stat.elsXmitACC++; if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) @@ -3330,21 +3273,16 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID); memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname, sizeof(struct lpfc_name)); - memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t)); - - /* Xmit ELS RPL ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0120 Xmit ELS RPL ACC response tag x%x " - "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, " - "rpi x%x\n", - phba->brd_no, vport->vpi, elsiocb->iotag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0120 Xmit ELS RPL ACC response tag x%x " + "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, " + "rpi x%x\n", + elsiocb->iotag, elsiocb->iocb.ulpContext, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; - phba->fc_stat.elsXmitACC++; if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); @@ -3397,7 +3335,6 @@ static int lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) { - struct lpfc_hba *phba = vport->phba; struct lpfc_dmabuf *pcmd; uint32_t *lp; IOCB_t *icmd; @@ -3411,12 +3348,9 @@ lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, cmd = *lp++; fp = (FARP *) lp; - /* FARP-REQ received from DID */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0601 FARP-REQ received from DID x%x\n", - phba->brd_no, vport->vpi, did); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0601 FARP-REQ received from DID x%x\n", did); /* We will only support match on WWPN or WWNN */ if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) { return 0; @@ -3464,7 +3398,6 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, uint32_t *lp; IOCB_t *icmd; uint32_t cmd, did; - struct lpfc_hba *phba = vport->phba; icmd = &cmdiocb->iocb; did = icmd->un.elsreq64.remoteID; @@ -3473,9 +3406,8 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, cmd = *lp++; /* FARP-RSP received from DID */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0600 FARP-RSP received from DID x%x\n", - phba->brd_no, vport->vpi, did); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0600 FARP-RSP received from DID x%x\n", did); /* ACCEPT the Farp resp request */ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); @@ -3495,10 +3427,8 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_hba *phba = vport->phba; /* FAN received */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0265 FAN received\n", - phba->brd_no, vport->vpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0265 FAN received\n"); icmd = &cmdiocb->iocb; did = icmd->un.elsreq64.remoteID; pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; @@ -3657,13 +3587,10 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) if (ndlp) remote_ID = ndlp->nlp_DID; } - - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0127 ELS timeout Data: x%x x%x x%x " - "x%x\n", - phba->brd_no, vport->vpi, els_command, - remote_ID, cmd->ulpCommand, cmd->ulpIoTag); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0127 ELS timeout Data: x%x x%x x%x " + "x%x\n", els_command, + remote_ID, cmd->ulpCommand, cmd->ulpIoTag); lpfc_sli_issue_abort_iotag(phba, pring, piocb); } spin_unlock_irq(&phba->hbalock); @@ -3838,11 +3765,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, cmd &= ELS_CMD_MASK; } /* ELS command received from NPORT */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0112 ELS command x%x received from NPORT x%x " - "Data: x%x\n", phba->brd_no, vport->vpi, cmd, did, - vport->port_state); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0112 ELS command x%x received from NPORT x%x " + "Data: x%x\n", cmd, did, vport->port_state); switch (cmd) { case ELS_CMD_PLOGI: lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, @@ -4011,10 +3936,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, rjt_err = LSRJT_INVALID_CMD; /* Unknown ELS command received from NPORT */ - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0115 Unknown ELS command x%x " - "received from NPORT x%x\n", - phba->brd_no, vport->vpi, cmd, did); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0115 Unknown ELS command x%x " + "received from NPORT x%x\n", cmd, did); if (newnode) lpfc_drop_node(vport, ndlp); break; @@ -4035,11 +3959,10 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, dropit: lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0111 Dropping received ELS cmd " + "(%d):0111 Dropping received ELS cmd " "Data: x%x x%x x%x\n", - phba->brd_no, vport ? vport->vpi : 0xffff, - icmd->ulpStatus, icmd->un.ulpWord[4], - icmd->ulpTimeout); + vport ? vport->vpi : 0xffff, icmd->ulpStatus, + icmd->un.ulpWord[4], icmd->ulpTimeout); phba->fc_stat.elsRcvDrop++; } @@ -4151,9 +4074,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0251 NameServer login: no memory\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0251 NameServer login: no memory\n"); return; } lpfc_nlp_init(vport, ndlp, NameServer_DID); @@ -4164,9 +4086,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) if (lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0)) { lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0252 Cannot issue NameServer login\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0252 Cannot issue NameServer login\n"); return; } @@ -4197,9 +4118,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_nlp_put(ndlp); if (mb->mbxStatus) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0915 Register VPI failed: 0x%x\n", - phba->brd_no, vport->vpi, mb->mbxStatus); + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0915 Register VPI failed: 0x%x\n", + mb->mbxStatus); switch (mb->mbxStatus) { case 0x11: /* unsupported feature */ @@ -4248,17 +4169,14 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; lpfc_vport_set_state(vport, FC_VPORT_FAILED); - - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0253 Register VPI: Cannot send mbox\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0253 Register VPI: Can't send mbox\n"); } } else { lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0254 Register VPI: no memory\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0254 Register VPI: no memory\n"); vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; lpfc_nlp_put(ndlp); @@ -4277,11 +4195,10 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, IOCB_t *irsp = &rspiocb->iocb; struct lpfc_iocbq *piocb; - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0123 FDISC completes. x%x/x%x prevDID: x%x\n", - phba->brd_no, vport->vpi, - irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0123 FDISC completes. x%x/x%x prevDID: x%x\n", + irsp->ulpStatus, irsp->un.ulpWord[4], + vport->fc_prevDID); /* Since all FDISCs are being single threaded, we * must reset the discovery timer for ALL vports * waiting to send FDISC when one completes. @@ -4298,13 +4215,10 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* Check for retry */ if (lpfc_els_retry(phba, cmdiocb, rspiocb)) goto out; - /* FDISC failed */ - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0124 FDISC failed. (%d/%d)\n", - phba->brd_no, vport->vpi, - irsp->ulpStatus, irsp->un.ulpWord[4]); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0124 FDISC failed. (%d/%d)\n", + irsp->ulpStatus, irsp->un.ulpWord[4]); if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) lpfc_vport_set_state(vport, FC_VPORT_FAILED); @@ -4370,10 +4284,8 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ELS_CMD_FDISC); if (!elsiocb) { lpfc_vport_set_state(vport, FC_VPORT_FAILED); - - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0255 Issue FDISC: no IOCB\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0255 Issue FDISC: no IOCB\n"); return 1; } @@ -4419,11 +4331,8 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); lpfc_vport_set_state(vport, FC_VPORT_FAILED); - - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0256 Issue FDISC: Cannot send IOCB\n", - phba->brd_no, vport->vpi); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0256 Issue FDISC: Cannot send IOCB\n"); return 1; } lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 914e74ac11e5..55c4e5455a57 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -201,25 +201,23 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) warn_on = 0; if (warn_on) { - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0203 Devloss timeout on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, - *name, *(name+1), *(name+2), *(name+3), - *(name+4), *(name+5), *(name+6), *(name+7), - ndlp->nlp_DID, ndlp->nlp_flag, - ndlp->nlp_state, ndlp->nlp_rpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0203 Devloss timeout on " + "WWPN %x:%x:%x:%x:%x:%x:%x:%x " + "NPort x%x Data: x%x x%x x%x\n", + *name, *(name+1), *(name+2), *(name+3), + *(name+4), *(name+5), *(name+6), *(name+7), + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, ndlp->nlp_rpi); } else { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0204 Devloss timeout on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, - *name, *(name+1), *(name+2), *(name+3), - *(name+4), *(name+5), *(name+6), *(name+7), - ndlp->nlp_DID, ndlp->nlp_flag, - ndlp->nlp_state, ndlp->nlp_rpi); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0204 Devloss timeout on " + "WWPN %x:%x:%x:%x:%x:%x:%x:%x " + "NPort x%x Data: x%x x%x x%x\n", + *name, *(name+1), *(name+2), *(name+3), + *(name+4), *(name+5), *(name+6), *(name+7), + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, ndlp->nlp_rpi); } if (!(vport->load_flag & FC_UNLOADING) && @@ -750,12 +748,10 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Check for error */ if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) { /* CLEAR_LA mbox error state */ - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0320 CLEAR_LA mbxStatus error x%x hba " - "state x%x\n", - phba->brd_no, vport->vpi, mb->mbxStatus, - vport->port_state); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0320 CLEAR_LA mbxStatus error x%x hba " + "state x%x\n", + mb->mbxStatus, vport->port_state); phba->link_state = LPFC_HBA_ERROR; goto out; } @@ -787,10 +783,8 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) out: /* Device Discovery completes */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0225 Device Discovery completes\n", - phba->brd_no, vport->vpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0225 Device Discovery completes\n"); mempool_free(pmb, phba->mbox_mem_pool); spin_lock_irq(shost->host_lock); @@ -847,19 +841,17 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; out: - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0306 CONFIG_LINK mbxStatus error x%x " - "HBA state x%x\n", - phba->brd_no, vport->vpi, pmb->mb.mbxStatus, - vport->port_state); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0306 CONFIG_LINK mbxStatus error x%x " + "HBA state x%x\n", + pmb->mb.mbxStatus, vport->port_state); mempool_free(pmb, phba->mbox_mem_pool); lpfc_linkdown(phba); - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0200 CONFIG_LINK bad hba state x%x\n", - phba->brd_no, vport->vpi, vport->port_state); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0200 CONFIG_LINK bad hba state x%x\n", + vport->port_state); lpfc_issue_clear_la(phba, vport); return; @@ -876,12 +868,10 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Check for error */ if (mb->mbxStatus) { /* READ_SPARAM mbox error state */ - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0319 READ_SPARAM mbxStatus error x%x " - "hba state x%x>\n", - phba->brd_no, vport->vpi, mb->mbxStatus, - vport->port_state); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0319 READ_SPARAM mbxStatus error x%x " + "hba state x%x>\n", + mb->mbxStatus, vport->port_state); lpfc_linkdown(phba); goto out; } @@ -964,7 +954,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) if (i == 0) { phba->alpa_map[0] = 0; } else { - if (phba->cfg_log_verbose & LOG_LINK_EVENT) { + if (vport->cfg_log_verbose & LOG_LINK_EVENT) { int numalpa, j, k; union { uint8_t pamap[16]; @@ -990,10 +980,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT, - "%d:1304 Link Up Event " + "1304 Link Up Event " "ALPA map Data: x%x " "x%x x%x x%x\n", - phba->brd_no, un.pa.wd1, un.pa.wd2, un.pa.wd3, un.pa.wd4); } @@ -1041,11 +1030,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) } out: lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0263 Discovery Mailbox error: state: 0x%x : %p %p\n", - phba->brd_no, vport->vpi, - vport->port_state, sparam_mbox, cfglink_mbox); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0263 Discovery Mailbox error: state: 0x%x : %p %p\n", + vport->port_state, sparam_mbox, cfglink_mbox); lpfc_issue_clear_la(phba, vport); return; } @@ -1086,8 +1073,8 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Check for error */ if (mb->mbxStatus) { lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, - "%d:1307 READ_LA mbox error x%x state x%x\n", - phba->brd_no, mb->mbxStatus, vport->port_state); + "1307 READ_LA mbox error x%x state x%x\n", + mb->mbxStatus, vport->port_state); lpfc_mbx_issue_link_down(phba); phba->link_state = LPFC_HBA_ERROR; goto lpfc_mbx_cmpl_read_la_free_mbuf; @@ -1118,26 +1105,26 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) phba->fc_stat.LinkUp++; if (phba->link_flag & LS_LOOPBACK_MODE) { lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, - "%d:1306 Link Up Event in loop back mode " - "x%x received Data: x%x x%x x%x x%x\n", - phba->brd_no, la->eventTag, phba->fc_eventTag, - la->granted_AL_PA, la->UlnkSpeed, - phba->alpa_map[0]); + "1306 Link Up Event in loop back mode " + "x%x received Data: x%x x%x x%x x%x\n", + la->eventTag, phba->fc_eventTag, + la->granted_AL_PA, la->UlnkSpeed, + phba->alpa_map[0]); } else { lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "%d:1303 Link Up Event x%x received " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, la->eventTag, phba->fc_eventTag, - la->granted_AL_PA, la->UlnkSpeed, - phba->alpa_map[0]); + "1303 Link Up Event x%x received " + "Data: x%x x%x x%x x%x\n", + la->eventTag, phba->fc_eventTag, + la->granted_AL_PA, la->UlnkSpeed, + phba->alpa_map[0]); } lpfc_mbx_process_link_up(phba, la); } else { phba->fc_stat.LinkDown++; lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "%d:1305 Link Down Event x%x received " + "1305 Link Down Event x%x received " "Data: x%x x%x x%x\n", - phba->brd_no, la->eventTag, phba->fc_eventTag, + la->eventTag, phba->fc_eventTag, phba->pport->port_state, vport->fc_flag); lpfc_mbx_issue_link_down(phba); } @@ -1185,10 +1172,9 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) case 0x0011: case 0x0020: case 0x9700: - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d (%d):0911 cmpl_unreg_vpi, " - "mb status = 0x%x\n", - phba->brd_no, vport->vpi, mb->mbxStatus); + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "0911 cmpl_unreg_vpi, mb status = 0x%x\n", + mb->mbxStatus); break; } vport->unreg_vpi_cmpl = VPORT_OK; @@ -1217,9 +1203,8 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) mbox->mbox_cmpl = lpfc_mbx_cmpl_unreg_vpi; rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); if (rc == MBX_NOT_FINISHED) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT, - "%d (%d):1800 Could not issue unreg_vpi\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, + "1800 Could not issue unreg_vpi\n"); mempool_free(mbox, phba->mbox_mem_pool); vport->unreg_vpi_cmpl = VPORT_ERROR; } @@ -1236,9 +1221,9 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) case 0x0011: case 0x9601: case 0x9602: - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d (%d):0912 cmpl_reg_vpi, mb status = 0x%x\n", - phba->brd_no, vport->vpi, mb->mbxStatus); + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "0912 cmpl_reg_vpi, mb status = 0x%x\n", + mb->mbxStatus); lpfc_vport_set_state(vport, FC_VPORT_FAILED); spin_lock_irq(shost->host_lock); vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); @@ -1300,10 +1285,9 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d (%d):0258 Register Fabric login error: 0x%x\n", - phba->brd_no, vport->vpi, mb->mbxStatus); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, + "0258 Register Fabric login error: 0x%x\n", + mb->mbxStatus); return; } @@ -1327,11 +1311,10 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) LPFC_SLI3_NPIV_ENABLED) { lpfc_vport_set_state(vports[i], FC_VPORT_NO_FABRIC_SUPP); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0259 No NPIV " - "Fabric support\n", - phba->brd_no, - vports[i]->vpi); + lpfc_printf_vlog(vport, KERN_ERR, + LOG_ELS, + "0259 No NPIV " + "Fabric support\n"); } } lpfc_destroy_vport_work_array(vports); @@ -1378,9 +1361,9 @@ out: return; } lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0260 Register NameServer error: 0x%x\n", - phba->brd_no, vport->vpi, mb->mbxStatus); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0260 Register NameServer error: 0x%x\n", + mb->mbxStatus); return; } @@ -1605,12 +1588,11 @@ lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int old_state = ndlp->nlp_state; char name1[16], name2[16]; - lpfc_printf_log(vport->phba, KERN_INFO, LOG_NODE, - "%d (%d):0904 NPort state transition x%06x, %s -> %s\n", - vport->phba->brd_no, vport->vpi, - ndlp->nlp_DID, - lpfc_nlp_state_name(name1, sizeof(name1), old_state), - lpfc_nlp_state_name(name2, sizeof(name2), state)); + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "0904 NPort state transition x%06x, %s -> %s\n", + ndlp->nlp_DID, + lpfc_nlp_state_name(name1, sizeof(name1), old_state), + lpfc_nlp_state_name(name2, sizeof(name2), state)); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE, "node statechg did:x%x old:%d ste:%d", @@ -1702,12 +1684,12 @@ lpfc_set_disctmo(struct lpfc_vport *vport) spin_unlock_irq(shost->host_lock); /* Start Discovery Timer state */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0247 Start Discovery Timer state x%x " - "Data: x%x x%lx x%x x%x\n", - phba->brd_no, vport->vpi, vport->port_state, tmo, - (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt, - vport->fc_adisc_cnt); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0247 Start Discovery Timer state x%x " + "Data: x%x x%lx x%x x%x\n", + vport->port_state, tmo, + (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt, + vport->fc_adisc_cnt); return; } @@ -1719,7 +1701,6 @@ int lpfc_can_disctmo(struct lpfc_vport *vport) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_hba *phba = vport->phba; unsigned long iflags; lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, @@ -1738,13 +1719,11 @@ lpfc_can_disctmo(struct lpfc_vport *vport) } /* Cancel Discovery Timer state */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0248 Cancel Discovery Timer state x%x " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->port_state, - vport->fc_flag, vport->fc_plogi_cnt, - vport->fc_adisc_cnt); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0248 Cancel Discovery Timer state x%x " + "Data: x%x x%x x%x\n", + vport->port_state, vport->fc_flag, + vport->fc_plogi_cnt, vport->fc_adisc_cnt); return 0; } @@ -1927,10 +1906,9 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); if (rc == MBX_NOT_FINISHED) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT, - "%d (%d):1815 Could not issue " - "unreg_did (default rpis)\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, + "1815 Could not issue " + "unreg_did (default rpis)\n"); mempool_free(mbox, phba->mbox_mem_pool); } } @@ -1949,12 +1927,11 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) struct lpfc_dmabuf *mp; /* Cleanup node for NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d (%d):0900 Cleanup node for NPort x%x " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, ndlp->nlp_flag, - ndlp->nlp_state, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "0900 Cleanup node for NPort x%x " + "Data: x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, ndlp->nlp_rpi); lpfc_dequeue_node(vport, ndlp); /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ @@ -2086,7 +2063,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, static struct lpfc_nodelist * __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) { - struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp; uint32_t data1; @@ -2096,20 +2072,18 @@ __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) ((uint32_t) ndlp->nlp_xri << 16) | ((uint32_t) ndlp->nlp_type << 8) | ((uint32_t) ndlp->nlp_rpi & 0xff)); - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d (%d):0929 FIND node DID " - " Data: x%p x%x x%x x%x\n", - phba->brd_no, vport->vpi, - ndlp, ndlp->nlp_DID, - ndlp->nlp_flag, data1); + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "0929 FIND node DID " + "Data: x%p x%x x%x x%x\n", + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); return ndlp; } } /* FIND node did NOT FOUND */ - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d (%d):0932 FIND node did x%x NOT FOUND.\n", - phba->brd_no, vport->vpi, did); + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "0932 FIND node did x%x NOT FOUND.\n", did); return NULL; } @@ -2301,12 +2275,11 @@ lpfc_disc_start(struct lpfc_vport *vport) vport->num_disc_nodes = 0; /* Start Discovery state */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0202 Start Discovery hba state x%x " - "Data: x%x x%x x%x\n", - phba->brd_no, vport->vpi, vport->port_state, - vport->fc_flag, vport->fc_plogi_cnt, - vport->fc_adisc_cnt); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0202 Start Discovery hba state x%x " + "Data: x%x x%x x%x\n", + vport->port_state, vport->fc_flag, vport->fc_plogi_cnt, + vport->fc_adisc_cnt); /* First do ADISCs - if any */ num_sent = lpfc_els_disc_adisc(vport); @@ -2524,10 +2497,8 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) * FAN */ /* FAN timeout */ - lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY, - "%d (%d):0221 FAN timeout\n", - phba->brd_no, vport->vpi); - + lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY, + "0221 FAN timeout\n"); /* Start discovery by sending FLOGI, clean up old rpis */ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { @@ -2554,10 +2525,9 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) case LPFC_FLOGI: /* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */ /* Initial FLOGI timeout */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0222 Initial %s timeout\n", - phba->brd_no, vport->vpi, - vport->vpi ? "FLOGI" : "FDISC"); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0222 Initial %s timeout\n", + vport->vpi ? "FLOGI" : "FDISC"); /* Assume no Fabric and go on with discovery. * Check for outstanding ELS FLOGI to abort. @@ -2573,11 +2543,9 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) case LPFC_FABRIC_CFG_LINK: /* hba_state is identically LPFC_FABRIC_CFG_LINK while waiting for NameServer login */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0223 Timeout while waiting for " - "NameServer login\n", - phba->brd_no, vport->vpi); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0223 Timeout while waiting for " + "NameServer login\n"); /* Next look for NameServer ndlp */ ndlp = lpfc_findnode_did(vport, NameServer_DID); if (ndlp) @@ -2588,11 +2556,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) case LPFC_NS_QRY: /* Check for wait for NameServer Rsp timeout */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0224 NameServer Query timeout " - "Data: x%x x%x\n", - phba->brd_no, vport->vpi, - vport->fc_ns_retry, LPFC_MAX_NS_RETRY); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0224 NameServer Query timeout " + "Data: x%x x%x\n", + vport->fc_ns_retry, LPFC_MAX_NS_RETRY); if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { /* Try it one more time */ @@ -2619,10 +2586,9 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) /* Setup and issue mailbox INITIALIZE LINK command */ initlinkmbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!initlinkmbox) { - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0206 Device Discovery " - "completion error\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0206 Device Discovery " + "completion error\n"); phba->link_state = LPFC_HBA_ERROR; break; } @@ -2643,9 +2609,8 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) case LPFC_DISC_AUTH: /* Node Authentication timeout */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0227 Node Authentication timeout\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0227 Node Authentication timeout\n"); lpfc_disc_flush_list(vport); /* @@ -2662,11 +2627,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) case LPFC_VPORT_READY: if (vport->fc_flag & FC_RSCN_MODE) { - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0231 RSCN timeout Data: x%x " - "x%x\n", - phba->brd_no, vport->vpi, - vport->fc_ns_retry, LPFC_MAX_NS_RETRY); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0231 RSCN timeout Data: x%x " + "x%x\n", + vport->fc_ns_retry, LPFC_MAX_NS_RETRY); /* Cleanup any outstanding ELS commands */ lpfc_els_flush_cmd(vport); @@ -2677,20 +2641,17 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) break; default: - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0229 Unexpected discovery timeout, " - "vport State x%x\n", - phba->brd_no, vport->vpi, vport->port_state); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0229 Unexpected discovery timeout, " + "vport State x%x\n", vport->port_state); break; } switch (phba->link_state) { case LPFC_CLEAR_LA: /* CLEAR LA timeout */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0228 CLEAR LA timeout\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0228 CLEAR LA timeout\n"); clrlaerr = 1; break; @@ -2701,10 +2662,9 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) case LPFC_LINK_DOWN: case LPFC_LINK_UP: case LPFC_HBA_ERROR: - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0230 Unexpected timeout, hba link " - "state x%x\n", - phba->brd_no, vport->vpi, phba->link_state); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0230 Unexpected timeout, hba link " + "state x%x\n", phba->link_state); clrlaerr = 1; break; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 83855a5a1826..7e5ea0774e58 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -107,10 +107,9 @@ lpfc_config_port_prep(struct lpfc_hba *phba) if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d:0324 Config Port initialization " + "0324 Config Port initialization " "error, mbxCmd x%x READ_NVPARM, " "mbxStatus x%x\n", - phba->brd_no, mb->mbxCommand, mb->mbxStatus); mempool_free(pmb, phba->mbox_mem_pool); return -ERESTART; @@ -128,9 +127,8 @@ lpfc_config_port_prep(struct lpfc_hba *phba) rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0439 Adapter failed to init, mbxCmd x%x " + "0439 Adapter failed to init, mbxCmd x%x " "READ_REV, mbxStatus x%x\n", - phba->brd_no, mb->mbxCommand, mb->mbxStatus); mempool_free( pmb, phba->mbox_mem_pool); return -ERESTART; @@ -144,9 +142,8 @@ lpfc_config_port_prep(struct lpfc_hba *phba) if (mb->un.varRdRev.rr == 0) { vp->rev.rBit = 0; lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0440 Adapter failed to init, READ_REV has " - "missing revision information.\n", - phba->brd_no); + "0440 Adapter failed to init, READ_REV has " + "missing revision information.\n"); mempool_free(pmb, phba->mbox_mem_pool); return -ERESTART; } @@ -197,9 +194,8 @@ lpfc_config_port_prep(struct lpfc_hba *phba) if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "%d:0441 VPD not present on adapter, " + "0441 VPD not present on adapter, " "mbxCmd x%x DUMP VPD, mbxStatus x%x\n", - phba->brd_no, mb->mbxCommand, mb->mbxStatus); mb->un.varDmp.word_cnt = 0; } @@ -253,9 +249,8 @@ lpfc_config_port_post(struct lpfc_hba *phba) pmb->vport = vport; if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0448 Adapter failed init, mbxCmd x%x " + "0448 Adapter failed init, mbxCmd x%x " "READ_SPARM mbxStatus x%x\n", - phba->brd_no, mb->mbxCommand, mb->mbxStatus); phba->link_state = LPFC_HBA_ERROR; mp = (struct lpfc_dmabuf *) pmb->context1; @@ -312,9 +307,8 @@ lpfc_config_port_post(struct lpfc_hba *phba) pmb->vport = vport; if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0453 Adapter failed to init, mbxCmd x%x " + "0453 Adapter failed to init, mbxCmd x%x " "READ_CONFIG, mbxStatus x%x\n", - phba->brd_no, mb->mbxCommand, mb->mbxStatus); phba->link_state = LPFC_HBA_ERROR; mempool_free( pmb, phba->mbox_mem_pool); @@ -344,9 +338,8 @@ lpfc_config_port_post(struct lpfc_hba *phba) && !(phba->lmt & LMT_10Gb))) { /* Reset link speed to auto */ lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT, - "%d:1302 Invalid speed for this board: " + "1302 Invalid speed for this board: " "Reset link speed to auto: x%x\n", - phba->brd_no, phba->cfg_link_speed); phba->cfg_link_speed = LINK_SPEED_AUTO; } @@ -402,9 +395,8 @@ lpfc_config_port_post(struct lpfc_hba *phba) lpfc_set_loopback_flag(phba); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0454 Adapter failed to init, mbxCmd x%x " + "0454 Adapter failed to init, mbxCmd x%x " "INIT_LINK, mbxStatus x%x\n", - phba->brd_no, mb->mbxCommand, mb->mbxStatus); /* Clear all interrupt enable conditions */ @@ -588,8 +580,8 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) * need to take the HBA offline. */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0459 Adapter heartbeat failure, taking " - "this port offline.\n", phba->brd_no); + "0459 Adapter heartbeat failure, taking " + "this port offline.\n"); spin_lock_irq(&phba->hbalock); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; @@ -631,9 +623,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba) phba->work_hs & HS_FFER5) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, - "%d:1301 Re-establishing Link " + "1301 Re-establishing Link " "Data: x%x x%x x%x\n", - phba->brd_no, phba->work_hs, + phba->work_hs, phba->work_status[0], phba->work_status[1]); vports = lpfc_create_vport_work_array(phba); if (vports != NULL) @@ -679,9 +671,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba) * twice. This is the adapter hardware error path. */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0457 Adapter Hardware Error " + "0457 Adapter Hardware Error " "Data: x%x x%x x%x\n", - phba->brd_no, phba->work_hs, + phba->work_hs, phba->work_status[0], phba->work_status[1]); event_data = FC_REG_DUMP_EVENT; @@ -777,8 +769,7 @@ lpfc_handle_latt_err_exit: /* The other case is an error from issue_mbox */ if (rc == -ENOMEM) lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, - "%d:0300 READ_LA: no buffers\n", - phba->brd_no); + "0300 READ_LA: no buffers\n"); return; } @@ -803,8 +794,7 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) /* Vital Product */ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "%d:0455 Vital Product Data: x%x x%x x%x x%x\n", - phba->brd_no, + "0455 Vital Product Data: x%x x%x x%x x%x\n", (uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2], (uint32_t) vpd[3]); while (!finished && (index < (len - 4))) { @@ -1323,10 +1313,9 @@ lpfc_establish_link_tmo(unsigned long ptr) /* Re-establishing Link, timer expired */ lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "%d:1300 Re-establishing Link, timer expired " + "1300 Re-establishing Link, timer expired " "Data: x%x x%x\n", - phba->brd_no, phba->pport->fc_flag, - phba->pport->port_state); + phba->pport->fc_flag, phba->pport->port_state); vports = lpfc_create_vport_work_array(phba); if (vports != NULL) for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { @@ -1382,8 +1371,7 @@ lpfc_online(struct lpfc_hba *phba) return 0; lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, - "%d:0458 Bring Adapter online\n", - phba->brd_no); + "0458 Bring Adapter online\n"); lpfc_block_mgmt_io(phba); @@ -1468,8 +1456,7 @@ lpfc_offline(struct lpfc_hba *phba) /* stop all timers associated with this hba */ lpfc_stop_phba_timers(phba); lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, - "%d:0460 Bring Adapter offline\n", - phba->brd_no); + "0460 Bring Adapter offline\n"); /* Bring down the SLI Layer and cleanup. The HBA is offline now. */ lpfc_sli_hba_down(phba); @@ -1648,17 +1635,15 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) } if (time >= 30 * HZ) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "%d:0461 Scanning longer than 30 " - "seconds. Continuing initialization\n", - phba->brd_no); + "0461 Scanning longer than 30 " + "seconds. Continuing initialization\n"); stat = 1; goto finished; } if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "%d:0465 Link down longer than 15 " - "seconds. Continuing initialization\n", - phba->brd_no); + "0465 Link down longer than 15 " + "seconds. Continuing initialization\n"); stat = 1; goto finished; } @@ -1910,17 +1895,16 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (phba->cfg_use_msi) { error = pci_enable_msi(phba->pcidev); if (error) - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "%d:0452 " - "Enable MSI failed, continuing with " - "IRQ\n", phba->brd_no); + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "0452 Enable MSI failed, continuing " + "with IRQ\n"); } error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, LPFC_DRIVER_NAME, phba); if (error) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0451 Enable interrupt handler failed\n", - phba->brd_no); + "0451 Enable interrupt handler failed\n"); goto out_disable_msi; } diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index 8a6ceffeabcf..626e4d878725 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h @@ -33,6 +33,12 @@ #define LOG_VPORT 0x4000 /* NPIV events */ #define LOG_ALL_MSG 0xffff /* LOG all messages */ +#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ + { if (((mask) &(vport)->cfg_log_verbose) || (level[1] <= '3')) \ + dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ + fmt, (vport)->phba->brd_no, vport->vpi, ##arg); } + #define lpfc_printf_log(phba, level, mask, fmt, arg...) \ - { if (((mask) &(phba)->cfg_log_verbose) || (level[1] <= '3')) \ - dev_printk(level, &((phba)->pcidev)->dev, fmt, ##arg); } + { if (((mask) &(phba)->pport->cfg_log_verbose) || (level[1] <= '3')) \ + dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ + fmt, phba->brd_no, ##arg); } diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 8f42fbfdd29e..5fa1c6f70a98 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -275,11 +275,8 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) kfree(mp); mb->mbxCommand = MBX_READ_SPARM64; /* READ_SPARAM: no buffers */ - lpfc_printf_log(phba, - KERN_WARNING, - LOG_MBOX, - "%d:0301 READ_SPARAM: no buffers\n", - phba->brd_no); + lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, + "0301 READ_SPARAM: no buffers\n"); return (1); } INIT_LIST_HEAD(&mp->list); @@ -378,9 +375,8 @@ lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, mb->mbxCommand = MBX_REG_LOGIN64; /* REG_LOGIN: no buffers */ lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, - "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, " - "flag x%x\n", - phba->brd_no, vpi, did, flag); + "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, " + "flag x%x\n", vpi, did, flag); return (1); } INIT_LIST_HEAD(&mp->list); diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9c159a8e6e8c..66ba51cbeb50 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -133,15 +133,15 @@ lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name)); return 1; bad_service_param: - lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0207 Device %x " - "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent " - "invalid service parameters. Ignoring device.\n", - vport->phba->brd_no, ndlp->vport->vpi, ndlp->nlp_DID, - sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1], - sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3], - sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5], - sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0207 Device %x " + "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent " + "invalid service parameters. Ignoring device.\n", + ndlp->nlp_DID, + sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1], + sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3], + sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5], + sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]); return 0; } @@ -194,11 +194,11 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) IOCB_t *cmd; /* Abort outstanding I/O on NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0205 Abort outstanding I/O on NPort x%x " - "Data: x%x x%x x%x\n", - phba->brd_no, ndlp->vport->vpi, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY, + "0205 Abort outstanding I/O on NPort x%x " + "Data: x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi); lpfc_fabric_abort_nport(ndlp); @@ -298,11 +298,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, icmd = &cmdiocb->iocb; /* PLOGI chkparm OK */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, - ndlp->nlp_rpi); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, + ndlp->nlp_rpi); if (vport->cfg_fcp_class == 2 && sp->cls2.classValid) ndlp->nlp_fcp_info |= CLASS2; @@ -582,12 +581,11 @@ static uint32_t lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { - lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0253 Illegal State Transition: node x%x " - "event x%x, state x%x Data: x%x x%x\n", - vport->phba->brd_no, vport->vpi, - ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, - ndlp->nlp_flag); + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0253 Illegal State Transition: node x%x " + "event x%x, state x%x Data: x%x x%x\n", + ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, + ndlp->nlp_flag); return ndlp->nlp_state; } @@ -777,15 +775,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) goto out; - /* PLOGI chkparm OK */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (%d):0121 PLOGI chkparm OK " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0121 PLOGI chkparm OK Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid)) ndlp->nlp_fcp_info |= CLASS2; else @@ -805,10 +799,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) { - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0133 PLOGI: no memory for reg_login " + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0133 PLOGI: no memory for reg_login " "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, ndlp->nlp_rpi); goto out; @@ -843,30 +836,27 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, kfree(mp); mempool_free(mbox, phba->mbox_mem_pool); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0134 PLOGI: cannot issue reg_login " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0134 PLOGI: cannot issue reg_login " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); } else { mempool_free(mbox, phba->mbox_mem_pool); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0135 PLOGI: cannot format reg_login " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, vport->vpi, - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0135 PLOGI: cannot format reg_login " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); } out: if (ndlp->nlp_DID == NameServer_DID) { lpfc_vport_set_state(vport, FC_VPORT_FAILED); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0261 Cannot Register NameServer login\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0261 Cannot Register NameServer login\n"); } /* Free this node since the driver cannot login or has the wrong @@ -1188,19 +1178,15 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, uint32_t evt) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_hba *phba = vport->phba; LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; MAILBOX_t *mb = &pmb->mb; uint32_t did = mb->un.varWords[1]; if (mb->mbxStatus) { /* RegLogin failed */ - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d (%d):0246 RegLogin failed Data: x%x x%x " - "x%x\n", - phba->brd_no, vport->vpi, + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + "0246 RegLogin failed Data: x%x x%x x%x\n", did, mb->mbxStatus, vport->port_state); - /* * If RegLogin failed due to lack of HBA resources do not * retry discovery. @@ -2046,7 +2032,6 @@ int lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { - struct lpfc_hba *phba = vport->phba; uint32_t cur_state, rc; uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t); @@ -2055,11 +2040,10 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, cur_state = ndlp->nlp_state; /* DSM in event on NPort in state */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0211 DSM in event x%x on NPort x%x in " - "state %d Data: x%x\n", - phba->brd_no, vport->vpi, - evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0211 DSM in event x%x on NPort x%x in " + "state %d Data: x%x\n", + evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, "DSM in: evt:%d ste:%d did:x%x", @@ -2069,11 +2053,9 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, rc = (func) (vport, ndlp, arg, evt); /* DSM out state on NPort */ - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d (%d):0212 DSM out state %d on NPort x%x " - "Data: x%x\n", - phba->brd_no, vport->vpi, - rc, ndlp->nlp_DID, ndlp->nlp_flag); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0212 DSM out state %d on NPort x%x Data: x%x\n", + rc, ndlp->nlp_DID, ndlp->nlp_flag); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, "DSM out: ste:%d did:x%x flg:x%x", diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 78666c62330e..9ee2927ad82a 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -406,9 +406,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; - struct lpfc_hba *phba = vport->phba; uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm; - uint32_t vpi = vport->vpi; uint32_t resp_info = fcprsp->rspStatus2; uint32_t scsi_status = fcprsp->rspStatus3; uint32_t *lp; @@ -440,15 +438,15 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, if (!scsi_status && (resp_info & RESID_UNDER)) logit = LOG_FCP; - lpfc_printf_log(phba, KERN_WARNING, logit, - "%d (%d):0730 FCP command x%x failed: x%x SNS x%x x%x " - "Data: x%x x%x x%x x%x x%x\n", - phba->brd_no, vpi, cmnd->cmnd[0], scsi_status, - be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info, - be32_to_cpu(fcprsp->rspResId), - be32_to_cpu(fcprsp->rspSnsLen), - be32_to_cpu(fcprsp->rspRspLen), - fcprsp->rspInfo3); + lpfc_printf_vlog(vport, KERN_WARNING, logit, + "0730 FCP command x%x failed: x%x SNS x%x x%x " + "Data: x%x x%x x%x x%x x%x\n", + cmnd->cmnd[0], scsi_status, + be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info, + be32_to_cpu(fcprsp->rspResId), + be32_to_cpu(fcprsp->rspSnsLen), + be32_to_cpu(fcprsp->rspRspLen), + fcprsp->rspInfo3); if (resp_info & RSP_LEN_VALID) { rsplen = be32_to_cpu(fcprsp->rspRspLen); @@ -463,12 +461,12 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, if (resp_info & RESID_UNDER) { scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d (%d):0716 FCP Read Underrun, expected %d, " - "residual %d Data: x%x x%x x%x\n", - phba->brd_no, vpi, be32_to_cpu(fcpcmd->fcpDl), - scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], - cmnd->underflow); + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, + "0716 FCP Read Underrun, expected %d, " + "residual %d Data: x%x x%x x%x\n", + be32_to_cpu(fcpcmd->fcpDl), + scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], + cmnd->underflow); /* * If there is an under run check if under run reported by @@ -478,14 +476,13 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) && fcpi_parm && (scsi_get_resid(cmnd) != fcpi_parm)) { - lpfc_printf_log(phba, KERN_WARNING, - LOG_FCP | LOG_FCP_ERROR, - "%d (%d):0735 FCP Read Check Error " - "and Underrun Data: x%x x%x x%x x%x\n", - phba->brd_no, vpi, - be32_to_cpu(fcpcmd->fcpDl), - scsi_get_resid(cmnd), fcpi_parm, - cmnd->cmnd[0]); + lpfc_printf_vlog(vport, KERN_WARNING, + LOG_FCP | LOG_FCP_ERROR, + "0735 FCP Read Check Error " + "and Underrun Data: x%x x%x x%x x%x\n", + be32_to_cpu(fcpcmd->fcpDl), + scsi_get_resid(cmnd), fcpi_parm, + cmnd->cmnd[0]); scsi_set_resid(cmnd, scsi_bufflen(cmnd)); host_status = DID_ERROR; } @@ -499,21 +496,19 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, (scsi_status == SAM_STAT_GOOD) && (scsi_bufflen(cmnd) - scsi_get_resid(cmnd) < cmnd->underflow)) { - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d (%d):0717 FCP command x%x residual " - "underrun converted to error " - "Data: x%x x%x x%x\n", - phba->brd_no, vpi, cmnd->cmnd[0], - scsi_bufflen(cmnd), - scsi_get_resid(cmnd), cmnd->underflow); + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, + "0717 FCP command x%x residual " + "underrun converted to error " + "Data: x%x x%x x%x\n", + cmnd->cmnd[0], cmnd->request_bufflen, + scsi_get_resid(cmnd), cmnd->underflow); host_status = DID_ERROR; } } else if (resp_info & RESID_OVER) { - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d (%d):0720 FCP command x%x residual " - "overrun error. Data: x%x x%x \n", - phba->brd_no, vpi, cmnd->cmnd[0], - scsi_bufflen(cmnd), scsi_get_resid(cmnd)); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0720 FCP command x%x residual overrun error. " + "Data: x%x x%x \n", cmnd->cmnd[0], + scsi_bufflen(cmnd), scsi_get_resid(cmnd)); host_status = DID_ERROR; /* @@ -522,13 +517,12 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, */ } else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR, - "%d (%d):0734 FCP Read Check Error Data: " - "x%x x%x x%x x%x\n", - phba->brd_no, vpi, - be32_to_cpu(fcpcmd->fcpDl), - be32_to_cpu(fcprsp->rspResId), - fcpi_parm, cmnd->cmnd[0]); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR, + "0734 FCP Read Check Error Data: " + "x%x x%x x%x x%x\n", + be32_to_cpu(fcpcmd->fcpDl), + be32_to_cpu(fcprsp->rspResId), + fcpi_parm, cmnd->cmnd[0]); host_status = DID_ERROR; scsi_set_resid(cmnd, scsi_bufflen(cmnd)); } @@ -547,9 +541,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, struct lpfc_rport_data *rdata = lpfc_cmd->rdata; struct lpfc_nodelist *pnode = rdata->pnode; struct scsi_cmnd *cmd = lpfc_cmd->pCmd; - uint32_t vpi = (lpfc_cmd->cur_iocbq.vport - ? lpfc_cmd->cur_iocbq.vport->vpi - : 0); int result; struct scsi_device *sdev, *tmp_sdev; int depth = 0; @@ -564,15 +555,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, else if (lpfc_cmd->status >= IOSTAT_CNT) lpfc_cmd->status = IOSTAT_DEFAULT; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d (%d):0729 FCP cmd x%x failed <%d/%d> " - "status: x%x result: x%x Data: x%x x%x\n", - phba->brd_no, vpi, cmd->cmnd[0], - cmd->device ? cmd->device->id : 0xffff, - cmd->device ? cmd->device->lun : 0xffff, - lpfc_cmd->status, lpfc_cmd->result, - pIocbOut->iocb.ulpContext, - lpfc_cmd->cur_iocbq.iocb.ulpIoTag); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0729 FCP cmd x%x failed <%d/%d> " + "status: x%x result: x%x Data: x%x x%x\n", + cmd->cmnd[0], + cmd->device ? cmd->device->id : 0xffff, + cmd->device ? cmd->device->lun : 0xffff, + lpfc_cmd->status, lpfc_cmd->result, + pIocbOut->iocb.ulpContext, + lpfc_cmd->cur_iocbq.iocb.ulpIoTag); switch (lpfc_cmd->status) { case IOSTAT_FCP_RSP_ERROR: @@ -605,13 +596,12 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, if (cmd->result || lpfc_cmd->fcp_rsp->rspSnsLen) { uint32_t *lp = (uint32_t *)cmd->sense_buffer; - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d (%d):0710 Iodone <%d/%d> cmd %p, error " - "x%x SNS x%x x%x Data: x%x x%x\n", - phba->brd_no, vpi, cmd->device->id, - cmd->device->lun, cmd, cmd->result, - *lp, *(lp + 3), cmd->retries, - scsi_get_resid(cmd)); + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, + "0710 Iodone <%d/%d> cmd %p, error " + "x%x SNS x%x x%x Data: x%x x%x\n", + cmd->device->id, cmd->device->lun, cmd, + cmd->result, *lp, *(lp + 3), cmd->retries, + scsi_get_resid(cmd)); } result = cmd->result; @@ -675,10 +665,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, depth = sdev->host->cmd_per_lun; if (depth) { - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d (%d):0711 detected queue full - " - "lun queue depth adjusted to %d.\n", - phba->brd_no, vpi, depth); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0711 detected queue full - lun queue " + "depth adjusted to %d.\n", depth); } } @@ -848,12 +837,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, return FAILED; /* Issue Target Reset to TGT */ - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d (%d):0702 Issue Target Reset to TGT %d " - "Data: x%x x%x\n", - phba->brd_no, vport->vpi, tgt_id, - rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, + "0702 Issue Target Reset to TGT %d Data: x%x x%x\n", + tgt_id, rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag); ret = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); @@ -960,10 +946,9 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) if (lpfc_cmd == NULL) { lpfc_adjust_queue_depth(phba); - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d (%d):0707 driver's buffer pool is empty, " - "IO busied\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, + "0707 driver's buffer pool is empty, " + "IO busied\n"); goto out_host_busy; } @@ -1104,22 +1089,19 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) if (lpfc_cmd->pCmd == cmnd) { ret = FAILED; - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0748 abort handler timed out waiting " - "for abort to complete: ret %#x, ID %d, " - "LUN %d, snum %#lx\n", - phba->brd_no, vport->vpi, ret, - cmnd->device->id, cmnd->device->lun, - cmnd->serial_number); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0748 abort handler timed out waiting " + "for abort to complete: ret %#x, ID %d, " + "LUN %d, snum %#lx\n", + ret, cmnd->device->id, cmnd->device->lun, + cmnd->serial_number); } out: - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d (%d):0749 SCSI Layer I/O Abort Request " - "Status x%x ID %d LUN %d snum %#lx\n", - phba->brd_no, vport->vpi, ret, cmnd->device->id, - cmnd->device->lun, cmnd->serial_number); - + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0749 SCSI Layer I/O Abort Request Status x%x ID %d " + "LUN %d snum %#lx\n", ret, cmnd->device->id, + cmnd->device->lun, cmnd->serial_number); return ret; } @@ -1154,11 +1136,10 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) rdata = cmnd->device->hostdata; if (!rdata || (loopcnt > ((vport->cfg_devloss_tmo * 2) + 1))){ - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0721 LUN Reset rport " - "failure: cnt x%x rdata x%p\n", - phba->brd_no, vport->vpi, - loopcnt, rdata); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0721 LUN Reset rport " + "failure: cnt x%x rdata x%p\n", + loopcnt, rdata); goto out; } pnode = rdata->pnode; @@ -1188,12 +1169,10 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) if (iocbqrsp == NULL) goto out_free_scsi_buf; - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d (%d):0703 Issue target reset to TGT %d LUN %d " - "rpi x%x nlp_flag x%x\n", - phba->brd_no, vport->vpi, cmnd->device->id, - cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); - + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, + "0703 Issue target reset to TGT %d LUN %d " + "rpi x%x nlp_flag x%x\n", cmnd->device->id, + cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); iocb_status = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); @@ -1239,10 +1218,9 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) } if (cnt) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0719 device reset I/O flush failure: " - "cnt x%x\n", - phba->brd_no, vport->vpi, cnt); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0719 device reset I/O flush failure: " + "cnt x%x\n", cnt); ret = FAILED; } @@ -1250,12 +1228,11 @@ out_free_scsi_buf: if (iocb_status != IOCB_TIMEDOUT) { lpfc_release_scsi_buf(phba, lpfc_cmd); } - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0713 SCSI layer issued device reset (%d, %d) " - "return x%x status x%x result x%x\n", - phba->brd_no, vport->vpi, cmnd->device->id, - cmnd->device->lun, ret, cmd_status, cmd_result); - + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0713 SCSI layer issued device reset (%d, %d) " + "return x%x status x%x result x%x\n", + cmnd->device->id, cmnd->device->lun, ret, + cmd_status, cmd_result); out: return ret; } @@ -1306,10 +1283,9 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) cmnd->device->lun, ndlp->rport->dd_data); if (ret != SUCCESS) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0700 Bus Reset on target %d " - "failed\n", - phba->brd_no, vport->vpi, i); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0700 Bus Reset on target %d failed\n", + i); err_count++; break; } @@ -1347,16 +1323,14 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) } if (cnt) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0715 Bus Reset I/O flush failure: " - "cnt x%x left x%x\n", - phba->brd_no, vport->vpi, cnt, i); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0715 Bus Reset I/O flush failure: " + "cnt x%x left x%x\n", cnt, i); ret = FAILED; } - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0714 SCSI layer issued Bus Reset Data: x%x\n", - phba->brd_no, vport->vpi, ret); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0714 SCSI layer issued Bus Reset Data: x%x\n", ret); out: return ret; } @@ -1389,32 +1363,28 @@ lpfc_slave_alloc(struct scsi_device *sdev) /* Allow some exchanges to be available always to complete discovery */ if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) { - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d (%d):0704 At limitation of %d " - "preallocated command buffers\n", - phba->brd_no, vport->vpi, total); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0704 At limitation of %d preallocated " + "command buffers\n", total); return 0; - /* Allow some exchanges to be available always to complete discovery */ } else if (total + num_to_alloc > phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) { - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d (%d):0705 Allocation request of %d " - "command buffers will exceed max of %d. " - "Reducing allocation request to %d.\n", - phba->brd_no, vport->vpi, num_to_alloc, - phba->cfg_hba_queue_depth, - (phba->cfg_hba_queue_depth - total)); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0705 Allocation request of %d " + "command buffers will exceed max of %d. " + "Reducing allocation request to %d.\n", + num_to_alloc, phba->cfg_hba_queue_depth, + (phba->cfg_hba_queue_depth - total)); num_to_alloc = phba->cfg_hba_queue_depth - total; } for (i = 0; i < num_to_alloc; i++) { scsi_buf = lpfc_new_scsi_buf(vport); if (!scsi_buf) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d (%d):0706 Failed to allocate " - "command buffer\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0706 Failed to allocate " + "command buffer\n"); break; } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 14fe6b000b59..2da75d85de84 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -49,9 +49,8 @@ lpfc_printf_log(phba, \ KERN_INFO, \ LOG_MBOX | LOG_SLI, \ - "%d (%d):0311 Mailbox command x%x cannot " \ + "(%d):0311 Mailbox command x%x cannot " \ "issue Data: x%x x%x x%x\n", \ - phba->brd_no, \ pmbox->vport ? pmbox->vport->vpi : 0, \ pmbox->mb.mbxCommand, \ phba->pport->port_state, \ @@ -231,13 +230,11 @@ lpfc_sli_ring_map(struct lpfc_hba *phba) rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0446 Adapter failed to init (%d), " + "0446 Adapter failed to init (%d), " "mbxCmd x%x CFG_RING, mbxStatus x%x, " "ring %d\n", - phba->brd_no, rc, - pmbox->mbxCommand, - pmbox->mbxStatus, - i); + rc, pmbox->mbxCommand, + pmbox->mbxStatus, i); phba->link_state = LPFC_HBA_ERROR; ret = -ENXIO; break; @@ -296,9 +293,9 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) if (unlikely(pring->local_getidx >= max_cmd_idx)) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0315 Ring %d issue: portCmdGet %d " + "0315 Ring %d issue: portCmdGet %d " "is bigger then cmd ring %d\n", - phba->brd_no, pring->ringno, + pring->ringno, pring->local_getidx, max_cmd_idx); phba->link_state = LPFC_HBA_ERROR; @@ -380,8 +377,8 @@ lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_ERR,LOG_SLI, - "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n", - phba->brd_no, psli->last_iotag); + "0318 Failed to allocate IOTAG.last IOTAG is %d\n", + psli->last_iotag); return 0; } @@ -535,10 +532,9 @@ lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) if (unlikely(hbqp->local_hbqGetIdx >= hbqp->entry_count)) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, - "%d:1802 HBQ %d: local_hbqGetIdx " + "1802 HBQ %d: local_hbqGetIdx " "%u is > than hbqp->entry_count %u\n", - phba->brd_no, hbqno, - hbqp->local_hbqGetIdx, + hbqno, hbqp->local_hbqGetIdx, hbqp->entry_count); phba->link_state = LPFC_HBA_ERROR; @@ -666,9 +662,8 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) } } lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, - "%d:1803 Bad hbq tag. Data: x%x x%x\n", - phba->brd_no, tag, - lpfc_hbq_defs[tag >> 16]->buffer_count); + "1803 Bad hbq tag. Data: x%x x%x\n", + tag, lpfc_hbq_defs[tag >> 16]->buffer_count); return NULL; } @@ -845,12 +840,10 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) */ if (lpfc_sli_chk_mbx_command(pmbox->mbxCommand) == MBX_SHUTDOWN) { - /* Unknow mailbox command compl */ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "%d (%d):0323 Unknown Mailbox command " + "(%d):0323 Unknown Mailbox command " "%x Cmpl\n", - phba->brd_no, pmb->vport ? pmb->vport->vpi : 0, pmbox->mbxCommand); phba->link_state = LPFC_HBA_ERROR; @@ -865,10 +858,9 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) /* Mbox cmd cmpl error - RETRYing */ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, - "%d (%d):0305 Mbox cmd cmpl " + "(%d):0305 Mbox cmd cmpl " "error - RETRYing Data: x%x " "x%x x%x x%x\n", - phba->brd_no, pmb->vport ? pmb->vport->vpi :0, pmbox->mbxCommand, pmbox->mbxStatus, @@ -887,9 +879,8 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) /* Mailbox cmd Cmpl */ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, - "%d (%d):0307 Mailbox cmd x%x Cmpl x%p " + "(%d):0307 Mailbox cmd x%x Cmpl x%p " "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x\n", - phba->brd_no, pmb->vport ? pmb->vport->vpi : 0, pmbox->mbxCommand, pmb->mbox_cmpl, @@ -1004,12 +995,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* Ring handler: unexpected Rctl Type received */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "%d:0313 Ring %d handler: unexpected Rctl x%x " + "0313 Ring %d handler: unexpected Rctl x%x " "Type x%x received\n", - phba->brd_no, - pring->ringno, - Rctl, - Type); + pring->ringno, Rctl, Type); } return 1; } @@ -1032,10 +1020,9 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, } lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0317 iotag x%x is out off " + "0317 iotag x%x is out off " "range: max iotag x%x wd0 x%x\n", - phba->brd_no, iotag, - phba->sli.last_iotag, + iotag, phba->sli.last_iotag, *(((uint32_t *) &prspiocb->iocb) + 7)); return NULL; } @@ -1083,18 +1070,16 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, * Ring handler: unexpected completion IoTag * */ - lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "%d (%d):0322 Ring %d handler: " - "unexpected completion IoTag x%x " - "Data: x%x x%x x%x x%x\n", - phba->brd_no, - cmdiocbp->vport->vpi, - pring->ringno, - saveq->iocb.ulpIoTag, - saveq->iocb.ulpStatus, - saveq->iocb.un.ulpWord[4], - saveq->iocb.ulpCommand, - saveq->iocb.ulpContext); + lpfc_printf_vlog(cmdiocbp->vport, KERN_WARNING, LOG_SLI, + "0322 Ring %d handler: " + "unexpected completion IoTag x%x " + "Data: x%x x%x x%x x%x\n", + pring->ringno, + saveq->iocb.ulpIoTag, + saveq->iocb.ulpStatus, + saveq->iocb.un.ulpWord[4], + saveq->iocb.ulpCommand, + saveq->iocb.ulpContext); } } @@ -1112,10 +1097,9 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) * rsp ring */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0312 Ring %d handler: portRspPut %d " + "0312 Ring %d handler: portRspPut %d " "is bigger then rsp ring %d\n", - phba->brd_no, pring->ringno, - le32_to_cpu(pgp->rspPutInx), + pring->ringno, le32_to_cpu(pgp->rspPutInx), pring->numRiocb); phba->link_state = LPFC_HBA_ERROR; @@ -1185,9 +1169,9 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) if (unlikely(irsp->ulpStatus)) { /* Rsp ring error: IOCB */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "%d:0326 Rsp Ring %d error: IOCB Data: " + "0326 Rsp Ring %d error: IOCB Data: " "x%x x%x x%x x%x x%x x%x x%x x%x\n", - phba->brd_no, pring->ringno, + pring->ringno, irsp->un.ulpWord[0], irsp->un.ulpWord[1], irsp->un.ulpWord[2], @@ -1207,9 +1191,9 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) */ if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0314 IOCB cmd 0x%x" - " processed. Skipping" - " completion", phba->brd_no, + "0314 IOCB cmd 0x%x " + "processed. Skipping " + "completion", irsp->ulpCommand); break; } @@ -1234,10 +1218,9 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) } else { /* Unknown IOCB command */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0321 Unknown IOCB command " + "0321 Unknown IOCB command " "Data: x%x, x%x x%x x%x x%x\n", - phba->brd_no, type, - irsp->ulpCommand, + type, irsp->ulpCommand, irsp->ulpStatus, irsp->ulpIoTag, irsp->ulpContext); @@ -1361,9 +1344,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, /* Rsp ring error: IOCB */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "%d:0336 Rsp Ring %d error: IOCB Data: " + "0336 Rsp Ring %d error: IOCB Data: " "x%x x%x x%x x%x x%x x%x x%x x%x\n", - phba->brd_no, pring->ringno, + pring->ringno, irsp->un.ulpWord[0], irsp->un.ulpWord[1], irsp->un.ulpWord[2], @@ -1383,10 +1366,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, */ if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0333 IOCB cmd 0x%x" + "0333 IOCB cmd 0x%x" " processed. Skipping" " completion\n", - phba->brd_no, irsp->ulpCommand); break; } @@ -1423,10 +1405,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, } else { /* Unknown IOCB command */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0334 Unknown IOCB command " + "0334 Unknown IOCB command " "Data: x%x, x%x x%x x%x x%x\n", - phba->brd_no, type, - irsp->ulpCommand, + type, irsp->ulpCommand, irsp->ulpStatus, irsp->ulpIoTag, irsp->ulpContext); @@ -1504,10 +1485,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, * rsp ring */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0303 Ring %d handler: portRspPut %d " + "0303 Ring %d handler: portRspPut %d " "is bigger then rsp ring %d\n", - phba->brd_no, pring->ringno, portRspPut, - portRspMax); + pring->ringno, portRspPut, portRspMax); phba->link_state = LPFC_HBA_ERROR; spin_unlock_irqrestore(&phba->hbalock, iflag); @@ -1596,13 +1576,12 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, if (irsp->ulpStatus) { /* Rsp ring error: IOCB */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "%d:0328 Rsp Ring %d error: " + "0328 Rsp Ring %d error: " "IOCB Data: " "x%x x%x x%x x%x " "x%x x%x x%x x%x " "x%x x%x x%x x%x " "x%x x%x x%x x%x\n", - phba->brd_no, pring->ringno, irsp->un.ulpWord[0], irsp->un.ulpWord[1], @@ -1677,10 +1656,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, } else { /* Unknown IOCB command */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0335 Unknown IOCB " + "0335 Unknown IOCB " "command Data: x%x " "x%x x%x x%x\n", - phba->brd_no, irsp->ulpCommand, irsp->ulpStatus, irsp->ulpIoTag, @@ -1908,8 +1886,8 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) /* Kill HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0329 Kill HBA Data: x%x x%x\n", - phba->brd_no, phba->pport->port_state, psli->sli_flag); + "0329 Kill HBA Data: x%x x%x\n", + phba->pport->port_state, psli->sli_flag); if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) == 0) @@ -1982,7 +1960,7 @@ lpfc_sli_brdreset(struct lpfc_hba *phba) /* Reset HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no, + "0325 Reset HBA Data: x%x x%x\n", phba->pport->port_state, psli->sli_flag); /* perform board reset */ @@ -2037,7 +2015,7 @@ lpfc_sli_brdrestart(struct lpfc_hba *phba) /* Restart HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0337 Restart HBA Data: x%x x%x\n", phba->brd_no, + "0337 Restart HBA Data: x%x x%x\n", phba->pport->port_state, psli->sli_flag); word0 = 0; @@ -2102,9 +2080,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) /* Adapter failed to init, timeout, status reg */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0436 Adapter failed to init, " - "timeout, status reg x%x\n", - phba->brd_no, status); + "0436 Adapter failed to init, " + "timeout, status reg x%x\n", status); phba->link_state = LPFC_HBA_ERROR; return -ETIMEDOUT; } @@ -2115,10 +2092,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) /* Adapter failed to init, chipset, status reg */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0437 Adapter failed to init, " - "chipset, status reg x%x\n", - phba->brd_no, - status); + "0437 Adapter failed to init, " + "chipset, status reg x%x\n", status); phba->link_state = LPFC_HBA_ERROR; return -EIO; } @@ -2145,10 +2120,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) /* ERROR: During chipset initialization */ /* Adapter failed to init, chipset, status reg */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0438 Adapter failed to init, chipset, " - "status reg x%x\n", - phba->brd_no, - status); + "0438 Adapter failed to init, chipset, " + "status reg x%x\n", status); phba->link_state = LPFC_HBA_ERROR; return -EIO; } @@ -2226,9 +2199,9 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba) lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, - "%d:1805 Adapter failed to init. " + "1805 Adapter failed to init. " "Data: x%x x%x x%x\n", - phba->brd_no, pmbox->mbxCommand, + pmbox->mbxCommand, pmbox->mbxStatus, hbqno); phba->link_state = LPFC_HBA_ERROR; @@ -2295,10 +2268,9 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode) rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0442 Adapter failed to init, mbxCmd x%x " + "0442 Adapter failed to init, mbxCmd x%x " "CONFIG_PORT, mbxStatus x%x Data: x%x\n", - phba->brd_no, pmb->mb.mbxCommand, - pmb->mb.mbxStatus, 0); + pmb->mb.mbxCommand, pmb->mb.mbxStatus, 0); spin_lock_irq(&phba->hbalock); phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(&phba->hbalock); @@ -2339,9 +2311,9 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) case 2: if (phba->cfg_npiv_enable) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, - "%d:1824 NPIV enabled: Override lpfc_sli_mode " + "1824 NPIV enabled: Override lpfc_sli_mode " "parameter (%d) to auto (0).\n", - phba->brd_no, lpfc_sli_mode); + lpfc_sli_mode); break; } mode = 2; @@ -2351,9 +2323,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) break; default: lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, - "%d:1819 Unrecognized lpfc_sli_mode " - "parameter: %d.\n", - phba->brd_no, lpfc_sli_mode); + "1819 Unrecognized lpfc_sli_mode " + "parameter: %d.\n", lpfc_sli_mode); break; } @@ -2361,9 +2332,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) rc = lpfc_do_config_port(phba, mode); if (rc && lpfc_sli_mode == 3) lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, - "%d:1820 Unable to select SLI-3. " - "Not supported by adapter.\n", - phba->brd_no); + "1820 Unable to select SLI-3. " + "Not supported by adapter.\n"); if (rc && mode != 2) rc = lpfc_do_config_port(phba, 2); if (rc) @@ -2382,8 +2352,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) } lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "%d:0444 Firmware in SLI %x mode. Max_vpi %d\n", - phba->brd_no, phba->sli_rev, phba->max_vpi); + "0444 Firmware in SLI %x mode. Max_vpi %d\n", + phba->sli_rev, phba->max_vpi); rc = lpfc_sli_ring_map(phba); if (rc) @@ -2408,8 +2378,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) lpfc_sli_hba_setup_error: phba->link_state = LPFC_HBA_ERROR; lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "%d:0445 Firmware initialization failed\n", - phba->brd_no); + "0445 Firmware initialization failed\n"); return rc; } @@ -2461,9 +2430,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) /* Mbox cmd timeout */ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "%d:0310 Mailbox command x%x timeout Data: x%x x%x " - "x%p\n", - phba->brd_no, + "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n", mb->mbxCommand, phba->pport->port_state, phba->sli.sli_flag, @@ -2486,8 +2453,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) lpfc_sli_abort_iocb_ring(phba, pring); lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "%d:0316 Resetting board due to mailbox timeout\n", - phba->brd_no); + "0316 Resetting board due to mailbox timeout\n"); /* * lpfc_offline calls lpfc_sli_hba_down which will clean up * on oustanding mailbox commands. @@ -2518,8 +2484,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) if(!pmbox->vport) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT, - "%d:1806 Mbox x%x failed. No vport\n", - phba->brd_no, + "1806 Mbox x%x failed. No vport\n", pmbox->mb.mbxCommand); dump_stack(); return MBXERR_ERROR; @@ -2596,9 +2561,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) /* Mbox cmd issue - BUSY */ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, - "%d (%d):0308 Mbox cmd issue - BUSY Data: " + "(%d):0308 Mbox cmd issue - BUSY Data: " "x%x x%x x%x x%x\n", - phba->brd_no, pmbox->vport ? pmbox->vport->vpi : 0xffffff, mb->mbxCommand, phba->pport->port_state, psli->sli_flag, flag); @@ -2660,9 +2624,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) /* Mailbox cmd issue */ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, - "%d (%d):0309 Mailbox cmd x%x issue Data: x%x x%x " + "(%d):0309 Mailbox cmd x%x issue Data: x%x x%x " "x%x\n", - phba->brd_no, pmbox->vport ? pmbox->vport->vpi : 0, + pmbox->vport ? pmbox->vport->vpi : 0, mb->mbxCommand, phba->pport->port_state, psli->sli_flag, flag); @@ -2864,8 +2828,7 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN)) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, - "%d:1807 IOCB x%x failed. No vport\n", - phba->brd_no, + "1807 IOCB x%x failed. No vport\n", piocb->iocb.ulpCommand); dump_stack(); return IOCB_ERROR; @@ -3096,11 +3059,10 @@ lpfc_sli_setup(struct lpfc_hba *phba) } if (totiocbsize > MAX_SLIM_IOCB_SIZE) { /* Too many cmd / rsp ring entries in SLI2 SLIM */ - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0462 Too many cmd / rsp ring entries in " - "SLI2 SLIM Data: x%x x%lx\n", - phba->brd_no, totiocbsize, - (unsigned long) MAX_SLIM_IOCB_SIZE); + printk(KERN_ERR "%d:0462 Too many cmd / rsp ring entries in " + "SLI2 SLIM Data: x%x x%lx\n", + phba->brd_no, totiocbsize, + (unsigned long) MAX_SLIM_IOCB_SIZE); } if (phba->cfg_multi_ring_support == 2) lpfc_extra_ring_setup(phba); @@ -3321,9 +3283,9 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "%d:0410 Cannot find virtual addr for mapped buf on " + "0410 Cannot find virtual addr for mapped buf on " "ring %d Data x%llx x%p x%p x%x\n", - phba->brd_no, pring->ringno, (unsigned long long)phys, + pring->ringno, (unsigned long long)phys, slp->next, slp->prev, pring->postbufq_cnt); return NULL; } @@ -3348,12 +3310,11 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, abort_iocb = phba->sli.iocbq_lookup[abort_iotag]; lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_SLI, - "%d:0327 Cannot abort els iocb %p " + "0327 Cannot abort els iocb %p " "with tag %x context %x, abort status %x, " "abort code %x\n", - phba->brd_no, abort_iocb, abort_iotag, - abort_context, irsp->ulpStatus, - irsp->un.ulpWord[4]); + abort_iocb, abort_iotag, abort_context, + irsp->ulpStatus, irsp->un.ulpWord[4]); /* * make sure we have the right iocbq before taking it @@ -3387,9 +3348,9 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* ELS cmd tag completes */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d (X):0133 Ignoring ELS cmd tag x%x completion Data: " + "0133 Ignoring ELS cmd tag x%x completion Data: " "x%x x%x x%x\n", - phba->brd_no, irsp->ulpIoTag, irsp->ulpStatus, + irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout); if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) lpfc_ct_free_iocb(phba, cmdiocb); @@ -3455,12 +3416,11 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, abtsiocbp->iocb_cmpl = lpfc_sli_abort_els_cmpl; - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d (%d):0339 Abort xri x%x, original iotag x%x, " - "abort cmd iotag x%x\n", - phba->brd_no, vport->vpi, - iabt->un.acxri.abortContextTag, - iabt->un.acxri.abortIoTag, abtsiocbp->iotag); + lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, + "0339 Abort xri x%x, original iotag x%x, " + "abort cmd iotag x%x\n", + iabt->un.acxri.abortContextTag, + iabt->un.acxri.abortIoTag, abtsiocbp->iotag); retval = __lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); abort_iotag_exit: @@ -3663,25 +3623,23 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, if (piocb->iocb_flag & LPFC_IO_WAKE) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0331 IOCB wake signaled\n", - phba->brd_no); + "0331 IOCB wake signaled\n"); } else if (timeleft == 0) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0338 IOCB wait timeout error - no " - "wake response Data x%x\n", - phba->brd_no, timeout); + "0338 IOCB wait timeout error - no " + "wake response Data x%x\n", timeout); retval = IOCB_TIMEDOUT; } else { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0330 IOCB wake NOT set, " - "Data x%x x%lx\n", phba->brd_no, + "0330 IOCB wake NOT set, " + "Data x%x x%lx\n", timeout, (timeleft / jiffies)); retval = IOCB_TIMEDOUT; } } else { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0332 IOCB wait issue failed, Data x%x\n", - phba->brd_no, retval); + ":0332 IOCB wait issue failed, Data x%x\n", + retval); retval = IOCB_ERROR; } @@ -3932,12 +3890,10 @@ lpfc_intr_handler(int irq, void *dev_id) */ lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, - "%d (%d):0304 Stray Mailbox " + "(%d):0304 Stray Mailbox " "Interrupt mbxCommand x%x " "mbxStatus x%x\n", - phba->brd_no, - (vport - ? vport->vpi : 0), + (vport ? vport->vpi : 0), pmbox->mbxCommand, pmbox->mbxStatus); } diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 70e1bc34fd48..77067d17c39d 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -125,11 +125,10 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) pmb->vport = vport; rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, - "%d (%d):1818 VPort failed init, mbxCmd x%x " - "READ_SPARM mbxStatus x%x, rc = x%x\n", - phba->brd_no, vport->vpi, - mb->mbxCommand, mb->mbxStatus, rc); + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT, + "1818 VPort failed init, mbxCmd x%x " + "READ_SPARM mbxStatus x%x, rc = x%x\n", + mb->mbxCommand, mb->mbxStatus, rc); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); if (rc != MBX_TIMEOUT) @@ -162,9 +161,9 @@ lpfc_valid_wwn_format(struct lpfc_hba *phba, struct lpfc_name *wwn, return 1; lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1822 Invalid %s: %02x:%02x:%02x:%02x:" + "1822 Invalid %s: %02x:%02x:%02x:%02x:" "%02x:%02x:%02x:%02x\n", - phba->brd_no, name_type, + name_type, wwn->u.wwn[0], wwn->u.wwn[1], wwn->u.wwn[2], wwn->u.wwn[3], wwn->u.wwn[4], wwn->u.wwn[5], @@ -209,9 +208,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) if ((phba->sli_rev < 3) || !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1808 Create VPORT failed: " + "1808 Create VPORT failed: " "NPIV is not enabled: SLImode:%d\n", - phba->brd_no, phba->sli_rev); + phba->sli_rev); rc = VPORT_INVAL; goto error_out; } @@ -219,9 +218,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) vpi = lpfc_alloc_vpi(phba); if (vpi == 0) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1809 Create VPORT failed: " + "1809 Create VPORT failed: " "Max VPORTs (%d) exceeded\n", - phba->brd_no, phba->max_vpi); + phba->max_vpi); rc = VPORT_NORESOURCES; goto error_out; } @@ -230,8 +229,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) /* Assign an unused board number */ if ((instance = lpfc_get_instance()) < 0) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1810 Create VPORT failed: Cannot get " - "instance number\n", phba->brd_no); + "1810 Create VPORT failed: Cannot get " + "instance number\n"); lpfc_free_vpi(phba, vpi); rc = VPORT_NORESOURCES; goto error_out; @@ -240,8 +239,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) vport = lpfc_create_port(phba, instance, &fc_vport->dev); if (!vport) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1811 Create VPORT failed: vpi x%x\n", - phba->brd_no, vpi); + "1811 Create VPORT failed: vpi x%x\n", vpi); lpfc_free_vpi(phba, vpi); rc = VPORT_NORESOURCES; goto error_out; @@ -251,10 +249,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) lpfc_debugfs_initialize(vport); if (lpfc_vport_sparm(phba, vport)) { - lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1813 Create VPORT failed: vpi:%d " - "Cannot get sparam\n", - phba->brd_no, vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1813 Create VPORT failed. " + "Cannot get sparam\n"); lpfc_free_vpi(phba, vpi); destroy_port(vport); rc = VPORT_NORESOURCES; @@ -274,10 +271,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) if (!lpfc_valid_wwn_format(phba, &vport->fc_sparam.nodeName, "WWNN") || !lpfc_valid_wwn_format(phba, &vport->fc_sparam.portName, "WWPN")) { - lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1821 Create VPORT failed: vpi:%d " - "Invalid WWN format\n", - phba->brd_no, vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1821 Create VPORT failed. " + "Invalid WWN format\n"); lpfc_free_vpi(phba, vpi); destroy_port(vport); rc = VPORT_INVAL; @@ -285,10 +281,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) } if (!lpfc_unique_wwpn(phba, vport)) { - lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1823 Create VPORT failed: vpi:%d " - "Duplicate WWN on HBA\n", - phba->brd_no, vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1823 Create VPORT failed. " + "Duplicate WWN on HBA\n"); lpfc_free_vpi(phba, vpi); destroy_port(vport); rc = VPORT_INVAL; @@ -320,10 +315,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) lpfc_initial_fdisc(vport); } else { lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0262 No NPIV Fabric " - "support\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0262 No NPIV Fabric support\n"); } } else { lpfc_vport_set_state(vport, FC_VPORT_FAILED); @@ -409,10 +402,8 @@ enable_vport(struct fc_vport *fc_vport) lpfc_initial_fdisc(vport); } else { lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP); - lpfc_printf_log(phba, KERN_ERR, LOG_ELS, - "%d (%d):0264 No NPIV Fabric " - "support\n", - phba->brd_no, vport->vpi); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0264 No NPIV Fabric support\n"); } } else { lpfc_vport_set_state(vport, FC_VPORT_FAILED); @@ -462,9 +453,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport) return VPORT_INVAL; if (vport->port_type == LPFC_PHYSICAL_PORT) { - lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "%d:1812 vport_delete failed: Cannot delete " - "physical host\n", phba->brd_no); + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1812 vport_delete failed: Cannot delete " + "physical host\n"); goto out; } @@ -544,8 +535,12 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) return NULL; spin_lock_irq(&phba->hbalock); list_for_each_entry(port_iterator, &phba->port_list, listentry) { - if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) + if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) { + lpfc_printf_vlog(port_iterator, KERN_ERR, LOG_VPORT, + "1801 Create vport work array FAILED: " + "cannot do scsi_host_get\n"); continue; + } vports[index++] = port_iterator; } spin_unlock_irq(&phba->hbalock); -- cgit v1.2.3 From 78b2d852a88cd2a55e3ab632109de045d58b83e3 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:10:21 -0400 Subject: [SCSI] lpfc 8.2.2 : Miscellaneous management and logging mods - Remove the "management_version" sysfs parameter (was unused) - Add HBQ information to lpfc debugfs - Change lpfc_npiv_enable name back to lpfc_enable_npiv (internal stds) - Remove "issue_lip" attribute from the vports transport template Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 3 +- drivers/scsi/lpfc/lpfc_attr.c | 17 +---- drivers/scsi/lpfc/lpfc_debugfs.c | 159 ++++++++++++++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_mbox.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 6 +- drivers/scsi/lpfc/lpfc_version.h | 2 - 7 files changed, 168 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 5a76d2b4253b..a6dd13e05ab2 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -430,7 +430,7 @@ struct lpfc_hba { /* HBA Config Parameters */ uint32_t cfg_ack0; - uint32_t cfg_npiv_enable; + uint32_t cfg_enable_npiv; uint32_t cfg_topology; uint32_t cfg_link_speed; uint32_t cfg_cr_delay; @@ -551,6 +551,7 @@ struct lpfc_hba { #ifdef CONFIG_LPFC_DEBUG_FS struct dentry *hba_debugfs_root; atomic_t debugfs_vport_count; + struct dentry *debug_hbqinfo; struct dentry *debug_dumpslim; struct dentry *debug_slow_ring_trc; struct lpfc_debugfs_trc *slow_ring_trc; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index c1cedc3d1b70..0a7f06ba77c0 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -67,12 +67,6 @@ lpfc_drvr_version_show(struct class_device *cdev, char *buf) return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n"); } -static ssize_t -management_version_show(struct class_device *cdev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n"); -} - static ssize_t lpfc_info_show(struct class_device *cdev, char *buf) { @@ -904,8 +898,6 @@ static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO, static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL); static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL); -static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, - NULL); static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, lpfc_board_mode_show, lpfc_board_mode_store); static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); @@ -1110,7 +1102,7 @@ MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:" " 2 - select SLI-2 even on SLI-3 capable HBAs," " 3 - select SLI-3"); -LPFC_ATTR_R(npiv_enable, 0, 0, 1, "Enable NPIV functionality"); +LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality"); /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear @@ -1530,9 +1522,8 @@ struct class_device_attribute *lpfc_hba_attrs[] = { &class_device_attr_lpfc_multi_ring_type, &class_device_attr_lpfc_fdmi_on, &class_device_attr_lpfc_max_luns, - &class_device_attr_lpfc_npiv_enable, + &class_device_attr_lpfc_enable_npiv, &class_device_attr_nport_evt_cnt, - &class_device_attr_management_version, &class_device_attr_board_mode, &class_device_attr_max_vpi, &class_device_attr_used_vpi, @@ -1569,7 +1560,6 @@ struct class_device_attribute *lpfc_vport_attrs[] = { &class_device_attr_lpfc_fdmi_on, &class_device_attr_lpfc_max_luns, &class_device_attr_nport_evt_cnt, - &class_device_attr_management_version, &class_device_attr_npiv_info, NULL, }; @@ -2413,7 +2403,6 @@ struct fc_function_template lpfc_vport_transport_functions = { .get_starget_port_name = lpfc_get_starget_port_name, .show_starget_port_name = 1, - .issue_fc_host_lip = lpfc_issue_lip, .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, .terminate_rport_io = lpfc_terminate_rport_io, @@ -2432,7 +2421,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_topology_init(phba, lpfc_topology); lpfc_link_speed_init(phba, lpfc_link_speed); lpfc_poll_tmo_init(phba, lpfc_poll_tmo); - lpfc_npiv_enable_init(phba, lpfc_npiv_enable); + lpfc_enable_npiv_init(phba, lpfc_enable_npiv); lpfc_use_msi_init(phba, lpfc_use_msi); phba->cfg_poll = lpfc_poll; phba->cfg_soft_wwnn = 0L; diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index dc7b858b95fa..f334761d04df 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -101,14 +101,20 @@ MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, #define LPFC_NODELIST_SIZE 8192 #define LPFC_NODELIST_ENTRY_SIZE 120 -/* dump_slim output buffer size */ +/* dumpslim output buffer size */ #define LPFC_DUMPSLIM_SIZE 4096 +/* hbqinfo output buffer size */ +#define LPFC_HBQINFO_SIZE 8192 + struct lpfc_debug { char *buffer; int len; }; +extern struct lpfc_hbq_init *lpfc_hbq_defs[]; +extern int lpfc_sli_hbq_count(void); + atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); unsigned long lpfc_debugfs_start_time = 0L; @@ -196,6 +202,105 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) return len; } +int lpfc_debugfs_last_hbq = -1; + +static int +lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) +{ + int len = 0; + int cnt, i, j, found, posted, low; + uint32_t phys, raw_index, getidx; + struct lpfc_hbq_init *hip; + struct hbq_s *hbqs; + struct lpfc_hbq_entry *hbqe; + struct lpfc_dmabuf *d_buf; + struct hbq_dmabuf *hbq_buf; + + cnt = LPFC_HBQINFO_SIZE; + spin_lock_irq(&phba->hbalock); + + /* toggle between multiple hbqs, if any */ + i = lpfc_sli_hbq_count(); + if (i > 1) { + lpfc_debugfs_last_hbq++; + if (lpfc_debugfs_last_hbq >= i) + lpfc_debugfs_last_hbq = 0; + } + else + lpfc_debugfs_last_hbq = 0; + + i = lpfc_debugfs_last_hbq; + + len += snprintf(buf+len, size-len, "HBQ %d Info\n", i); + + posted = 0; + list_for_each_entry(d_buf, &phba->hbq_buffer_list, list) + posted++; + + hip = lpfc_hbq_defs[i]; + len += snprintf(buf+len, size-len, + "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n", + hip->hbq_index, hip->profile, hip->rn, + hip->buffer_count, hip->init_count, hip->add_count, posted); + + hbqs = &phba->hbqs[i]; + raw_index = phba->hbq_get[i]; + getidx = le32_to_cpu(raw_index); + len += snprintf(buf+len, size-len, + "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", + hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx, + hbqs->local_hbqGetIdx, getidx); + + hbqe = (struct lpfc_hbq_entry *) phba->hbqslimp.virt; + for (j=0; jentry_count; j++) { + len += snprintf(buf+len, size-len, + "%03d: %08x %04x %05x ", j, + hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag); + + i = 0; + found = 0; + + /* First calculate if slot has an associated posted buffer */ + low = hbqs->hbqPutIdx - posted; + if (low >= 0) { + if ((j >= hbqs->hbqPutIdx) || (j < low)) { + len += snprintf(buf+len, size-len, "Unused\n"); + goto skipit; + } + } + else { + if ((j >= hbqs->hbqPutIdx) && + (j < (hbqs->entry_count+low))) { + len += snprintf(buf+len, size-len, "Unused\n"); + goto skipit; + } + } + + /* Get the Buffer info for the posted buffer */ + list_for_each_entry(d_buf, &phba->hbq_buffer_list, list) { + hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); + phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); + if (phys == hbqe->bde.addrLow) { + len += snprintf(buf+len, size-len, + "Buf%d: %p %06x\n", i, + hbq_buf->dbuf.virt, hbq_buf->tag); + found = 1; + break; + } + i++; + } + if (!found) { + len += snprintf(buf+len, size-len, "No DMAinfo?\n"); + } +skipit: + hbqe++; + if (len > LPFC_HBQINFO_SIZE - 54) + break; + } + spin_unlock_irq(&phba->hbalock); + return len; +} + static int lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size) { @@ -491,6 +596,33 @@ out: return rc; } +static int +lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) +{ + struct lpfc_hba *phba = inode->i_private; + struct lpfc_debug *debug; + int rc = -ENOMEM; + + debug = kmalloc(sizeof(*debug), GFP_KERNEL); + if (!debug) + goto out; + + /* Round to page boundry */ + debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL); + if (!debug->buffer) { + kfree(debug); + goto out; + } + + debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer, + LPFC_HBQINFO_SIZE); + file->private_data = debug; + + rc = 0; +out: + return rc; +} + static int lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file) { @@ -604,6 +736,15 @@ static struct file_operations lpfc_debugfs_op_nodelist = { .release = lpfc_debugfs_release, }; +#undef lpfc_debugfs_op_hbqinfo +static struct file_operations lpfc_debugfs_op_hbqinfo = { + .owner = THIS_MODULE, + .open = lpfc_debugfs_hbqinfo_open, + .llseek = lpfc_debugfs_lseek, + .read = lpfc_debugfs_read, + .release = lpfc_debugfs_release, +}; + #undef lpfc_debugfs_op_dumpslim static struct file_operations lpfc_debugfs_op_dumpslim = { .owner = THIS_MODULE, @@ -663,6 +804,18 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) atomic_inc(&lpfc_debugfs_hba_count); atomic_set(&phba->debugfs_vport_count, 0); + /* Setup hbqinfo */ + snprintf(name, sizeof(name), "hbqinfo"); + phba->debug_hbqinfo = + debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, + phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_hbqinfo); + if (!phba->debug_hbqinfo) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "0409 Cannot create debugfs hbqinfo\n"); + goto debug_failed; + } + /* Setup dumpslim */ snprintf(name, sizeof(name), "dumpslim"); phba->debug_dumpslim = @@ -819,6 +972,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) } if (atomic_read(&phba->debugfs_vport_count) == 0) { + if (phba->debug_hbqinfo) { + debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ + phba->debug_hbqinfo = NULL; + } if (phba->debug_dumpslim) { debugfs_remove(phba->debug_dumpslim); /* dumpslim */ phba->debug_dumpslim = NULL; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 55c4e5455a57..f96ab75ba637 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -990,7 +990,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) } } else { if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { - if (phba->max_vpi && phba->cfg_npiv_enable && + if (phba->max_vpi && phba->cfg_enable_npiv && (phba->sli_rev == 3)) phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; } diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 5fa1c6f70a98..09ecdcb63a74 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -688,7 +688,7 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */ - if (phba->max_vpi && phba->cfg_npiv_enable && + if (phba->max_vpi && phba->cfg_enable_npiv && phba->vpd.sli3Feat.cmv) { mb->un.varCfgPort.max_vpi = phba->max_vpi; mb->un.varCfgPort.cmv = 1; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 2da75d85de84..5417bc26f181 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -602,7 +602,7 @@ static struct lpfc_hbq_init lpfc_els_hbq = { .add_count = 5, }; -static struct lpfc_hbq_init *lpfc_hbq_defs[] = { +struct lpfc_hbq_init *lpfc_hbq_defs[] = { &lpfc_els_hbq, }; @@ -2136,7 +2136,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) return 0; } -static int +int lpfc_sli_hbq_count(void) { return ARRAY_SIZE(lpfc_hbq_defs); @@ -2309,7 +2309,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) switch (lpfc_sli_mode) { case 2: - if (phba->cfg_npiv_enable) { + if (phba->cfg_enable_npiv) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, "1824 NPIV enabled: Override lpfc_sli_mode " "parameter (%d) to auto (0).\n", diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index a5bc79eef052..0b4e6fd02679 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -25,5 +25,3 @@ #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ LPFC_DRIVER_VERSION #define LPFC_COPYRIGHT "Copyright(c) 2004-2007 Emulex. All rights reserved." - -#define DFC_API_VERSION "0.0.0" -- cgit v1.2.3 From 51ef4c26891a734bc8416b639ad460a8162926bc Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:10:31 -0400 Subject: [SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes - Fix vport ndlp ref counting errors - Fix use after free of ndlp structure - Use the correct flag to check for LOADING setting. - Fix driver unload bugs (related to shost references) after link down or rscn - Fix up HBQ initialization - Fix port_list locking around driver unload. - Fix references to hostdata as a phba - Fix GFFID type offset to work correctly with big endian structure. - Only call pci_disable_msi if the pci_enable_msi succeeded - Fix vport_delete wait/fail if in discovery - Put a reference on the nameservers ndlp when performing CT traffic. - Remove unbalanced hba unlock. - Fix up HBQ processing - Fix lpfc debugfs discovery trace output for ELS rsp cmpl - Send ADISC when rpi is 0 - Stop FDISC retrying forever - Unable to retrieve correct config parameter for vport - Fix sli_validate_fcp_iocb, sli_sum_iocb, sli_abort_iocb to be vport-aware. - Fix index-out-of-range error in iocb. Spotted by Coverity. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 33 ++++++---- drivers/scsi/lpfc/lpfc_attr.c | 29 +++------ drivers/scsi/lpfc/lpfc_crtn.h | 18 +++--- drivers/scsi/lpfc/lpfc_ct.c | 19 ++++++ drivers/scsi/lpfc/lpfc_debugfs.c | 11 ++-- drivers/scsi/lpfc/lpfc_els.c | 64 +++++++++---------- drivers/scsi/lpfc/lpfc_hbadisc.c | 53 ++++++++------- drivers/scsi/lpfc/lpfc_hw.h | 4 ++ drivers/scsi/lpfc/lpfc_init.c | 86 ++++++++++++++----------- drivers/scsi/lpfc/lpfc_mbox.c | 6 +- drivers/scsi/lpfc/lpfc_mem.c | 32 +++++++--- drivers/scsi/lpfc/lpfc_nportdisc.c | 31 +++++---- drivers/scsi/lpfc/lpfc_scsi.c | 26 +++----- drivers/scsi/lpfc/lpfc_sli.c | 128 +++++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_sli.h | 8 +-- drivers/scsi/lpfc/lpfc_vport.c | 40 ++++++++---- 16 files changed, 342 insertions(+), 246 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index a6dd13e05ab2..c28db0521c01 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -78,6 +78,7 @@ struct lpfc_dma_pool { struct hbq_dmabuf { struct lpfc_dmabuf dbuf; + uint32_t size; uint32_t tag; }; @@ -329,15 +330,7 @@ struct lpfc_vport { #define FC_LOADING 0x1 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ char *vname; /* Application assigned name */ - struct fc_vport *fc_vport; -#ifdef CONFIG_LPFC_DEBUG_FS - struct dentry *debug_disc_trc; - struct dentry *debug_nodelist; - struct dentry *vport_debugfs_root; - struct lpfc_debugfs_trc *disc_trc; - atomic_t disc_trc_cnt; -#endif /* Vport Config Parameters */ uint32_t cfg_scan_down; uint32_t cfg_lun_queue_depth; @@ -353,6 +346,16 @@ struct lpfc_vport { uint32_t cfg_max_luns; uint32_t dev_loss_tmo_changed; + + struct fc_vport *fc_vport; + +#ifdef CONFIG_LPFC_DEBUG_FS + struct dentry *debug_disc_trc; + struct dentry *debug_nodelist; + struct dentry *vport_debugfs_root; + struct lpfc_debugfs_trc *disc_trc; + atomic_t disc_trc_cnt; +#endif }; struct hbq_s { @@ -360,11 +363,19 @@ struct hbq_s { uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */ uint32_t hbqPutIdx; /* HBQ slot to use */ uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */ + void *hbq_virt; /* Virtual ptr to this hbq */ + struct list_head hbq_buffer_list; /* buffers assigned to this HBQ */ + /* Callback for HBQ buffer allocation */ + struct hbq_dmabuf *(*hbq_alloc_buffer) (struct lpfc_hba *); + /* Callback for HBQ buffer free */ + void (*hbq_free_buffer) (struct lpfc_hba *, + struct hbq_dmabuf *); }; -#define LPFC_MAX_HBQS 16 -/* this matches the possition in the lpfc_hbq_defs array */ +#define LPFC_MAX_HBQS 4 +/* this matches the position in the lpfc_hbq_defs array */ #define LPFC_ELS_HBQ 0 +#define LPFC_EXTRA_HBQ 1 struct lpfc_hba { struct lpfc_sli sli; @@ -460,7 +471,6 @@ struct lpfc_hba { wait_queue_head_t *work_wait; struct task_struct *worker_thread; - struct list_head hbq_buffer_list; uint32_t hbq_count; /* Count of configured HBQs */ struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */ @@ -529,6 +539,7 @@ struct lpfc_hba { mempool_t *nlp_mem_pool; struct fc_host_statistics link_stats; + uint8_t using_msi; struct list_head port_list; struct lpfc_vport *pport; /* physical lpfc_vport pointer */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 0a7f06ba77c0..09743d7b6bab 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1027,8 +1027,8 @@ static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ static ssize_t lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)phba->cfg_soft_wwnn); } @@ -1037,8 +1037,8 @@ lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) static ssize_t lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; unsigned int i, j, cnt=count; u8 wwnn[8]; @@ -1153,24 +1153,15 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) static void lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport) { - struct lpfc_vport **vports; struct Scsi_Host *shost; struct lpfc_nodelist *ndlp; - int i; - vports = lpfc_create_vport_work_array(vport->phba); - if (vports != NULL) - for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { - shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(shost->host_lock); - list_for_each_entry(ndlp, &vports[i]->fc_nodes, - nlp_listp) - if (ndlp->rport) - ndlp->rport->dev_loss_tmo = - vport->cfg_devloss_tmo; - spin_unlock_irq(shost->host_lock); - } - lpfc_destroy_vport_work_array(vports); + shost = lpfc_shost_from_vport(vport); + spin_lock_irq(shost->host_lock); + list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) + if (ndlp->rport) + ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo; + spin_unlock_irq(shost->host_lock); } static int diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index ef86345ced6e..b789355fedf5 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -102,7 +102,7 @@ int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t); int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, - struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t); + struct lpfc_nodelist *, LPFC_MBOXQ_t *); int lpfc_els_rsp_reject(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, struct lpfc_nodelist *, LPFC_MBOXQ_t *); int lpfc_els_rsp_adisc_acc(struct lpfc_vport *, struct lpfc_iocbq *, @@ -163,9 +163,11 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); void lpfc_mbox_cmpl_put(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_mbox_tmo_val(struct lpfc_hba *, int); -void lpfc_config_hbq(struct lpfc_hba *, struct lpfc_hbq_init *, uint32_t , - LPFC_MBOXQ_t *); +void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *, + uint32_t , LPFC_MBOXQ_t *); struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t); +struct hbq_dmabuf *lpfc_els_hbq_alloc(struct lpfc_hba *); +void lpfc_els_hbq_free(struct lpfc_hba *, struct hbq_dmabuf *); int lpfc_mem_alloc(struct lpfc_hba *); void lpfc_mem_free(struct lpfc_hba *); @@ -202,6 +204,7 @@ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, struct lpfc_sli_ring *, dma_addr_t); +int lpfc_sli_hbq_count(void); int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *, uint32_t); int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *, uint32_t); void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *); @@ -209,10 +212,9 @@ struct hbq_dmabuf *lpfc_sli_hbqbuf_find(struct lpfc_hba *, uint32_t); int lpfc_sli_hbq_size(void); int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); -int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, - uint64_t, lpfc_ctx_cmd); -int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, - uint64_t, uint32_t, lpfc_ctx_cmd); +int lpfc_sli_sum_iocb(struct lpfc_vport *, uint16_t, uint64_t, lpfc_ctx_cmd); +int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t, + uint64_t, lpfc_ctx_cmd); void lpfc_mbox_timeout(unsigned long); void lpfc_mbox_timeout_handler(struct lpfc_hba *); @@ -236,8 +238,6 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb); -void *lpfc_hbq_alloc(struct lpfc_hba *, int, dma_addr_t *); -void lpfc_hbq_free(struct lpfc_hba *, void *, dma_addr_t); void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *); void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index ad7f33a31567..6f187f3b3048 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -257,6 +257,10 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb) { struct lpfc_dmabuf *buf_ptr; + if (ctiocb->context_un.ndlp) { + lpfc_nlp_put(ctiocb->context_un.ndlp); + ctiocb->context_un.ndlp = NULL; + } if (ctiocb->context1) { buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1; lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); @@ -314,6 +318,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, /* Save for completion so we can release these resources */ geniocb->context1 = (uint8_t *) inp; geniocb->context2 = (uint8_t *) outp; + geniocb->context_un.ndlp = ndlp; /* Fill in payload, bp points to frame payload */ icmd->ulpCommand = CMD_GEN_REQUEST64_CR; @@ -548,8 +553,12 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *bmp; struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; + struct lpfc_nodelist *ndlp; int rc; + /* First save ndlp, before we overwrite it */ + ndlp = cmdiocb->context_un.ndlp; + /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; @@ -674,6 +683,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_disc_start(vport); } out: + cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */ lpfc_ct_free_iocb(phba, cmdiocb); return; } @@ -776,10 +786,14 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; IOCB_t *irsp; struct lpfc_sli_ct_request *CTrsp; + struct lpfc_nodelist *ndlp; int cmdcode, rc; uint8_t retry; uint32_t latt; + /* First save ndlp, before we overwrite it */ + ndlp = cmdiocb->context_un.ndlp; + /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; @@ -828,6 +842,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } out: + cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */ lpfc_ct_free_iocb(phba, cmdiocb); return; } @@ -1066,6 +1081,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, cmpl = lpfc_cmpl_ct_cmd_rff_id; break; } + lpfc_nlp_get(ndlp); if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) { /* On success, The cmpl function will free the buffers */ @@ -1076,6 +1092,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, } rc=6; + lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, bmp->virt, bmp->phys); ns_cmd_free_bmp: kfree(bmp); @@ -1501,10 +1518,12 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) bpl->tus.w = le32_to_cpu(bpl->tus.w); cmpl = lpfc_cmpl_ct_cmd_fdmi; + lpfc_nlp_get(ndlp); if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0)) return 0; + lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, bmp->virt, bmp->phys); fdmi_cmd_free_bmp: kfree(bmp); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index f334761d04df..697a09dccb6f 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -71,7 +71,7 @@ * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in * lpfc_debugfs.h . */ -static int lpfc_debugfs_enable = 0; +static int lpfc_debugfs_enable = 1; module_param(lpfc_debugfs_enable, int, 0); MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); @@ -113,7 +113,6 @@ struct lpfc_debug { }; extern struct lpfc_hbq_init *lpfc_hbq_defs[]; -extern int lpfc_sli_hbq_count(void); atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); unsigned long lpfc_debugfs_start_time = 0L; @@ -233,8 +232,9 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) len += snprintf(buf+len, size-len, "HBQ %d Info\n", i); + hbqs = &phba->hbqs[i]; posted = 0; - list_for_each_entry(d_buf, &phba->hbq_buffer_list, list) + list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) posted++; hip = lpfc_hbq_defs[i]; @@ -243,7 +243,6 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) hip->hbq_index, hip->profile, hip->rn, hip->buffer_count, hip->init_count, hip->add_count, posted); - hbqs = &phba->hbqs[i]; raw_index = phba->hbq_get[i]; getidx = le32_to_cpu(raw_index); len += snprintf(buf+len, size-len, @@ -251,7 +250,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx); - hbqe = (struct lpfc_hbq_entry *) phba->hbqslimp.virt; + hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; for (j=0; jentry_count; j++) { len += snprintf(buf+len, size-len, "%03d: %08x %04x %05x ", j, @@ -277,7 +276,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) } /* Get the Buffer info for the posted buffer */ - list_for_each_entry(d_buf, &phba->hbq_buffer_list, list) { + list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); if (phys == hbqe->bde.addrLow) { diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9365e19696e2..8085900635d4 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -196,9 +196,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, bpl->tus.w = le32_to_cpu(bpl->tus.w); } - /* Save for completion so we can release these resources */ - if (elscmd != ELS_CMD_LS_RJT) - elsiocb->context1 = lpfc_nlp_get(ndlp); + elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->context2 = pcmd; elsiocb->context3 = pbuflist; elsiocb->retry = retry; @@ -1809,8 +1807,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "retrying...\n"); lpfc_mbx_unreg_vpi(vport); retry = 1; - /* Always retry for this case */ - cmdiocb->retry = 0; + /* FDISC retry policy */ + maxretry = 48; + if (cmdiocb->retry >= 32) + delay = 1000; } break; @@ -1886,8 +1886,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, delay = 1000; maxretry = 48; } else if (cmd == ELS_CMD_FDISC) { - /* Always retry for this case */ - cmdiocb->retry = 0; + /* FDISC retry policy */ + maxretry = 48; + if (cmdiocb->retry >= 32) + delay = 1000; } retry = 1; break; @@ -2121,9 +2123,9 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, - "ACC cmpl: status:x%x/x%x did:x%x", + "ELS rsp cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], - irsp->un.rcvels.remoteID); + cmdiocb->iocb.un.elsreq64.remoteID); /* ELS response tag completes */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0110 ELS response tag x%x completes " @@ -2184,7 +2186,7 @@ out: int lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, - LPFC_MBOXQ_t *mbox, uint8_t newnode) + LPFC_MBOXQ_t *mbox) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; @@ -2270,11 +2272,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, default: return 1; } - - if (newnode) { - lpfc_nlp_put(ndlp); - elsiocb->context1 = NULL; - } /* Xmit ELS ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0128 Xmit ELS ACC response tag x%x, XRI: x%x, " @@ -2333,10 +2330,8 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, pcmd += sizeof(uint32_t); *((uint32_t *) (pcmd)) = rejectError; - if (mbox) { + if (mbox) elsiocb->context_un.mbox = mbox; - elsiocb->context1 = lpfc_nlp_get(ndlp); - } /* Xmit ELS RJT response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, @@ -2353,6 +2348,15 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, phba->fc_stat.elsXmitLSRJT++; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); + + /* If the node is in the UNUSED state, and we are sending + * a reject, we are done with it. Release driver reference + * count here. The outstanding els will release its reference on + * completion and the node can be freed then. + */ + if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) + lpfc_nlp_put(ndlp); + if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); return 1; @@ -2747,7 +2751,7 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) static int lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, - struct lpfc_nodelist *ndlp, uint8_t newnode) + struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; @@ -2781,8 +2785,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x", ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, - newnode); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); return 0; } @@ -2814,7 +2817,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, ndlp->nlp_flag); lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, - ndlp, NULL, newnode); + ndlp, NULL); return 0; } } @@ -2870,8 +2873,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, vport->port_state); } /* Send back ACC */ - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, - newnode); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); /* send RECOVERY event for ALL nodes that match RSCN payload */ lpfc_rscn_recovery_check(vport); @@ -2896,7 +2898,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, lpfc_set_disctmo(vport); /* Send back ACC */ - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); /* send RECOVERY event for ALL nodes that match RSCN payload */ lpfc_rscn_recovery_check(vport); @@ -2965,7 +2967,7 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) static int lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, - struct lpfc_nodelist *ndlp, uint8_t newnode) + struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; @@ -3048,7 +3050,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, } /* Send back ACC */ - lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); + lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); return 0; } @@ -3409,7 +3411,7 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0600 FARP-RSP received from DID x%x\n", did); /* ACCEPT the Farp resp request */ - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); return 0; } @@ -3791,7 +3793,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, did, vport->port_state, ndlp->nlp_flag); phba->fc_stat.elsRcvFLOGI++; - lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode); + lpfc_els_rcv_flogi(vport, elsiocb, ndlp); if (newnode) lpfc_drop_node(vport, ndlp); break; @@ -3821,7 +3823,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, break; case ELS_CMD_RSCN: phba->fc_stat.elsRcvRSCN++; - lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode); + lpfc_els_rcv_rscn(vport, elsiocb, ndlp); if (newnode) lpfc_drop_node(vport, ndlp); break; @@ -3951,8 +3953,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp, NULL); - if (newnode) - lpfc_drop_node(vport, ndlp); } return; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f96ab75ba637..8788f14b1dec 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -83,10 +83,17 @@ lpfc_terminate_rport_io(struct fc_rport *rport) ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); if (ndlp->nlp_sid != NLP_NO_SID) { - lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); + lpfc_sli_abort_iocb(ndlp->vport, + &phba->sli.ring[phba->sli.fcp_ring], + ndlp->nlp_sid, 0, LPFC_CTX_TGT); } + /* + * A device is normally blocked for rediscovery and unblocked when + * devloss timeout happens. In case a vport is removed or driver + * unloaded before devloss timeout happens, we need to unblock here. + */ + scsi_target_unblock(&rport->dev); return; } @@ -194,8 +201,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) if (ndlp->nlp_sid != NLP_NO_SID) { warn_on = 1; /* flush the target */ - lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); + lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], + ndlp->nlp_sid, 0, LPFC_CTX_TGT); } if (vport->load_flag & FC_UNLOADING) warn_on = 0; @@ -348,6 +355,7 @@ lpfc_work_done(struct lpfc_hba *phba) struct lpfc_sli_ring *pring; uint32_t ha_copy, status, control, work_port_events; struct lpfc_vport **vports; + struct lpfc_vport *vport; int i; spin_lock_irq(&phba->hbalock); @@ -365,12 +373,22 @@ lpfc_work_done(struct lpfc_hba *phba) lpfc_handle_latt(phba); vports = lpfc_create_vport_work_array(phba); if (vports != NULL) - for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { - work_port_events = vports[i]->work_port_events; + for(i = 0; i < LPFC_MAX_VPORTS; i++) { + /* + * We could have no vports in array if unloading, so if + * this happens then just use the pport + */ + if (vports[i] == NULL && i == 0) + vport = phba->pport; + else + vport = vports[i]; + if (vport == NULL) + break; + work_port_events = vport->work_port_events; if (work_port_events & WORKER_DISC_TMO) - lpfc_disc_timeout_handler(vports[i]); + lpfc_disc_timeout_handler(vport); if (work_port_events & WORKER_ELS_TMO) - lpfc_els_timeout_handler(vports[i]); + lpfc_els_timeout_handler(vport); if (work_port_events & WORKER_HB_TMO) lpfc_hb_timeout_handler(phba); if (work_port_events & WORKER_MBOX_TMO) @@ -378,14 +396,14 @@ lpfc_work_done(struct lpfc_hba *phba) if (work_port_events & WORKER_FABRIC_BLOCK_TMO) lpfc_unblock_fabric_iocbs(phba); if (work_port_events & WORKER_FDMI_TMO) - lpfc_fdmi_timeout_handler(vports[i]); + lpfc_fdmi_timeout_handler(vport); if (work_port_events & WORKER_RAMP_DOWN_QUEUE) lpfc_ramp_down_queue_handler(phba); if (work_port_events & WORKER_RAMP_UP_QUEUE) lpfc_ramp_up_queue_handler(phba); - spin_lock_irq(&vports[i]->work_port_lock); - vports[i]->work_port_events &= ~work_port_events; - spin_unlock_irq(&vports[i]->work_port_lock); + spin_lock_irq(&vport->work_port_lock); + vport->work_port_events &= ~work_port_events; + spin_unlock_irq(&vport->work_port_lock); } lpfc_destroy_vport_work_array(vports); @@ -1638,16 +1656,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) void lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - - if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) - lpfc_cancel_retry_delay_tmo(vport, ndlp); - if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) - lpfc_nlp_counters(vport, ndlp->nlp_state, -1); - spin_lock_irq(shost->host_lock); - list_del_init(&ndlp->nlp_listp); - ndlp->nlp_flag &= ~NLP_TARGET_REMOVE; - spin_unlock_irq(shost->host_lock); + lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); lpfc_nlp_put(ndlp); } diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index c2fb59f595f3..a90b1fd9c760 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -150,7 +150,11 @@ struct lpfc_sli_ct_request { struct gff_acc { uint8_t fbits[128]; } gff_acc; +#ifdef __BIG_ENDIAN_BITFIELD +#define FCP_TYPE_FEATURE_OFFSET 7 +#else /* __LITTLE_ENDIAN_BITFIELD */ #define FCP_TYPE_FEATURE_OFFSET 4 +#endif struct rff { uint32_t PortId; uint8_t reserved[2]; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7e5ea0774e58..21f8f7a56e23 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -55,6 +55,8 @@ static DEFINE_IDR(lpfc_hba_index); +extern struct lpfc_hbq_init *lpfc_hbq_defs[]; + /************************************************************************/ /* */ /* lpfc_config_port_prep */ @@ -429,18 +431,11 @@ lpfc_config_port_post(struct lpfc_hba *phba) int lpfc_hba_down_prep(struct lpfc_hba *phba) { - struct lpfc_vport **vports; - int i; - /* Disable interrupts */ writel(0, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ - vports = lpfc_create_vport_work_array(phba); - if (vports != NULL) - for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) - lpfc_cleanup_discovery_resources(vports[i]); - lpfc_destroy_vport_work_array(vports); + lpfc_cleanup_discovery_resources(phba->pport); return 0; } @@ -512,7 +507,7 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) mempool_free(pmboxq, phba->mbox_mem_pool); if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) && !(phba->link_state == LPFC_HBA_ERROR) && - !(phba->pport->fc_flag & FC_UNLOADING)) + !(phba->pport->load_flag & FC_UNLOADING)) mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL); return; @@ -526,7 +521,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) struct lpfc_sli *psli = &phba->sli; if ((phba->link_state == LPFC_HBA_ERROR) || - (phba->pport->fc_flag & FC_UNLOADING) || + (phba->pport->load_flag & FC_UNLOADING) || (phba->pport->fc_flag & FC_OFFLINE_MODE)) return; @@ -1340,16 +1335,9 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport) static void lpfc_stop_phba_timers(struct lpfc_hba *phba) { - struct lpfc_vport **vports; - int i; - del_timer_sync(&phba->fcp_poll_timer); del_timer_sync(&phba->fc_estabtmo); - vports = lpfc_create_vport_work_array(phba); - if (vports != NULL) - for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) - lpfc_stop_vport_timers(vports[i]); - lpfc_destroy_vport_work_array(vports); + lpfc_stop_vport_timers(phba->pport); del_timer_sync(&phba->sli.mbox_tmo); del_timer_sync(&phba->fabric_block_timer); phba->hb_outstanding = 0; @@ -1455,6 +1443,11 @@ lpfc_offline(struct lpfc_hba *phba) /* stop all timers associated with this hba */ lpfc_stop_phba_timers(phba); + vports = lpfc_create_vport_work_array(phba); + if (vports != NULL) + for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) + lpfc_stop_vport_timers(vports[i]); + lpfc_destroy_vport_work_array(vports); lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "0460 Bring Adapter offline\n"); /* Bring down the SLI Layer and cleanup. The HBA is offline @@ -1629,7 +1622,7 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) spin_lock_irq(shost->host_lock); - if (vport->fc_flag & FC_UNLOADING) { + if (vport->load_flag & FC_UNLOADING) { stat = 1; goto finished; } @@ -1706,7 +1699,7 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) fc_host_max_npiv_vports(shost) = phba->max_vpi; spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_LOADING; + vport->load_flag &= ~FC_LOADING; spin_unlock_irq(shost->host_lock); } @@ -1718,9 +1711,10 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) struct lpfc_sli *psli; struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL; struct Scsi_Host *shost = NULL; + void *ptr; unsigned long bar0map_len, bar2map_len; int error = -ENODEV; - int i; + int i, hbq_count; uint16_t iotag; if (pci_enable_device(pdev)) @@ -1741,7 +1735,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_phba; INIT_LIST_HEAD(&phba->port_list); - INIT_LIST_HEAD(&phba->hbq_buffer_list); /* * Get all the module params for configuring this host and then * establish the host. @@ -1819,6 +1812,17 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (!phba->hbqslimp.virt) goto out_free_slim; + hbq_count = lpfc_sli_hbq_count(); + ptr = phba->hbqslimp.virt; + for (i = 0; i < hbq_count; ++i) { + phba->hbqs[i].hbq_virt = ptr; + INIT_LIST_HEAD(&phba->hbqs[i].hbq_buffer_list); + ptr += (lpfc_hbq_defs[i]->entry_count * + sizeof(struct lpfc_hbq_entry)); + } + phba->hbqs[LPFC_ELS_HBQ].hbq_alloc_buffer = lpfc_els_hbq_alloc; + phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer = lpfc_els_hbq_free; + memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size()); /* Initialize the SLI Layer to run with lpfc HBAs. */ @@ -1894,7 +1898,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (phba->cfg_use_msi) { error = pci_enable_msi(phba->pcidev); - if (error) + if (!error) + phba->using_msi = 1; + else lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0452 Enable MSI failed, continuing " "with IRQ\n"); @@ -1941,14 +1947,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) out_remove_device: lpfc_free_sysfs_attr(vport); spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_UNLOADING; + vport->load_flag |= FC_UNLOADING; spin_unlock_irq(shost->host_lock); out_free_irq: lpfc_stop_phba_timers(phba); phba->pport->work_port_events = 0; free_irq(phba->pcidev->irq, phba); out_disable_msi: - pci_disable_msi(phba->pcidev); + if (phba->using_msi) + pci_disable_msi(phba->pcidev); destroy_port(vport); out_kthread_stop: kthread_stop(phba->worker_thread); @@ -1990,10 +1997,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; - struct lpfc_vport *port_iterator; spin_lock_irq(&phba->hbalock); - list_for_each_entry(port_iterator, &phba->port_list, listentry) - port_iterator->load_flag |= FC_UNLOADING; + vport->load_flag |= FC_UNLOADING; spin_unlock_irq(&phba->hbalock); kfree(vport->vname); @@ -2001,7 +2006,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) fc_remove_host(shost); scsi_remove_host(shost); - /* * Bring down the SLI Layer. This step disable all interrupts, * clears the rings, discards all mailbox commands, and resets @@ -2022,7 +2026,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev) /* Release the irq reservation */ free_irq(phba->pcidev->irq, phba); - pci_disable_msi(phba->pcidev); + if (phba->using_msi) + pci_disable_msi(phba->pcidev); pci_set_drvdata(pdev, NULL); scsi_host_put(shost); @@ -2064,8 +2069,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev) static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; @@ -2081,6 +2086,11 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, pring = &psli->ring[psli->fcp_ring]; lpfc_sli_abort_iocb_ring(phba, pring); + /* Release the irq reservation */ + free_irq(phba->pcidev->irq, phba); + if (phba->using_msi) + pci_disable_msi(phba->pcidev); + /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; } @@ -2093,8 +2103,8 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, */ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; struct lpfc_sli *psli = &phba->sli; int bars = pci_select_bars(pdev, IORESOURCE_MEM); @@ -2108,9 +2118,9 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) pci_set_master(pdev); /* Re-establishing Link */ - spin_lock_irq(host->host_lock); + spin_lock_irq(shost->host_lock); phba->pport->fc_flag |= FC_ESTABLISH_LINK; - spin_unlock_irq(host->host_lock); + spin_unlock_irq(shost->host_lock); spin_lock_irq(&phba->hbalock); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; @@ -2133,8 +2143,8 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) */ static void lpfc_io_resume(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; if (lpfc_online(phba) == 0) { mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 09ecdcb63a74..a592733664e9 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -560,7 +560,8 @@ lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb, } void -lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc, +lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id, + struct lpfc_hbq_init *hbq_desc, uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb) { int i; @@ -568,6 +569,7 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc, struct config_hbq_var *hbqmb = &mb->un.varCfgHbq; memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); + hbqmb->hbqId = id; hbqmb->entry_count = hbq_desc->entry_count; /* # entries in HBQ */ hbqmb->recvNotify = hbq_desc->rn; /* Receive * Notification */ @@ -687,7 +689,7 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ - mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */ + mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count(); if (phba->max_vpi && phba->cfg_enable_npiv && phba->vpd.sli3Feat.cmv) { mb->un.varCfgPort.max_vpi = phba->max_vpi; diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 3594c469494f..43c3b8a0d76a 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -231,21 +231,34 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) return; } -void * -lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) +struct hbq_dmabuf * +lpfc_els_hbq_alloc(struct lpfc_hba *phba) { - void *ret; - ret = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_ATOMIC, handle); - return ret; + struct hbq_dmabuf *hbqbp; + + hbqbp = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); + if (!hbqbp) + return NULL; + + hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL, + &hbqbp->dbuf.phys); + if (!hbqbp->dbuf.virt) { + kfree(hbqbp); + return NULL; + } + hbqbp->size = LPFC_BPL_SIZE; + return hbqbp; } void -lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma) +lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp) { - pci_pool_free(phba->lpfc_hbq_pool, virt, dma); + pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys); + kfree(hbqbp); return; } +/* This is ONLY called for the LPFC_ELS_HBQ */ void lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) { @@ -254,9 +267,8 @@ lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf); if (hbq_entry->tag == -1) { - lpfc_hbq_free(phba, hbq_entry->dbuf.virt, - hbq_entry->dbuf.phys); - kfree(hbq_entry); + (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer) + (phba, hbq_entry); } else { lpfc_sli_free_hbq(phba, hbq_entry); } diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 66ba51cbeb50..880af0cd463d 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -329,7 +329,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, case NLP_STE_PRLI_ISSUE: case NLP_STE_UNMAPPED_NODE: case NLP_STE_MAPPED_NODE: - lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); return 1; } @@ -407,7 +407,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp, mbox); return 1; } - lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); return 1; out: @@ -451,7 +451,7 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp); } else { lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, - NULL, 0); + NULL); } return 1; } @@ -488,9 +488,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_flag |= NLP_LOGO_ACC; spin_unlock_irq(shost->host_lock); if (els_cmd == ELS_CMD_PRLO) - lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); else - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); if (!(ndlp->nlp_type & NLP_FABRIC) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { @@ -564,6 +564,11 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); + if (!ndlp->nlp_rpi) { + ndlp->nlp_flag &= ~NLP_NPR_ADISC; + return 0; + } + /* Check config parameter use-adisc or FCP-2 */ if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { @@ -627,7 +632,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_LOGO_ACC; spin_unlock_irq(shost->host_lock); - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); return ndlp->nlp_state; @@ -723,7 +728,7 @@ lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_els_abort(phba, ndlp); if (evt == NLP_EVT_RCV_LOGO) { - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); } else { lpfc_issue_els_logo(vport, ndlp, 0); } @@ -1167,7 +1172,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb; cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); return ndlp->nlp_state; } @@ -1322,7 +1327,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); return ndlp->nlp_state; } @@ -1514,7 +1519,7 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); return ndlp->nlp_state; } @@ -1585,8 +1590,8 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; /* flush the target */ - lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); + lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], + ndlp->nlp_sid, 0, LPFC_CTX_TGT); /* Treat like rcv logo */ lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO); @@ -1719,7 +1724,7 @@ lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_flag |= NLP_LOGO_ACC; spin_unlock_irq(shost->host_lock); - lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) { mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 9ee2927ad82a..94458d7a8f7f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -152,7 +152,6 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) } } lpfc_destroy_vport_work_array(vports); - spin_unlock_irq(&phba->hbalock); atomic_set(&phba->num_rsrc_err, 0); atomic_set(&phba->num_cmd_success, 0); } @@ -1195,14 +1194,12 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) * Unfortunately, some targets do not abide by this forcing the driver * to double check. */ - cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - cmnd->device->id, cmnd->device->lun, + cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, cmnd->device->lun, LPFC_CTX_LUN); if (cnt) - lpfc_sli_abort_iocb(phba, - &phba->sli.ring[phba->sli.fcp_ring], + lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], cmnd->device->id, cmnd->device->lun, - 0, LPFC_CTX_LUN); + LPFC_CTX_LUN); loopcnt = 0; while(cnt) { schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); @@ -1211,10 +1208,8 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT) break; - cnt = lpfc_sli_sum_iocb(phba, - &phba->sli.ring[phba->sli.fcp_ring], - cmnd->device->id, cmnd->device->lun, - LPFC_CTX_LUN); + cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, + cmnd->device->lun, LPFC_CTX_LUN); } if (cnt) { @@ -1304,11 +1299,10 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) * the targets. Unfortunately, some targets do not abide by * this forcing the driver to double check. */ - cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - 0, 0, LPFC_CTX_HOST); + cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST); if (cnt) - lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - 0, 0, 0, LPFC_CTX_HOST); + lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], + 0, 0, LPFC_CTX_HOST); loopcnt = 0; while(cnt) { schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); @@ -1317,9 +1311,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT) break; - cnt = lpfc_sli_sum_iocb(phba, - &phba->sli.ring[phba->sli.fcp_ring], - 0, 0, LPFC_CTX_HOST); + cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST); } if (cnt) { diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 5417bc26f181..c54a9ea336a6 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -545,7 +545,8 @@ lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) return NULL; } - return (struct lpfc_hbq_entry *) phba->hbqslimp.virt + hbqp->hbqPutIdx; + return (struct lpfc_hbq_entry *) phba->hbqs[hbqno].hbq_virt + + hbqp->hbqPutIdx; } void @@ -553,18 +554,21 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) { struct lpfc_dmabuf *dmabuf, *next_dmabuf; struct hbq_dmabuf *hbq_buf; + int i, hbq_count; + hbq_count = lpfc_sli_hbq_count(); /* Return all memory used by all HBQs */ - list_for_each_entry_safe(dmabuf, next_dmabuf, - &phba->hbq_buffer_list, list) { - hbq_buf = container_of(dmabuf, struct hbq_dmabuf, dbuf); - list_del(&hbq_buf->dbuf.list); - lpfc_hbq_free(phba, hbq_buf->dbuf.virt, hbq_buf->dbuf.phys); - kfree(hbq_buf); + for (i = 0; i < hbq_count; ++i) { + list_for_each_entry_safe(dmabuf, next_dmabuf, + &phba->hbqs[i].hbq_buffer_list, list) { + hbq_buf = container_of(dmabuf, struct hbq_dmabuf, dbuf); + list_del(&hbq_buf->dbuf.list); + (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf); + } } } -static void +static struct lpfc_hbq_entry * lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno, struct hbq_dmabuf *hbq_buf) { @@ -578,7 +582,7 @@ lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno, hbqe->bde.addrHigh = le32_to_cpu(putPaddrHigh(physaddr)); hbqe->bde.addrLow = le32_to_cpu(putPaddrLow(physaddr)); - hbqe->bde.tus.f.bdeSize = FCELSSIZE; + hbqe->bde.tus.f.bdeSize = hbq_buf->size; hbqe->bde.tus.f.bdeFlags = 0; hbqe->bde.tus.w = le32_to_cpu(hbqe->bde.tus.w); hbqe->buffer_tag = le32_to_cpu(hbq_buf->tag); @@ -587,8 +591,9 @@ lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno, writel(hbqp->hbqPutIdx, phba->hbq_put + hbqno); /* flush */ readl(phba->hbq_put + hbqno); - list_add_tail(&hbq_buf->dbuf.list, &phba->hbq_buffer_list); + list_add_tail(&hbq_buf->dbuf.list, &hbqp->hbq_buffer_list); } + return hbqe; } static struct lpfc_hbq_init lpfc_els_hbq = { @@ -596,14 +601,26 @@ static struct lpfc_hbq_init lpfc_els_hbq = { .entry_count = 200, .mask_count = 0, .profile = 0, - .ring_mask = 1 << LPFC_ELS_RING, + .ring_mask = (1 << LPFC_ELS_RING), .buffer_count = 0, .init_count = 20, .add_count = 5, }; +static struct lpfc_hbq_init lpfc_extra_hbq = { + .rn = 1, + .entry_count = 200, + .mask_count = 0, + .profile = 0, + .ring_mask = (1 << LPFC_EXTRA_RING), + .buffer_count = 0, + .init_count = 0, + .add_count = 5, +}; + struct lpfc_hbq_init *lpfc_hbq_defs[] = { &lpfc_els_hbq, + &lpfc_extra_hbq, }; int @@ -612,6 +629,10 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) uint32_t i, start, end; struct hbq_dmabuf *hbq_buffer; + if (!phba->hbqs[hbqno].hbq_alloc_buffer) { + return 0; + } + start = lpfc_hbq_defs[hbqno]->buffer_count; end = count + lpfc_hbq_defs[hbqno]->buffer_count; if (end > lpfc_hbq_defs[hbqno]->entry_count) { @@ -620,17 +641,14 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) /* Populate HBQ entries */ for (i = start; i < end; i++) { - hbq_buffer = kmalloc(sizeof(struct hbq_dmabuf), - GFP_KERNEL); + hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); if (!hbq_buffer) return 1; - hbq_buffer->dbuf.virt = lpfc_hbq_alloc(phba, MEM_PRI, - &hbq_buffer->dbuf.phys); - if (hbq_buffer->dbuf.virt == NULL) - return 1; hbq_buffer->tag = (i | (hbqno << 16)); - lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer); - lpfc_hbq_defs[hbqno]->buffer_count++; + if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) + lpfc_hbq_defs[hbqno]->buffer_count++; + else + (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); } return 0; } @@ -654,10 +672,15 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) { struct lpfc_dmabuf *d_buf; struct hbq_dmabuf *hbq_buf; + uint32_t hbqno; + + hbqno = tag >> 16; + if (hbqno > LPFC_MAX_HBQS) + return NULL; - list_for_each_entry(d_buf, &phba->hbq_buffer_list, list) { + list_for_each_entry(d_buf, &phba->hbqs[hbqno].hbq_buffer_list, list) { hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); - if ((hbq_buf->tag & 0xffff) == tag) { + if (hbq_buf->tag == tag) { return hbq_buf; } } @@ -668,13 +691,15 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) } void -lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *sp) +lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *hbq_buffer) { uint32_t hbqno; - if (sp) { - hbqno = sp->tag >> 16; - lpfc_sli_hbq_to_firmware(phba, hbqno, sp); + if (hbq_buffer) { + hbqno = hbq_buffer->tag >> 16; + if (!lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) { + (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); + } } } @@ -904,21 +929,26 @@ static struct lpfc_dmabuf * lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) { struct hbq_dmabuf *hbq_entry, *new_hbq_entry; + uint32_t hbqno; + void *virt; /* virtual address ptr */ + dma_addr_t phys; /* mapped address */ hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); if (hbq_entry == NULL) return NULL; list_del(&hbq_entry->dbuf.list); - new_hbq_entry = kmalloc(sizeof(struct hbq_dmabuf), GFP_ATOMIC); + + hbqno = tag >> 16; + new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); if (new_hbq_entry == NULL) return &hbq_entry->dbuf; - new_hbq_entry->dbuf = hbq_entry->dbuf; new_hbq_entry->tag = -1; - hbq_entry->dbuf.virt = lpfc_hbq_alloc(phba, 0, &hbq_entry->dbuf.phys); - if (hbq_entry->dbuf.virt == NULL) { - kfree(new_hbq_entry); - return &hbq_entry->dbuf; - } + phys = new_hbq_entry->dbuf.phys; + virt = new_hbq_entry->dbuf.virt; + new_hbq_entry->dbuf.phys = hbq_entry->dbuf.phys; + new_hbq_entry->dbuf.virt = hbq_entry->dbuf.virt; + hbq_entry->dbuf.phys = phys; + hbq_entry->dbuf.virt = virt; lpfc_sli_free_hbq(phba, hbq_entry); return &new_hbq_entry->dbuf; } @@ -964,7 +994,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, irsp->un.ulpWord[3]); if (irsp->ulpBdeCount == 2) saveq->context3 = lpfc_sli_replace_hbqbuff(phba, - irsp->un.ulpWord[15]); + irsp->unsli3.sli3Words[7]); } /* unSolicited Responses */ @@ -2189,8 +2219,8 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba) phba->hbqs[hbqno].local_hbqGetIdx = 0; phba->hbqs[hbqno].entry_count = lpfc_hbq_defs[hbqno]->entry_count; - lpfc_config_hbq(phba, lpfc_hbq_defs[hbqno], hbq_entry_index, - pmb); + lpfc_config_hbq(phba, hbqno, lpfc_hbq_defs[hbqno], + hbq_entry_index, pmb); hbq_entry_index += phba->hbqs[hbqno].entry_count; if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { @@ -3433,8 +3463,8 @@ abort_iotag_exit: } static int -lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, - uint64_t lun_id, uint32_t ctx, +lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, + uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) { struct lpfc_scsi_buf *lpfc_cmd; @@ -3444,6 +3474,9 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, if (!(iocbq->iocb_flag & LPFC_IO_FCP)) return rc; + if (iocbq->vport != vport) + return rc; + lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); cmnd = lpfc_cmd->pCmd; @@ -3460,10 +3493,6 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, if (cmnd->device->id == tgt_id) rc = 0; break; - case LPFC_CTX_CTX: - if (iocbq->iocb.ulpContext == ctx) - rc = 0; - break; case LPFC_CTX_HOST: rc = 0; break; @@ -3477,17 +3506,18 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, } int -lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, - uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) +lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id, + lpfc_ctx_cmd ctx_cmd) { + struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *iocbq; int sum, i; for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; - if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id, - 0, ctx_cmd) == 0) + if (lpfc_sli_validate_fcp_iocb (iocbq, vport, tgt_id, lun_id, + ctx_cmd) == 0) sum++; } @@ -3503,10 +3533,10 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } int -lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, - uint16_t tgt_id, uint64_t lun_id, uint32_t ctx, - lpfc_ctx_cmd abort_cmd) +lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, + uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd abort_cmd) { + struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *iocbq; struct lpfc_iocbq *abtsiocb; IOCB_t *cmd = NULL; @@ -3516,7 +3546,7 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; - if (lpfc_sli_validate_fcp_iocb(iocbq, tgt_id, lun_id, 0, + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, abort_cmd) != 0) continue; diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 76058505795e..50f6d627da2e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -26,7 +26,6 @@ struct lpfc_vport; typedef enum _lpfc_ctx_cmd { LPFC_CTX_LUN, LPFC_CTX_TGT, - LPFC_CTX_CTX, LPFC_CTX_HOST } lpfc_ctx_cmd; @@ -54,9 +53,10 @@ struct lpfc_iocbq { void *context2; /* caller context information */ void *context3; /* caller context information */ union { - wait_queue_head_t *wait_queue; - struct lpfc_iocbq *rsp_iocb; - struct lpfcMboxq *mbox; + wait_queue_head_t *wait_queue; + struct lpfc_iocbq *rsp_iocb; + struct lpfcMboxq *mbox; + struct lpfc_nodelist *ndlp; } context_un; void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 77067d17c39d..7f0c263d1bd3 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -432,8 +432,29 @@ lpfc_vport_delete(struct fc_vport *fc_vport) struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; struct lpfc_hba *phba = vport->phba; long timeout; - int rc = VPORT_ERROR; + if (vport->port_type == LPFC_PHYSICAL_PORT) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1812 vport_delete failed: Cannot delete " + "physical host\n"); + return VPORT_ERROR; + } + /* + * If we are not unloading the driver then prevent the vport_delete + * from happening until after this vport's discovery is finished. + */ + if (!(phba->pport->load_flag & FC_UNLOADING)) { + int check_count = 0; + while (check_count < ((phba->fc_ratov * 3) + 3) && + vport->port_state > LPFC_VPORT_FAILED && + vport->port_state < LPFC_VPORT_READY) { + check_count++; + msleep(1000); + } + if (vport->port_state > LPFC_VPORT_FAILED && + vport->port_state < LPFC_VPORT_READY) + return -EAGAIN; + } /* * This is a bit of a mess. We want to ensure the shost doesn't get * torn down until we're done with the embedded lpfc_vport structure. @@ -451,16 +472,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport) */ if (!scsi_host_get(shost) || !scsi_host_get(shost)) return VPORT_INVAL; - - if (vport->port_type == LPFC_PHYSICAL_PORT) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, - "1812 vport_delete failed: Cannot delete " - "physical host\n"); - goto out; - } - + spin_lock_irq(&phba->hbalock); vport->load_flag |= FC_UNLOADING; - + spin_unlock_irq(&phba->hbalock); kfree(vport->vname); lpfc_debugfs_terminate(vport); fc_remove_host(lpfc_shost_from_vport(vport)); @@ -514,10 +528,8 @@ skip_logo: spin_unlock_irq(&phba->hbalock); lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, "1828 Vport Deleted.\n"); - rc = VPORT_OK; -out: scsi_host_put(shost); - return rc; + return VPORT_OK; } EXPORT_SYMBOL(lpfc_vport_create); @@ -536,7 +548,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) spin_lock_irq(&phba->hbalock); list_for_each_entry(port_iterator, &phba->port_list, listentry) { if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) { - lpfc_printf_vlog(port_iterator, KERN_ERR, LOG_VPORT, + lpfc_printf_vlog(port_iterator, KERN_WARNING, LOG_VPORT, "1801 Create vport work array FAILED: " "cannot do scsi_host_get\n"); continue; -- cgit v1.2.3 From 311464ec0bfea96e7f09f4afca26283f5fa90c24 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:10:37 -0400 Subject: [SCSI] lpfc 8.2.2 : Style cleanups - Clean up all instances of mixed tab-space indentation - Clean up sparse build errors - Add appropriate static's Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 6 +++--- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_ct.c | 4 ++-- drivers/scsi/lpfc/lpfc_debugfs.c | 8 +++----- drivers/scsi/lpfc/lpfc_hbadisc.c | 32 +++----------------------------- drivers/scsi/lpfc/lpfc_hw.h | 10 +++++----- drivers/scsi/lpfc/lpfc_init.c | 4 ---- drivers/scsi/lpfc/lpfc_sli.c | 4 ++-- drivers/scsi/lpfc/lpfc_sli.h | 2 +- drivers/scsi/lpfc/lpfc_vport.c | 4 ++-- 11 files changed, 23 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index c28db0521c01..ba3ecab9baf3 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -45,7 +45,7 @@ struct lpfc_sli2_slim; #define LPFC_DISC_IOCB_BUFF_COUNT 20 #define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */ -#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */ +#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */ /* Define macros for 64 bit support */ #define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr))) @@ -381,7 +381,7 @@ struct lpfc_hba { struct lpfc_sli sli; uint32_t sli_rev; /* SLI2 or SLI3 */ uint32_t sli3_options; /* Mask of enabled SLI3 options */ -#define LPFC_SLI3_ENABLED 0x01 +#define LPFC_SLI3_ENABLED 0x01 #define LPFC_SLI3_HBQ_ENABLED 0x02 #define LPFC_SLI3_NPIV_ENABLED 0x04 #define LPFC_SLI3_VPORT_TEARDOWN 0x08 @@ -390,7 +390,7 @@ struct lpfc_hba { enum hba_state link_state; uint32_t link_flag; /* link state flags */ -#define LS_LOOPBACK_MODE 0x1 /* NPort is in Loopback mode */ +#define LS_LOOPBACK_MODE 0x1 /* NPort is in Loopback mode */ /* This flag is set while issuing */ /* INIT_LINK mailbox command */ #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 09743d7b6bab..80a11218b9bb 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -430,7 +430,7 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) return -EIO; } -int +static int lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, uint32_t *axri, uint32_t *mrpi, uint32_t *arpi, diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index b789355fedf5..a599e1510710 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -278,6 +278,7 @@ extern void lpfc_debugfs_disc_trc(struct lpfc_vport *, int, char *, uint32_t, uint32_t, uint32_t); extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t, uint32_t, uint32_t); +extern struct lpfc_hbq_init *lpfc_hbq_defs[]; /* Interface exported by fabric iocb scheduler */ int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 6f187f3b3048..c701e4d611a9 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -688,7 +688,7 @@ out: return; } -void +static void lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { @@ -885,7 +885,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -int +static int lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol, size_t size) { diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 697a09dccb6f..2e3c01bebed6 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -112,10 +112,8 @@ struct lpfc_debug { int len; }; -extern struct lpfc_hbq_init *lpfc_hbq_defs[]; - -atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); -unsigned long lpfc_debugfs_start_time = 0L; +static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); +static unsigned long lpfc_debugfs_start_time = 0L; static int lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) @@ -201,7 +199,7 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) return len; } -int lpfc_debugfs_last_hbq = -1; +static int lpfc_debugfs_last_hbq = -1; static int lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 8788f14b1dec..c81c2b3228d6 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -349,7 +349,7 @@ lpfc_work_list_done(struct lpfc_hba *phba) } -void +static void lpfc_work_done(struct lpfc_hba *phba) { struct lpfc_sli_ring *pring; @@ -1591,7 +1591,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) [NLP_STE_NPR_NODE] = "NPR", }; - if (state < ARRAY_SIZE(states) && states[state]) + if (state < NLP_STE_MAX_STATE && states[state]) strlcpy(buffer, states[state], size); else snprintf(buffer, size, "unknown (%d)", state); @@ -2814,32 +2814,6 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn) return ndlp; } -void -lpfc_dev_loss_delay(unsigned long ptr) -{ - struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr; - struct lpfc_vport *vport = ndlp->vport; - struct lpfc_hba *phba = vport->phba; - struct lpfc_work_evt *evtp = &ndlp->dev_loss_evt; - unsigned long flags; - - evtp = &ndlp->dev_loss_evt; - - spin_lock_irqsave(&phba->hbalock, flags); - if (!list_empty(&evtp->evt_listp)) { - spin_unlock_irqrestore(&phba->hbalock, flags); - return; - } - - evtp->evt_arg1 = ndlp; - evtp->evt = LPFC_EVT_DEV_LOSS_DELAY; - list_add_tail(&evtp->evt_listp, &phba->work_list); - if (phba->work_wait) - lpfc_worker_wake_up(phba); - spin_unlock_irqrestore(&phba->hbalock, flags); - return; -} - void lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint32_t did) @@ -2863,7 +2837,7 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return; } -void +static void lpfc_nlp_release(struct kref *kref) { struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index a90b1fd9c760..451accd5564b 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -809,7 +809,7 @@ typedef struct _RNID { /* Structure is in Big Endian format */ } un; } RNID; -typedef struct _RPS { /* Structure is in Big Endian format */ +typedef struct _RPS { /* Structure is in Big Endian format */ union { uint32_t portNum; struct lpfc_name portName; @@ -827,7 +827,7 @@ typedef struct _RPS_RSP { /* Structure is in Big Endian format */ uint32_t crcCnt; } RPS_RSP; -typedef struct _RPL { /* Structure is in Big Endian format */ +typedef struct _RPL { /* Structure is in Big Endian format */ uint32_t maxsize; uint32_t index; } RPL; @@ -838,7 +838,7 @@ typedef struct _PORT_NUM_BLK { struct lpfc_name portName; } PORT_NUM_BLK; -typedef struct _RPL_RSP { /* Structure is in Big Endian format */ +typedef struct _RPL_RSP { /* Structure is in Big Endian format */ uint32_t listLen; uint32_t index; PORT_NUM_BLK port_num_blk; @@ -2617,8 +2617,8 @@ typedef union { LOAD_SM_VAR varLdSM; /* cmd = 1 (LOAD_SM) */ READ_NV_VAR varRDnvp; /* cmd = 2 (READ_NVPARMS) */ WRITE_NV_VAR varWTnvp; /* cmd = 3 (WRITE_NVPARMS) */ - BIU_DIAG_VAR varBIUdiag; /* cmd = 4 (RUN_BIU_DIAG) */ - INIT_LINK_VAR varInitLnk; /* cmd = 5 (INIT_LINK) */ + BIU_DIAG_VAR varBIUdiag; /* cmd = 4 (RUN_BIU_DIAG) */ + INIT_LINK_VAR varInitLnk; /* cmd = 5 (INIT_LINK) */ DOWN_LINK_VAR varDwnLnk; /* cmd = 6 (DOWN_LINK) */ CONFIG_LINK varCfgLnk; /* cmd = 7 (CONFIG_LINK) */ PART_SLIM_VAR varSlim; /* cmd = 8 (PART_SLIM) */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 21f8f7a56e23..414350ab584e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -53,10 +53,6 @@ static struct scsi_transport_template *lpfc_transport_template = NULL; static struct scsi_transport_template *lpfc_vport_transport_template = NULL; static DEFINE_IDR(lpfc_hba_index); - - -extern struct lpfc_hbq_init *lpfc_hbq_defs[]; - /************************************************************************/ /* */ /* lpfc_config_port_prep */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index c54a9ea336a6..ce5ff2bccba6 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -363,7 +363,7 @@ lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) if (psli->iocbq_lookup) memcpy(new_arr, old_arr, ((psli->last_iotag + 1) * - sizeof (struct lpfc_iocbq *))); + sizeof (struct lpfc_iocbq *))); psli->iocbq_lookup = new_arr; psli->iocbq_lookup_len = new_len; psli->last_iotag = iotag; @@ -623,7 +623,7 @@ struct lpfc_hbq_init *lpfc_hbq_defs[] = { &lpfc_extra_hbq, }; -int +static int lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) { uint32_t i, start, end; diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 50f6d627da2e..51b2b6b949be 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -143,7 +143,7 @@ struct lpfc_sli_ring { uint16_t numCiocb; /* number of command iocb's per ring */ uint16_t numRiocb; /* number of rsp iocb's per ring */ uint16_t sizeCiocb; /* Size of command iocb's in this ring */ - uint16_t sizeRiocb; /* Size of response iocb's in this ring */ + uint16_t sizeRiocb; /* Size of response iocb's in this ring */ uint32_t fast_iotag; /* max fastlookup based iotag */ uint32_t iotag_ctr; /* keeps track of the next iotag to use */ diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 7f0c263d1bd3..dcb415e717c3 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -331,7 +331,7 @@ error_out: return rc; } -int +static int disable_vport(struct fc_vport *fc_vport) { struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; @@ -376,7 +376,7 @@ disable_vport(struct fc_vport *fc_vport) return VPORT_OK; } -int +static int enable_vport(struct fc_vport *fc_vport) { struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; -- cgit v1.2.3 From 822b41f4eb98c144a07747e88e94941946bda124 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:10:46 -0400 Subject: [SCSI] lpfc 8.2.2 : Change version number to 8.2.2 Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 0b4e6fd02679..0081f49286bc 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.2.1" +#define LPFC_DRIVER_VERSION "8.2.2" #define LPFC_DRIVER_NAME "lpfc" -- cgit v1.2.3 From 585a8a59ebfc81327e1c4f2c0e80730bdd2e5d8e Mon Sep 17 00:00:00 2001 From: Mark Fortescue Date: Tue, 31 Jul 2007 20:10:45 +0100 Subject: [SCSI] qlogicpti: Some cosmetic changes Change a printk sequencing issue where <6> ... was coming up in the middle of a line when scsi_add_host was being called. Reduce the length of some printk messages and make the messages more consistant. All cosmetic but it makes it easier to read as it scrolles off the screen during boot. Signed-off-by: Mark Fortescue Acked-by: David S. Miller Signed-off-by: James Bottomley --- drivers/scsi/qlogicpti.c | 50 ++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index c4195ea869e9..594887205b0f 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -193,7 +193,8 @@ static int qlogicpti_mbox_command(struct qlogicpti *qpti, u_short param[], int f cpu_relax(); } if (!loop_count) - printk(KERN_EMERG "qlogicpti: mbox_command loop timeout #1\n"); + printk(KERN_EMERG "qlogicpti%d: mbox_command loop timeout #1\n", + qpti->qpti_id); /* Write mailbox command registers. */ switch (mbox_param[param[0]] >> 4) { @@ -224,8 +225,8 @@ static int qlogicpti_mbox_command(struct qlogicpti *qpti, u_short param[], int f (sbus_readw(qpti->qregs + HCCTRL) & HCCTRL_CRIRQ)) udelay(20); if (!loop_count) - printk(KERN_EMERG "qlogicpti: mbox_command[%04x] loop timeout #2\n", - param[0]); + printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #2\n", + qpti->qpti_id, param[0]); /* Wait for SBUS semaphore to get set. */ loop_count = DEFAULT_LOOP_COUNT; @@ -238,16 +239,16 @@ static int qlogicpti_mbox_command(struct qlogicpti *qpti, u_short param[], int f break; } if (!loop_count) - printk(KERN_EMERG "qlogicpti: mbox_command[%04x] loop timeout #3\n", - param[0]); + printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #3\n", + qpti->qpti_id, param[0]); /* Wait for MBOX busy condition to go away. */ loop_count = DEFAULT_LOOP_COUNT; while (--loop_count && (sbus_readw(qpti->qregs + MBOX0) == 0x04)) udelay(20); if (!loop_count) - printk(KERN_EMERG "qlogicpti: mbox_command[%04x] loop timeout #4\n", - param[0]); + printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #4\n", + qpti->qpti_id, param[0]); /* Read back output parameters. */ switch (mbox_param[param[0]] & 0xf) { @@ -342,7 +343,8 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) while (--loop_count && ((sbus_readw(qpti->qregs + MBOX0) & 0xff) == 0x04)) udelay(20); if (!loop_count) - printk(KERN_EMERG "qlogicpti: reset_hardware loop timeout\n"); + printk(KERN_EMERG "qlogicpti%d: reset_hardware loop timeout\n", + qpti->qpti_id); sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL); set_sbus_cfg1(qpti); @@ -721,12 +723,12 @@ static int __init qpti_register_irq(struct qlogicpti *qpti) IRQF_SHARED, "Qlogic/PTI", qpti)) goto fail; - printk("qpti%d: IRQ %d ", qpti->qpti_id, qpti->irq); + printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq); return 0; fail: - printk("qpti%d: Cannot acquire irq line\n", qpti->qpti_id); + printk("qlogicpti%d: Cannot acquire irq line\n", qpti->qpti_id); return -1; } @@ -1210,7 +1212,7 @@ static int qlogicpti_return_status(struct Status_Entry *sts, int id) host_status = DID_OK; break; default: - printk(KERN_EMERG "qpti%d: unknown completion status 0x%04x\n", + printk(KERN_EMERG "qlogicpti%d: unknown completion status 0x%04x\n", id, sts->completion_status); host_status = DID_ERROR; break; @@ -1329,8 +1331,8 @@ static int qlogicpti_abort(struct scsi_cmnd *Cmnd) u32 cmd_cookie; int i; - printk(KERN_WARNING "qlogicpti : Aborting cmd for tgt[%d] lun[%d]\n", - (int)Cmnd->device->id, (int)Cmnd->device->lun); + printk(KERN_WARNING "qlogicpti%d: Aborting cmd for tgt[%d] lun[%d]\n", + qpti->qpti_id, (int)Cmnd->device->id, (int)Cmnd->device->lun); qlogicpti_disable_irqs(qpti); @@ -1348,7 +1350,8 @@ static int qlogicpti_abort(struct scsi_cmnd *Cmnd) param[3] = cmd_cookie & 0xffff; if (qlogicpti_mbox_command(qpti, param, 0) || (param[0] != MBOX_COMMAND_COMPLETE)) { - printk(KERN_EMERG "qlogicpti : scsi abort failure: %x\n", param[0]); + printk(KERN_EMERG "qlogicpti%d: scsi abort failure: %x\n", + qpti->qpti_id, param[0]); return_status = FAILED; } @@ -1364,7 +1367,8 @@ static int qlogicpti_reset(struct scsi_cmnd *Cmnd) struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; int return_status = SUCCESS; - printk(KERN_WARNING "qlogicpti : Resetting SCSI bus!\n"); + printk(KERN_WARNING "qlogicpti%d: Resetting SCSI bus!\n", + qpti->qpti_id); qlogicpti_disable_irqs(qpti); @@ -1372,7 +1376,8 @@ static int qlogicpti_reset(struct scsi_cmnd *Cmnd) param[1] = qpti->host_param.bus_reset_delay; if (qlogicpti_mbox_command(qpti, param, 0) || (param[0] != MBOX_COMMAND_COMPLETE)) { - printk(KERN_EMERG "qlogicisp : scsi bus reset failure: %x\n", param[0]); + printk(KERN_EMERG "qlogicisp%d: scsi bus reset failure: %x\n", + qpti->qpti_id, param[0]); return_status = FAILED; } @@ -1454,22 +1459,25 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi if (qlogicpti_reset_hardware(host)) goto fail_unmap_queues; - if (scsi_add_host(host, &dev->dev)) - goto fail_unmap_queues; - printk("(Firmware v%d.%d.%d)", qpti->fware_majrev, qpti->fware_minrev, qpti->fware_micrev); fcode = of_get_property(dp, "isp-fcode", NULL); if (fcode && fcode[0]) - printk("(Firmware %s)", fcode); + printk("(FCode %s)", fcode); if (of_find_property(dp, "differential", NULL) != NULL) qpti->differential = 1; - printk (" [%s Wide, using %s interface]\n", + printk("\nqlogicpti%d: [%s Wide, using %s interface]\n", + qpti->qpti_id, (qpti->ultra ? "Ultra" : "Fast"), (qpti->differential ? "differential" : "single ended")); + if (scsi_add_host(host, &dev->dev)) { + printk("qlogicpti%d: Failed scsi_add_host\n", qpti->qpti_id); + goto fail_unmap_queues; + } + dev_set_drvdata(&sdev->ofdev.dev, qpti); qpti_chain_add(qpti); -- cgit v1.2.3 From a9c2f18800753c82c45fc13b27bdc148849bdbb2 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 1 Aug 2007 20:30:36 +0200 Subject: ieee1394: revert "sbp2: enforce 32bit DMA mapping" Revert commit 0555659d63c285ceb7ead3115532e1b71b0f27a7 from 2.6.22-rc1. The dma_set_mask call somehow failed on a PowerMac G5, PPC64: http://lkml.org/lkml/2007/8/1/344 Should there ever occur a DMA mapping beyond the physical DMA range, a proper SBP-2 firmware will report transport errors. So let's leave it at that. Signed-off-by: Stefan Richter Tested-by: Olaf Hering --- drivers/ieee1394/sbp2.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index e882cb951b47..47dbe8f17e82 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -773,11 +773,6 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud) SBP2_ERR("failed to register lower 4GB address range"); goto failed_alloc; } -#else - if (dma_set_mask(hi->host->device.parent, DMA_32BIT_MASK)) { - SBP2_ERR("failed to set 4GB DMA mask"); - goto failed_alloc; - } #endif } -- cgit v1.2.3 From e4f8cac5e07528f7e0bc21d3682c16c9de993ecb Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 21 Jul 2007 17:51:22 +0200 Subject: ieee1394: sbp2: more correct Kconfig dependencies Make the option SBP2_PHYS_DMA available on all architectures where it compiles. This includes x86-64 where I runtime-tested it successfully. Signed-off-by: Stefan Richter --- drivers/ieee1394/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig index 8012b3b0ce75..545663ef820b 100644 --- a/drivers/ieee1394/Kconfig +++ b/drivers/ieee1394/Kconfig @@ -97,7 +97,7 @@ config IEEE1394_SBP2 config IEEE1394_SBP2_PHYS_DMA bool "Enable replacement for physical DMA in SBP2" - depends on IEEE1394 && IEEE1394_SBP2 && EXPERIMENTAL && (X86_32 || PPC_32) + depends on IEEE1394_SBP2 && VIRT_TO_BUS && EXPERIMENTAL help This builds sbp2 for use with non-OHCI host adapters which do not support physical DMA or for when ohci1394 is run with phys_dma=0. -- cgit v1.2.3 From 25659f7183376c6b37661da6141d5eaa21479061 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 21 Jul 2007 22:43:05 +0200 Subject: firewire: fw-sbp2: set correct maximum payload (fixes CardBus adapters) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As far as I know, all CardBus FireWire 400 adapters have a maximum payload of 1024 bytes which is less than the speed-dependent limit of 2048 bytes. Fw-sbp2 has to take the host adapter's limit into account. This apparently fixes Juju's incompatibility with my CardBus cards, a NEC based card and a VIA based card. Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 5 ++++- drivers/firewire/fw-transaction.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 3e4a369d0057..ba816ef6def1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -984,6 +984,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) struct fw_unit *unit = sd->unit; struct fw_device *device = fw_device(unit->device.parent); struct sbp2_command_orb *orb; + unsigned max_payload; /* * Bidirectional commands are not yet implemented, and unknown @@ -1017,8 +1018,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) * specifies the max payload size as 2 ^ (max_payload + 2), so * if we set this to max_speed + 7, we get the right value. */ + max_payload = min(device->max_speed + 7, + device->card->max_receive - 1); orb->request.misc = - COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) | + COMMAND_ORB_MAX_PAYLOAD(max_payload) | COMMAND_ORB_SPEED(device->max_speed) | COMMAND_ORB_NOTIFY; diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 5ceaccd10564..fa7967b57408 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -231,7 +231,7 @@ struct fw_card { unsigned long reset_jiffies; unsigned long long guid; - int max_receive; + unsigned max_receive; int link_speed; int config_rom_generation; -- cgit v1.2.3 From 4eaff7d63052d781732de9eff4d2287c8e00348f Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 25 Jul 2007 19:18:08 +0200 Subject: firewire: fw-ohci: dma_free_coherent needs IRQs enabled Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index db703758db98..7e427b4c74b5 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -907,6 +907,8 @@ static void bus_reset_tasklet(unsigned long data) int self_id_count, i, j, reg; int generation, new_generation; unsigned long flags; + void *free_rom = NULL; + dma_addr_t free_rom_bus = 0; reg = reg_read(ohci, OHCI1394_NodeID); if (!(reg & OHCI1394_NodeID_idValid)) { @@ -970,8 +972,8 @@ static void bus_reset_tasklet(unsigned long data) */ if (ohci->next_config_rom != NULL) { - dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, - ohci->config_rom, ohci->config_rom_bus); + free_rom = ohci->config_rom; + free_rom_bus = ohci->config_rom_bus; ohci->config_rom = ohci->next_config_rom; ohci->config_rom_bus = ohci->next_config_rom_bus; ohci->next_config_rom = NULL; @@ -990,6 +992,10 @@ static void bus_reset_tasklet(unsigned long data) spin_unlock_irqrestore(&ohci->lock, flags); + if (free_rom) + dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, + free_rom, free_rom_bus); + fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, self_id_count, ohci->self_id_buffer); } @@ -1186,7 +1192,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length) { struct fw_ohci *ohci; unsigned long flags; - int retval = 0; + int retval = -EBUSY; __be32 *next_config_rom; dma_addr_t next_config_rom_bus; @@ -1240,10 +1246,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length) reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus); - } else { - dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, - next_config_rom, next_config_rom_bus); - retval = -EBUSY; + retval = 0; } spin_unlock_irqrestore(&ohci->lock, flags); @@ -1257,6 +1260,9 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length) */ if (retval == 0) fw_core_initiate_bus_reset(&ohci->card, 1); + else + dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, + next_config_rom, next_config_rom_bus); return retval; } -- cgit v1.2.3 From ae57988f68acdc9fbee649765148f15eb7a1b991 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Thu, 2 Aug 2007 20:34:17 +0200 Subject: firewire: fw-core: make two variables static Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 3ce8e2fbe15f..3e1cb12e43cd 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -734,7 +734,7 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p) } EXPORT_SYMBOL(fw_core_handle_response); -const struct fw_address_region topology_map_region = +static const struct fw_address_region topology_map_region = { .start = 0xfffff0001000ull, .end = 0xfffff0001400ull, }; static void @@ -772,7 +772,7 @@ static struct fw_address_handler topology_map = { .address_callback = handle_topology_map, }; -const struct fw_address_region registers_region = +static const struct fw_address_region registers_region = { .start = 0xfffff0000000ull, .end = 0xfffff0000400ull, }; static void -- cgit v1.2.3 From ed7e63a51d46e835422d89c687b8a3e419a4212a Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Fri, 3 Aug 2007 16:07:58 +0800 Subject: ucc_geth: fix section mismatch This fix section mismatch: reference to .exit.text:uec_mdio_exit (between 'ucc_geth_init' and 'uec_mdio_init') void __exit uec_mdio_exit(void) is called from - static int __init ucc_geth_init(void) - static void __exit ucc_geth_exit(void) First one would make error path more than just an error. Signed-off-by: Domen Puncer Signed-off-by: Li Yang --- drivers/net/ucc_geth_mii.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 5f8c2d30a328..6c257b88ce51 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -272,7 +272,8 @@ int __init uec_mdio_init(void) return of_register_platform_driver(&uec_mdio_driver); } -void __exit uec_mdio_exit(void) +/* called from __init ucc_geth_init, therefore can not be __exit */ +void uec_mdio_exit(void) { of_unregister_platform_driver(&uec_mdio_driver); } -- cgit v1.2.3 From 7c5b016246a889ec4b5dc8d40cab525e888a649e Mon Sep 17 00:00:00 2001 From: Jan Altenberg Date: Fri, 3 Aug 2007 16:08:15 +0800 Subject: ucc_geth: remove get_perm_addr from ucc_geth_ethtool.c This is needed because commit 313674afa8fdced2fe79f50f38e1c387b63d8790 inlines the generic function to the caller. Signed-off-by: Jan Altenberg Signed-off-by: Li Yang --- drivers/net/ucc_geth_ethtool.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index a8994c7b8583..64bef7c12365 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c @@ -379,7 +379,6 @@ static const struct ethtool_ops uec_ethtool_ops = { .get_stats_count = uec_get_stats_count, .get_strings = uec_get_strings, .get_ethtool_stats = uec_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; void uec_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.3 From bec494775600b1cd7c144d31a09e1f46df9c6324 Mon Sep 17 00:00:00 2001 From: Satyam Sharma Date: Fri, 3 Aug 2007 08:27:13 +0530 Subject: [MTD] Makefile fix for mtdsuper We want drivers/mtd/{mtdcore, mtdsuper, mtdpart}.c to be built and linked into the same mtd.ko module. Fix the Makefile to ensure this, and remove duplicate MODULE_ declarations in mtdpart.c, as mtdcore.c already has them. Signed-off-by: Satyam Sharma Signed-off-by: David Woodhouse --- drivers/mtd/Makefile | 2 +- drivers/mtd/mtdpart.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 451adcc52b3c..6d958a4566ff 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -3,9 +3,9 @@ # # Core functionality. +obj-$(CONFIG_MTD) += mtd.o mtd-y := mtdcore.o mtdsuper.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o -obj-$(CONFIG_MTD) += $(mtd-y) obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 9c6236852942..6174a97d7902 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -560,7 +560,3 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, EXPORT_SYMBOL_GPL(parse_mtd_partitions); EXPORT_SYMBOL_GPL(register_mtd_parser); EXPORT_SYMBOL_GPL(deregister_mtd_parser); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nicolas Pitre "); -MODULE_DESCRIPTION("Generic support for partitioning of MTD devices"); -- cgit v1.2.3 From 66dbfbe6fde35c881deda5cebb6ecaa0dcc1c975 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 5 Aug 2007 06:08:38 -0400 Subject: [SCSI] lpfc : scsi command accessor fix for 8.2.2 It was pointed out by Boaz Harrosh that our 8.2.2 lpfc patches revert a change to using SCSI command accessor functions. This patch, to be applied on top of the 8.2.2. patches, updates the driver for the accessor functions. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 94458d7a8f7f..17d7dc05149b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -499,7 +499,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, "0717 FCP command x%x residual " "underrun converted to error " "Data: x%x x%x x%x\n", - cmnd->cmnd[0], cmnd->request_bufflen, + cmnd->cmnd[0], scsi_bufflen(cmnd), scsi_get_resid(cmnd), cmnd->underflow); host_status = DID_ERROR; } -- cgit v1.2.3 From 36026ecc20e5df722bbe2ea9e451c73d686ef107 Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Mon, 23 Jul 2007 10:07:42 +0300 Subject: IB/core: Ignore membership bit in ib_find_pkey() ib_find_pkey() is used as a replacement for ib_find_cached_pkey(), and the original function ignored the membership bit when searching for a P_Key, so ib_find_pkey() should ignore the bit too. In particular, IPoIB turns on the P_Key membership bit of limited membership P_Keys when creating a child interface and looks for the full membership P_key. This broke if a port was a partial member of a partition when IPoIB switched from ib_find_cached_pkey() to ib_find_pkey(), and this change fixes things again. Signed-off-by: Moni Shoua Signed-off-by: Roland Dreier --- drivers/infiniband/core/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 3ada17c0f239..2506c43ba041 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -702,7 +702,7 @@ int ib_find_pkey(struct ib_device *device, if (ret) return ret; - if (pkey == tmp_pkey) { + if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) { *index = i; return 0; } -- cgit v1.2.3 From 5399891052badf97948098d01772113801f6ef58 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/sa: Don't need to check for default P_Key twice Now that ib_find_pkey() ignores the membership bit of P_Keys, there's no need for ib_sa to look for both 0x7fff and 0xffff in a port's P_Key table. Signed-off-by: Roland Dreier --- drivers/infiniband/core/sa_query.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 20ab6b3e484d..d271bd715c12 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -385,9 +385,7 @@ static void update_sm_ah(struct work_struct *work) new_ah->pkey_index = 0; if (ib_find_pkey(port->agent->device, port->port_num, - IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) && - ib_find_pkey(port->agent->device, port->port_num, - IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index)) + IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index)) printk(KERN_ERR "Couldn't find index for default PKey\n"); memset(&ah_attr, 0, sizeof ah_attr); -- cgit v1.2.3 From 445d68070c9c02acdda38e6d69bd43096f521035 Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/mad: Fix error path if response alloc fails in ib_mad_recv_done_handler() If ib_mad_recv_done_handler() fails to allocate response, then it just printed a warning and continued, which leads to an oops if the MAD is being handled for a switch device, because the switch code uses response without checking for NULL. Fix this by bailing out of the function if the allocation fails. Signed-off-by: Suresh Shelvapille Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index bc547f1d34ba..969785762052 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1842,16 +1842,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, { struct ib_mad_qp_info *qp_info; struct ib_mad_private_header *mad_priv_hdr; - struct ib_mad_private *recv, *response; + struct ib_mad_private *recv, *response = NULL; struct ib_mad_list_head *mad_list; struct ib_mad_agent_private *mad_agent; int port_num; - response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); - if (!response) - printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " - "for response buffer\n"); - mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; qp_info = mad_list->mad_queue->qp_info; dequeue_mad(mad_list); @@ -1879,6 +1874,13 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num)) goto out; + response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); + if (!response) { + printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " + "for response buffer\n"); + goto out; + } + if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) port_num = wc->port_num; else -- cgit v1.2.3 From 86dfbecdea733a6e940b958e94a85af45b89a0b9 Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/mad: Fix memory leak in switch handling in ib_mad_recv_done_handler() If agent_send_response() returns an error, we shouldn't do anything differently than if it succeeds; setting response to NULL just means that the response buffer gets leaked. Signed-off-by: Suresh Shelvapille Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 969785762052..6f4287716ab1 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1916,12 +1916,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, response->header.recv_wc.recv_buf.mad = &response->mad.mad; response->header.recv_wc.recv_buf.grh = &response->grh; - if (!agent_send_response(&response->mad.mad, - &response->grh, wc, - port_priv->device, - smi_get_fwd_port(&recv->mad.smp), - qp_info->qp->qp_num)) - response = NULL; + agent_send_response(&response->mad.mad, + &response->grh, wc, + port_priv->device, + smi_get_fwd_port(&recv->mad.smp), + qp_info->qp->qp_num); goto out; } -- cgit v1.2.3 From 8fc394b1971241999ef9b022feabf6a164791e3f Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/mad: agent_send_response() should be void Nothing looks at the return value of agent_send_response(), so there's no point in returning anything. Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier --- drivers/infiniband/core/agent.c | 24 ++++++++++-------------- drivers/infiniband/core/agent.h | 6 +++--- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index db2633e4aae6..ae7c2880e624 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c @@ -78,15 +78,14 @@ ib_get_agent_port(struct ib_device *device, int port_num) return entry; } -int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, - struct ib_wc *wc, struct ib_device *device, - int port_num, int qpn) +void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn) { struct ib_agent_port_private *port_priv; struct ib_mad_agent *agent; struct ib_mad_send_buf *send_buf; struct ib_ah *ah; - int ret; struct ib_mad_send_wr_private *mad_send_wr; if (device->node_type == RDMA_NODE_IB_SWITCH) @@ -96,23 +95,21 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, if (!port_priv) { printk(KERN_ERR SPFX "Unable to find port agent\n"); - return -ENODEV; + return; } agent = port_priv->agent[qpn]; ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); if (IS_ERR(ah)) { - ret = PTR_ERR(ah); - printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret); - return ret; + printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n"); + return; } send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, GFP_KERNEL); if (IS_ERR(send_buf)) { - ret = PTR_ERR(send_buf); - printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret); + printk(KERN_ERR SPFX "ib_create_send_mad error\n"); goto err1; } @@ -126,16 +123,15 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, mad_send_wr->send_wr.wr.ud.port_num = port_num; } - if ((ret = ib_post_send_mad(send_buf, NULL))) { - printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret); + if (ib_post_send_mad(send_buf, NULL)) { + printk(KERN_ERR SPFX "ib_post_send_mad error\n"); goto err2; } - return 0; + return; err2: ib_free_send_mad(send_buf); err1: ib_destroy_ah(ah); - return ret; } static void agent_send_handler(struct ib_mad_agent *mad_agent, diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index 86d72fab37b0..fb9ed1489f95 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h @@ -46,8 +46,8 @@ extern int ib_agent_port_open(struct ib_device *device, int port_num); extern int ib_agent_port_close(struct ib_device *device, int port_num); -extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, - struct ib_wc *wc, struct ib_device *device, - int port_num, int qpn); +extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn); #endif /* __AGENT_H_ */ -- cgit v1.2.3 From 38d5af9565f3fa1bf258f3eaeb47c4a95fd7a2b2 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 31 Jul 2007 15:10:54 -0700 Subject: IB/mad: Fix address handle leak in mad_rmpp The address handle associated with dual-sided RMPP direction switch ACKs is never destroyed. Free the AH for ACKs which fall into this category. Problem was reported by Dotan Barak . Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad_rmpp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 3663fd7022be..d43bc62005b3 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -163,8 +163,10 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, hdr_len, 0, GFP_KERNEL); if (IS_ERR(msg)) ib_destroy_ah(ah); - else + else { msg->ah = ah; + msg->context[0] = ah; + } return msg; } @@ -197,9 +199,7 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent, void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) { - struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad; - - if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK) + if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah) ib_destroy_ah(mad_send_wc->send_buf->ah); ib_free_send_mad(mad_send_wc->send_buf); } -- cgit v1.2.3 From 92ddc447ce7382e36b72a240697c00bf4beb8d75 Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Wed, 1 Aug 2007 13:33:56 +0300 Subject: IB: Move the macro IB_UMEM_MAX_PAGE_CHUNK() to umem.c After moving the definition of struct ib_umem_chunk from ib_verbs.h to ib_umem.h there isn't any reason for the macro IB_UMEM_MAX_PAGE_CHUNK to stay in ib_verbs.h. Move the macro to umem.c, the only place where it is used. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier --- drivers/infiniband/core/umem.c | 5 +++++ include/rdma/ib_verbs.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 26d0470eef6e..664d2faa9e74 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -40,6 +40,11 @@ #include "uverbs.h" +#define IB_UMEM_MAX_PAGE_CHUNK \ + ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \ + ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \ + (void *) &((struct ib_umem_chunk *) 0)->page_list[0])) + static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty) { struct ib_umem_chunk *chunk, *tmp; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 7a99f1125d24..4bea182d7116 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -733,11 +733,6 @@ struct ib_udata { size_t outlen; }; -#define IB_UMEM_MAX_PAGE_CHUNK \ - ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \ - ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \ - (void *) &((struct ib_umem_chunk *) 0)->page_list[0])) - struct ib_pd { struct ib_device *device; struct ib_uobject *uobject; -- cgit v1.2.3 From 699924b1e1ea3c9307eb582b9cc386e4af88aaae Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Sun, 29 Jul 2007 15:12:29 -0500 Subject: RDMA/cxgb3: Always call low level send function via cxgb3_ofld_send() This avoids deadlocks. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb3/iwch_cm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 9574088f0d4e..1cdfcd43b0bc 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -139,7 +139,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); skb->priority = CPL_PRIORITY_SETUP; - tdev->send(tdev, skb); + cxgb3_ofld_send(tdev, skb); return; } @@ -161,7 +161,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep) req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); skb->priority = CPL_PRIORITY_DATA; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -183,7 +183,7 @@ int iwch_resume_tid(struct iwch_ep *ep) req->val = 0; skb->priority = CPL_PRIORITY_DATA; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -784,7 +784,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); skb->priority = CPL_PRIORITY_ACK; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return credits; } @@ -1152,7 +1152,7 @@ static int listen_start(struct iwch_listen_ep *ep) req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); skb->priority = 1; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -1186,7 +1186,7 @@ static int listen_stop(struct iwch_listen_ep *ep) req->cpu_idx = 0; OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); skb->priority = 1; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -1264,7 +1264,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); rpl->opt2 = 0; rpl->rsvd = rpl->opt2; - tdev->send(tdev, skb); + cxgb3_ofld_send(tdev, skb); } } @@ -1557,7 +1557,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); rpl->cmd = CPL_ABORT_NO_RST; - ep->com.tdev->send(ep->com.tdev, rpl_skb); + cxgb3_ofld_send(ep->com.tdev, rpl_skb); if (state != ABORTING) { state_set(&ep->com, DEAD); release_ep_resources(ep); -- cgit v1.2.3 From 5d7cbfd63136e4469a896acfadb33e19ed62f068 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 3 Aug 2007 10:45:18 -0700 Subject: IB/srp: Wrap OUI checking for workarounds in helper functions Wrap the checking for Mellanox and Topspin OUIs to decide whether to use a workaround into helper functions. This will make it cleaner to add a new OUI to check (as we need to do now that some targets with a Cisco OUI still need the Topspin workarounds). Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index f01ca182f226..fb6c5798daf3 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -75,16 +75,12 @@ module_param(topspin_workarounds, int, 0444); MODULE_PARM_DESC(topspin_workarounds, "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); -static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; - static int mellanox_workarounds = 1; module_param(mellanox_workarounds, int, 0444); MODULE_PARM_DESC(mellanox_workarounds, "Enable workarounds for Mellanox SRP target bugs if != 0"); -static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; - static void srp_add_one(struct ib_device *device); static void srp_remove_one(struct ib_device *device); static void srp_completion(struct ib_cq *cq, void *target_ptr); @@ -108,6 +104,22 @@ static const char *srp_target_info(struct Scsi_Host *host) return host_to_target(host)->target_name; } +static int srp_target_is_topspin(struct srp_target_port *target) +{ + static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; + + return topspin_workarounds && + !memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui); +} + +static int srp_target_is_mellanox(struct srp_target_port *target) +{ + static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; + + return mellanox_workarounds && + !memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui); +} + static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, gfp_t gfp_mask, enum dma_data_direction direction) @@ -360,7 +372,7 @@ static int srp_send_req(struct srp_target_port *target) * zero out the first 8 bytes of our initiator port ID and set * the second 8 bytes to the local node GUID. */ - if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { + if (srp_target_is_topspin(target)) { printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " "activated for target GUID %016llx\n", (unsigned long long) be64_to_cpu(target->ioc_guid)); @@ -585,8 +597,8 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, if (!dev->fmr_pool) return -ENODEV; - if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) && - mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3)) + if (srp_target_is_mellanox(target) && + (ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask)) return -EINVAL; len = page_cnt = 0; @@ -1087,8 +1099,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, break; case IB_CM_REJ_PORT_REDIRECT: - if (topspin_workarounds && - !memcmp(&target->ioc_guid, topspin_oui, 3)) { + if (srp_target_is_topspin(target)) { /* * Topspin/Cisco SRP gateways incorrectly send * reject reason code 25 when they mean 24 -- cgit v1.2.3 From 3d1ff48da760968793f3c36672961ffd23088787 Mon Sep 17 00:00:00 2001 From: Raghava Kondapalli Date: Fri, 3 Aug 2007 10:45:18 -0700 Subject: IB/srp: Add OUI for new Cisco targets New Cisco IB SRP targets use the Cisco OUI 00-1b-0d but still need the Topspin workarounds. Add this OUI to srp_target_is_topspin(). Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index fb6c5798daf3..f6a051428144 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -107,9 +107,11 @@ static const char *srp_target_info(struct Scsi_Host *host) static int srp_target_is_topspin(struct srp_target_port *target) { static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; + static const u8 cisco_oui[3] = { 0x00, 0x1b, 0x0d }; return topspin_workarounds && - !memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui); + (!memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui) || + !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui)); } static int srp_target_is_mellanox(struct srp_target_port *target) -- cgit v1.2.3 From e84a02ba0b33a97a8486f3248fd45f50b1a1c014 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Sat, 4 Aug 2007 00:22:30 +0900 Subject: sony-laptop: restore the last user requested brightness level on resume. Signed-off-by: Mattia Dongili Signed-off-by: Len Brown --- drivers/misc/sony-laptop.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 14ee06c8f127..9a803e13c307 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -942,6 +942,11 @@ static int sony_nc_resume(struct acpi_device *device) } } + /* set the last requested brightness level */ + if (sony_backlight_device && + !sony_backlight_update_status(sony_backlight_device)) + printk(KERN_WARNING DRV_PFX "unable to restore brightness level"); + /* re-initialize models with specific requirements */ dmi_check_system(sony_nc_ids); -- cgit v1.2.3 From 11604ecf6fb9c2ab0152fbddb7ea2724438ef76e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 4 Aug 2007 00:22:31 +0900 Subject: sony-laptop: sony_nc_ids[] can become static. Signed-off-by: Adrian Bunk Signed-off-by: Mattia Dongili Signed-off-by: Len Brown --- drivers/misc/sony-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 9a803e13c307..91da6880ae93 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -845,7 +845,7 @@ static struct sony_nc_event sony_C_events[] = { }; /* SNC-only model map */ -struct dmi_system_id sony_nc_ids[] = { +static struct dmi_system_id sony_nc_ids[] = { { .ident = "Sony Vaio FE Series", .callback = sony_nc_C_enable, -- cgit v1.2.3 From f7b88ccb63188e775fe02e746c39ed177741cfc7 Mon Sep 17 00:00:00 2001 From: Eugene Teo Date: Sat, 4 Aug 2007 00:22:32 +0900 Subject: sonypi: fix ids member of struct acpi_driver ids member of struct acpi_driver is of type struct acpi_device_id, not a character array. Signed-off-by: Eugene Teo Signed-off-by: Mattia Dongili Signed-off-by: Len Brown --- drivers/char/sonypi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 73037a4d3c50..aeec67e27264 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1147,10 +1147,15 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type) return 0; } +const static struct acpi_device_id sonypi_device_ids[] = { + {"SNY6001", 0}, + {"", 0}, +}; + static struct acpi_driver sonypi_acpi_driver = { .name = "sonypi", .class = "hkey", - .ids = "SNY6001", + .ids = sonypi_device_ids, .ops = { .add = sonypi_acpi_add, .remove = sonypi_acpi_remove, -- cgit v1.2.3 From ac36393de6034be7266264a435360e7628849005 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 27 Jul 2007 17:04:40 -0300 Subject: ACPI: thinkpad-acpi: fix the module init failure path Thomas Renninger reports that if one tries to load thinkpad-acpi in a non-thinkpad, one gets: Call Trace: [] kref_get+0x2f/0x36 [] kobject_get+0x12/0x17 [] get_driver+0x14/0x1a [] driver_remove_file+0x11/0x32 [] :thinkpad_acpi:thinkpad_acpi_module_exit+0xa8/0xfc [] :thinkpad_acpi:thinkpad_acpi_module_init+0x74a/0x776 [] __link_module+0x0/0x25 [] sys_init_module+0x162c/0x178f [] system_call+0x7e/0x83 So, track if the platform driver and its driver attributes were registered, and only deallocate them in that case. This patch is based on Thomas Renninger's patch for the issue. Signed-off-by: Henrique de Moraes Holschuh Acked-by: Thomas Renninger Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 10 ++++++++-- drivers/misc/thinkpad_acpi.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index fa80f355e522..f6cd34a3dbac 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -4668,12 +4668,15 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } + tp_features.platform_drv_registered = 1; + ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); if (ret) { printk(IBM_ERR "unable to create sysfs driver attributes\n"); thinkpad_acpi_module_exit(); return ret; } + tp_features.platform_drv_attrs_registered = 1; /* Device initialization */ @@ -4756,8 +4759,11 @@ static void thinkpad_acpi_module_exit(void) if (tpacpi_pdev) platform_device_unregister(tpacpi_pdev); - tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); - platform_driver_unregister(&tpacpi_pdriver); + if (tp_features.platform_drv_attrs_registered) + tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); + + if (tp_features.platform_drv_registered) + platform_driver_unregister(&tpacpi_pdriver); if (proc_dir) remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 88af089d6494..eee8809a50d9 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h @@ -246,6 +246,8 @@ static struct { u16 wan:1; u16 fan_ctrl_status_undef:1; u16 input_device_registered:1; + u16 platform_drv_registered:1; + u16 platform_drv_attrs_registered:1; } tp_features; struct thinkpad_id_data { -- cgit v1.2.3 From de47b69c7b7be46b0848b2c4f8e23c478cd68690 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 29 Jul 2007 00:45:59 +0200 Subject: asus_acpi: fix possible double free (found by Coverity) Signed-off-by: Jesper Juhl Signed-off-by: Len Brown --- drivers/acpi/asus_acpi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 9c4bd220c44f..86fd142f4bf3 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1192,6 +1192,7 @@ static int asus_hotk_get_info(void) break; default: kfree(model); + model = NULL; break; } } -- cgit v1.2.3 From 3fc701d5d459f3b83ba874613048d36e91debca2 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Wed, 1 Aug 2007 21:39:32 -0700 Subject: [CG6]: fix memory size detection This patch fixes memory size detection on the CG6 card. The 1MB TGX card has dblbuf property set to 0. Signed-off-by: Krzysztof Helt Signed-off-by: David S. Miller --- drivers/video/cg6.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 87c747123538..ee9046db9c7d 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -677,6 +677,7 @@ static int __devinit cg6_probe(struct of_device *op, const struct of_device_id * struct fb_info *info; struct cg6_par *par; int linebytes, err; + int dblbuf; info = framebuffer_alloc(sizeof(struct cg6_par), &op->dev); @@ -698,7 +699,9 @@ static int __devinit cg6_probe(struct of_device *op, const struct of_device_id * linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); - if (of_find_property(dp, "dblbuf", NULL)) + + dblbuf = of_getintprop_default(dp, "dblbuf", 0); + if (dblbuf) par->fbsize *= 4; par->fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET, -- cgit v1.2.3 From f1cd1fe61b96e4312312d42c0a9784dfab12e007 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 3 Aug 2007 17:28:17 -0400 Subject: ACPI: EC: Remove noisy debug printk fron EC driver. ACPI: EC: Handler for query 0x57 is not found! Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 469f3f57f881..dd384ec757dd 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -471,7 +471,6 @@ static void acpi_ec_gpe_query(void *ec_cxt) } } mutex_unlock(&ec->lock); - printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value); } static u32 acpi_ec_gpe_handler(void *data) -- cgit v1.2.3 From 198919151dea65d83dd0fb66979b1df28402f2b0 Mon Sep 17 00:00:00 2001 From: Vu Pham Date: Fri, 3 Aug 2007 14:25:48 -0700 Subject: IB/mlx4: Fix opcode returned in RDMA read completion Current code has a cut-and-paste error and returns IB_WC_SEND when it should return IB_WC_RDMA_READ. Signed-off-by: Vu Pham Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx4/cq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 660b27aecae5..8bf44daf45ec 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -389,7 +389,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, wc->opcode = IB_WC_SEND; break; case MLX4_OPCODE_RDMA_READ: - wc->opcode = IB_WC_SEND; + wc->opcode = IB_WC_RDMA_READ; wc->byte_len = be32_to_cpu(cqe->byte_cnt); break; case MLX4_OPCODE_ATOMIC_CS: -- cgit v1.2.3 From 3bd92ba19a89fe61ebf58804f9c8675372f50c1c Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 3 Aug 2007 17:38:20 -0400 Subject: ACPI: Battery: Synchronize battery operations. http://bugzilla.kernel.org/show_bug.cgi?id=8768 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/battery.c | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 81651032791b..d7b499fe0cd9 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -113,7 +113,7 @@ struct acpi_battery_info { acpi_string oem_info; }; -enum acpi_battery_files{ +enum acpi_battery_files { ACPI_BATTERY_INFO = 0, ACPI_BATTERY_STATE, ACPI_BATTERY_ALARM, @@ -129,13 +129,14 @@ struct acpi_battery_flags { }; struct acpi_battery { - struct mutex mutex; struct acpi_device *device; struct acpi_battery_flags flags; struct acpi_buffer bif_data; struct acpi_buffer bst_data; + struct mutex lock; unsigned long alarm; unsigned long update_time[ACPI_BATTERY_NUMFILES]; + }; inline int acpi_battery_present(struct acpi_battery *battery) @@ -235,10 +236,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) return 0; /* Evaluate _BIF */ - - status = - acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, - &buffer); + mutex_lock(&battery->lock); + status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", + NULL, &buffer); + mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); return -ENODEV; @@ -285,10 +286,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) return 0; /* Evaluate _BST */ - - status = - acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, - &buffer); + mutex_lock(&battery->lock); + status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", + NULL, &buffer); + mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); return -ENODEV; @@ -336,9 +337,10 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, arg0.integer.value = alarm; - status = - acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", + mutex_lock(&battery->lock); + status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", &arg_list, NULL); + mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) return -ENODEV; @@ -658,8 +660,6 @@ acpi_battery_write_alarm(struct file *file, if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; - mutex_lock(&battery->mutex); - result = acpi_battery_update(battery, 1, &update_result); if (result) { result = -ENODEV; @@ -688,9 +688,7 @@ acpi_battery_write_alarm(struct file *file, acpi_battery_check_result(battery, result); if (!result) - result = count; - - mutex_unlock(&battery->mutex); + return count; return result; } @@ -714,8 +712,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq) int update_result = ACPI_BATTERY_NONE_UPDATE; int update = 0; - mutex_lock(&battery->mutex); - update = (get_seconds() - battery->update_time[fid] >= update_time); update = (update | battery->flags.update[fid]); @@ -733,7 +729,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq) result = acpi_read_funcs[fid].print(seq, result); acpi_battery_check_result(battery, result); battery->flags.update[fid] = result; - mutex_unlock(&battery->mutex); return result; } @@ -897,10 +892,7 @@ static int acpi_battery_add(struct acpi_device *device) if (!battery) return -ENOMEM; - mutex_init(&battery->mutex); - - mutex_lock(&battery->mutex); - + mutex_init(&battery->lock); battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); @@ -936,7 +928,6 @@ static int acpi_battery_add(struct acpi_device *device) kfree(battery); } - mutex_unlock(&battery->mutex); return result; } @@ -951,8 +942,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type) battery = acpi_driver_data(device); - mutex_lock(&battery->mutex); - status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); @@ -963,9 +952,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) kfree(battery->bst_data.pointer); - mutex_unlock(&battery->mutex); - - mutex_destroy(&battery->mutex); + mutex_destroy(&battery->lock); kfree(battery); -- cgit v1.2.3 From cd8c93a4e04dce8f00d1ef3a476aac8bd65ae40b Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 3 Aug 2007 17:52:48 -0400 Subject: ACPI: EC: If ECDT is not found, look up EC in DSDT. Some ASUS laptops access EC space from device _INI methods, but do not provide ECDT for early EC setup. In order to make them function properly, there is a need to find EC is DSDT before any _INI is called. Similar functionality was turned on by acpi_fake_ecdt=1 command line before. Now it is on all the time. http://bugzilla.kernel.org/show_bug.cgi?id=8598 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index dd384ec757dd..4d7fe829a6e2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -664,30 +664,32 @@ acpi_ec_register_query_methods(acpi_handle handle, u32 level, return AE_OK; } -static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle) +static acpi_status +ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) { - if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS, - ec_parse_io_ports, ec))) - return -EINVAL; + acpi_status status; + + struct acpi_ec *ec = context; + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + ec_parse_io_ports, ec); + if (ACPI_FAILURE(status)) + return status; /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ - if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe))) - return -EINVAL; + status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); + if (ACPI_FAILURE(status)) + return status; /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); - /* Find and register all query methods */ - acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, - acpi_ec_register_query_methods, ec, NULL); - ec->handle = handle; printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", ec->gpe, ec->command_addr, ec->data_addr); - return 0; + return AE_CTRL_TERMINATE; } static int acpi_ec_add(struct acpi_device *device) @@ -704,7 +706,8 @@ static int acpi_ec_add(struct acpi_device *device) if (!ec) return -ENOMEM; - if (ec_parse_device(ec, device->handle)) { + if (ec_parse_device(device->handle, 0, ec, NULL) != + AE_CTRL_TERMINATE) { kfree(ec); return -EINVAL; } @@ -867,18 +870,21 @@ int __init acpi_ec_ecdt_probe(void) /* * Generate a boot ec context */ - status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); - if (ACPI_FAILURE(status)) - goto error; - - printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); - - boot_ec->command_addr = ecdt_ptr->control.address; - boot_ec->data_addr = ecdt_ptr->data.address; - boot_ec->gpe = ecdt_ptr->gpe; - boot_ec->handle = ACPI_ROOT_OBJECT; + if (ACPI_SUCCESS(status)) { + printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n"); + boot_ec->command_addr = ecdt_ptr->control.address; + boot_ec->data_addr = ecdt_ptr->data.address; + boot_ec->gpe = ecdt_ptr->gpe; + boot_ec->handle = ACPI_ROOT_OBJECT; + } else { + printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); + status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, + boot_ec, NULL); + if (ACPI_FAILURE(status)) + goto error; + } ret = ec_install_handlers(boot_ec); if (!ret) { -- cgit v1.2.3 From 52fe4bdf40bc07498c5f7935551774e8f8458190 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 3 Aug 2007 17:55:53 -0400 Subject: ACPI: EC: fix build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/acpi/ec.c:657: warning: ‘acpi_ec_register_query_methods’ defined but not used Signed-off-by: Len Brown --- drivers/acpi/ec.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 4d7fe829a6e2..629289034b61 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -651,19 +651,6 @@ static struct acpi_ec *make_acpi_ec(void) return ec; } -static acpi_status -acpi_ec_register_query_methods(acpi_handle handle, u32 level, - void *context, void **return_value) -{ - struct acpi_namespace_node *node = handle; - struct acpi_ec *ec = context; - int value = 0; - if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { - acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); - } - return AE_OK; -} - static acpi_status ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) { -- cgit v1.2.3 From 7c010de7506954e973abfab5c5999c5a97f7a73e Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 3 Aug 2007 17:57:53 -0400 Subject: ACPI: EC: Switch from boot_ec as soon as we find its desc in DSDT. Some ASUS laptops fail to use boot time EC and need to eventually switch to one described in DSDT. http://bugzilla.kernel.org/show_bug.cgi?id=8709 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 629289034b61..71caa7d983a3 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -679,6 +679,14 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) return AE_CTRL_TERMINATE; } +static void ec_remove_handlers(struct acpi_ec *ec) +{ + acpi_remove_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler); + acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); +} + static int acpi_ec_add(struct acpi_device *device) { struct acpi_ec *ec = NULL; @@ -702,16 +710,15 @@ static int acpi_ec_add(struct acpi_device *device) /* Check if we found the boot EC */ if (boot_ec) { if (boot_ec->gpe == ec->gpe) { - /* We might have incorrect info for GL at boot time */ mutex_lock(&boot_ec->lock); - boot_ec->global_lock = ec->global_lock; - /* Copy handlers from new ec into boot ec */ - list_splice(&ec->list, &boot_ec->list); + ec_remove_handlers(boot_ec); mutex_unlock(&boot_ec->lock); - kfree(ec); - ec = boot_ec; + mutex_destroy(&boot_ec->lock); + kfree(boot_ec); + first_ec = boot_ec = NULL; } - } else + } + if (!first_ec) first_ec = ec; ec->handle = device->handle; acpi_driver_data(device) = ec; @@ -740,9 +747,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type) if (ec == first_ec) first_ec = NULL; - /* Don't touch boot EC */ - if (boot_ec != ec) - kfree(ec); return 0; } @@ -806,9 +810,7 @@ static int acpi_ec_start(struct acpi_device *device) if (!ec) return -EINVAL; - /* Boot EC is already working */ - if (ec != boot_ec) - ret = ec_install_handlers(ec); + ret = ec_install_handlers(ec); /* EC is fully operational, allow queries */ atomic_set(&ec->query_pending, 0); @@ -818,7 +820,6 @@ static int acpi_ec_start(struct acpi_device *device) static int acpi_ec_stop(struct acpi_device *device, int type) { - acpi_status status; struct acpi_ec *ec; if (!device) @@ -827,21 +828,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type) ec = acpi_driver_data(device); if (!ec) return -EINVAL; - - /* Don't touch boot EC */ - if (ec == boot_ec) - return 0; - - status = acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, - &acpi_ec_space_handler); - if (ACPI_FAILURE(status)) - return -ENODEV; - - status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); - if (ACPI_FAILURE(status)) - return -ENODEV; - + ec_remove_handlers(ec); return 0; } -- cgit v1.2.3 From b6b1d87785712474d0ed80689c17107d616a1171 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Fri, 3 Aug 2007 16:07:43 +0200 Subject: serial: fix 8250 early console setup the early setup function serial8250_console_early_setup() can be called from non __init code (eg. hotpluggable serial ports like serial_cs) so remove the __init from the call chain to avoid crashes. Signed-off-by: Daniel Ritz Cc: Yinghai Lu Signed-off-by: Linus Torvalds --- drivers/serial/8250.c | 2 +- drivers/serial/8250_early.c | 2 +- kernel/printk.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 2f5a5ac1b271..301313002f6b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2514,7 +2514,7 @@ static int __init serial8250_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -static int __init serial8250_console_early_setup(void) +static int serial8250_console_early_setup(void) { return serial8250_find_port_for_earlycon(); } diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index 150cad5c2eba..4d4c9f01be8d 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c @@ -227,7 +227,7 @@ int __init setup_early_serial8250_console(char *cmdline) return 0; } -int __init serial8250_find_port_for_earlycon(void) +int serial8250_find_port_for_earlycon(void) { struct early_serial8250_device *device = &early_device; struct uart_port *port = &device->port; diff --git a/kernel/printk.c b/kernel/printk.c index 051d27e36a6c..bd2cd062878d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -732,7 +732,7 @@ int __init add_preferred_console(char *name, int idx, char *options) return 0; } -int __init update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options) +int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options) { struct console_cmdline *c; int i; -- cgit v1.2.3 From 3e847423bf029c2170692c75580a856debed617b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 2 Aug 2007 19:21:30 +0100 Subject: fix s2io regression * wrong argument passed to pci_unmap_single() on failure exit paths * leak in the same area Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/s2io.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2be0a0f1b48f..24feb00600ee 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2430,7 +2430,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { pci_unmap_single (nic->pdev, - (dma_addr_t)skb->data, + (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); goto pci_map_failed; @@ -6211,7 +6211,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, if( (rxdp3->Buffer0_ptr == 0) || (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { pci_unmap_single (sp->pdev, - (dma_addr_t)(*skb)->data, + (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); goto memalloc_failed; } @@ -6224,7 +6224,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, if( (rxdp3->Buffer1_ptr == 0) || (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { pci_unmap_single (sp->pdev, - (dma_addr_t)(*skb)->data, + (dma_addr_t)rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single (sp->pdev, + (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); goto memalloc_failed; } -- cgit v1.2.3 From 07ddf768d860bee7bd6581b7af3ce1009dbd05d0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 29 Jul 2007 17:00:37 +0200 Subject: ACPI: EC: acpi_ec_remove(): fix use-after-free This patch fixes an obvious use-after-free introduced by commit 837012ede14a8fc088be3682c964da7fc6af026b. Spotted by the Coverity checker. Signed-off-by: Adrian Bunk Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 71caa7d983a3..b649ac7122a5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -730,14 +730,14 @@ static int acpi_ec_add(struct acpi_device *device) static int acpi_ec_remove(struct acpi_device *device, int type) { struct acpi_ec *ec; - struct acpi_ec_query_handler *handler; + struct acpi_ec_query_handler *handler, *tmp; if (!device) return -EINVAL; ec = acpi_driver_data(device); mutex_lock(&ec->lock); - list_for_each_entry(handler, &ec->list, node) { + list_for_each_entry_safe(handler, tmp, &ec->list, node) { list_del(&handler->node); kfree(handler); } -- cgit v1.2.3 From bc90a0105dea7b773e99ae7abde56a6930081ddb Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 9 Jul 2007 11:33:15 -0700 Subject: ACPI: sbs: remove dead code Remove dead code spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 7d8e78ea13a5..82c3a550016d 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -1415,7 +1415,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) char dir_name[32]; int do_battery_init = 0, do_ac_init = 0; int old_remaining_capacity = 0; - int update_ac = 1, update_battery = 1; + int update_battery = 1; int up_tm = update_time; if (sbs_zombie(sbs)) { @@ -1435,10 +1435,6 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) sbs->run_cnt++; - if (!update_ac && !update_battery) { - goto end; - } - old_ac_present = sbs->ac.ac_present; result = acpi_ac_get_present(sbs); -- cgit v1.2.3 From 0a5245099819b0ae0a8e985f54909ba8414faba5 Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Thu, 26 Jul 2007 12:56:55 +0300 Subject: ACPI: EC: fix run-together printk lines Signed-off-by: Meelis Roos Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index b649ac7122a5..b28b56524f0b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -673,7 +673,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) ec->handle = handle; - printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", + printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); return AE_CTRL_TERMINATE; -- cgit v1.2.3 From 3e0c95fd648c0d3175b9ff2232597d0b02eb7d46 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 3 Aug 2007 20:56:54 -0700 Subject: [TG3]: Fix suspend/resume problem. Joachim Deguara reported that tg3 devices would not resume properly if the device was shutdown before the system was suspended. In such scenario where the netif_running state is 0, tg3_suspend() would not save the PCI state and so the memory enable bit and bus master enable bit would be lost. We fix this by always saving and restoring the PCI state in tg3_suspend() and tg3_resume() regardless of netif_running() state. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index dc41c055ebb5..58740428dd07 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -64,8 +64,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.79" -#define DRV_MODULE_RELDATE "July 18, 2007" +#define DRV_MODULE_VERSION "3.80" +#define DRV_MODULE_RELDATE "August 2, 2007" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -12111,6 +12111,12 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) struct tg3 *tp = netdev_priv(dev); int err; + /* PCI register 4 needs to be saved whether netif_running() or not. + * MSI address and data need to be saved if using MSI and + * netif_running(). + */ + pci_save_state(pdev); + if (!netif_running(dev)) return 0; @@ -12130,9 +12136,6 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tg3_full_unlock(tp); - /* Save MSI address and data for resume. */ - pci_save_state(pdev); - err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); if (err) { tg3_full_lock(tp, 0); @@ -12160,11 +12163,11 @@ static int tg3_resume(struct pci_dev *pdev) struct tg3 *tp = netdev_priv(dev); int err; + pci_restore_state(tp->pdev); + if (!netif_running(dev)) return 0; - pci_restore_state(tp->pdev); - err = tg3_set_power_state(tp, PCI_D0); if (err) return err; -- cgit v1.2.3 From 6caebb02294b503c5eced4a3f90e6166548ce879 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 3 Aug 2007 20:57:25 -0700 Subject: [BNX2]: Fix suspend/resume problem. The device would not resume properly if it was shutdown before the system was suspended. In such scenario where the netif_running state is 0, bnx2_suspend() would not save the PCI state and so the memory enable bit and bus master enable bit would be lost. We fix this by always saving and restoring the PCI state in bnx2_suspend() and bnx2_resume() regardless of netif_running() state. Update version to 1.6.4. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d53dfc5bbae0..24e7f9ab3f5a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -54,8 +54,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.6.3" -#define DRV_MODULE_RELDATE "July 16, 2007" +#define DRV_MODULE_VERSION "1.6.4" +#define DRV_MODULE_RELDATE "August 3, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -6937,6 +6937,11 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) struct bnx2 *bp = netdev_priv(dev); u32 reset_code; + /* PCI register 4 needs to be saved whether netif_running() or not. + * MSI address and data need to be saved if using MSI and + * netif_running(). + */ + pci_save_state(pdev); if (!netif_running(dev)) return 0; @@ -6952,7 +6957,6 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; bnx2_reset_chip(bp, reset_code); bnx2_free_skbs(bp); - pci_save_state(pdev); bnx2_set_power_state(bp, pci_choose_state(pdev, state)); return 0; } @@ -6963,10 +6967,10 @@ bnx2_resume(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct bnx2 *bp = netdev_priv(dev); + pci_restore_state(pdev); if (!netif_running(dev)) return 0; - pci_restore_state(pdev); bnx2_set_power_state(bp, PCI_D0); netif_device_attach(dev); bnx2_init_nic(bp); -- cgit v1.2.3 From 03a5743a12b58e10eaa936a02498539db645ba4e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 3 Aug 2007 16:41:11 -0500 Subject: [SCSI] sd: disentangle barriers in SCSI Our current implementation has a generic set of barrier functions that go through the SCSI driver model. Realistically, this is unnecessary, because the only device that can use barriers (sd) can set the flush functions up at probe or revalidate time. This patch pulls the barrier functions out of the mid layer and scsi driver model and relocates them directly in sd. Acked-by: Tejun Heo Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 17 ----------------- drivers/scsi/sd.c | 14 +++++++++++--- include/scsi/scsi_driver.h | 2 -- include/scsi/sd.h | 2 -- 4 files changed, 11 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 21c075d44db1..a417a6ff9f97 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1038,22 +1038,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd) return BLKPREP_KILL; } -static int scsi_issue_flush_fn(struct request_queue *q, struct gendisk *disk, - sector_t *error_sector) -{ - struct scsi_device *sdev = q->queuedata; - struct scsi_driver *drv; - - if (sdev->sdev_state != SDEV_RUNNING) - return -ENXIO; - - drv = *(struct scsi_driver **) disk->private_data; - if (drv->issue_flush) - return drv->issue_flush(&sdev->sdev_gendev, error_sector); - - return -EOPNOTSUPP; -} - static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, struct request *req) { @@ -1596,7 +1580,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) return NULL; blk_queue_prep_rq(q, scsi_prep_fn); - blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); blk_queue_softirq_done(q, scsi_softirq_done); return q; } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e21c7142a3ea..2c6116fd4578 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -241,7 +241,6 @@ static struct scsi_driver sd_template = { }, .rescan = sd_rescan, .init_command = sd_init_command, - .issue_flush = sd_issue_flush, }; /* @@ -800,10 +799,17 @@ static int sd_sync_cache(struct scsi_disk *sdkp) return 0; } -static int sd_issue_flush(struct device *dev, sector_t *error_sector) +static int sd_issue_flush(struct request_queue *q, struct gendisk *disk, + sector_t *error_sector) { int ret = 0; - struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); + struct scsi_device *sdp = q->queuedata; + struct scsi_disk *sdkp; + + if (sdp->sdev_state != SDEV_RUNNING) + return -ENXIO; + + sdkp = scsi_disk_get_from_dev(&sdp->sdev_gendev); if (!sdkp) return -ENODEV; @@ -1663,6 +1669,8 @@ static int sd_probe(struct device *dev) sd_revalidate_disk(gd); + blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); + gd->driverfs_dev = &sdp->sdev_gendev; gd->flags = GENHD_FL_DRIVERFS; if (sdp->removable) diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 02e26c1672bf..3465f31a21c4 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -13,8 +13,6 @@ struct scsi_driver { int (*init_command)(struct scsi_cmnd *); void (*rescan)(struct device *); - int (*issue_flush)(struct device *, sector_t *); - int (*prepare_flush)(struct request_queue *, struct request *); }; #define to_scsi_driver(drv) \ container_of((drv), struct scsi_driver, gendrv) diff --git a/include/scsi/sd.h b/include/scsi/sd.h index 78583fee0ab2..ce02ad1f5185 100644 --- a/include/scsi/sd.h +++ b/include/scsi/sd.h @@ -56,8 +56,6 @@ static int sd_suspend(struct device *dev, pm_message_t state); static int sd_resume(struct device *dev); static void sd_rescan(struct device *); static int sd_init_command(struct scsi_cmnd *); -static int sd_issue_flush(struct device *, sector_t *); -static void sd_prepare_flush(struct request_queue *, struct request *); static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); static void scsi_disk_release(struct class_device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); -- cgit v1.2.3 From 50535df3ee3d3407ff61044692942288df7fcd6a Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 29 Jul 2007 22:16:14 +0300 Subject: [SCSI] aha152x: fix debug mode symbol conflict The symbol conflicts with the rather global one in include/linux/locks.h. Signed-off-by: Randy Dunlap Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 10 +++++----- drivers/scsi/aha152x.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 85f2394ffc3e..0afc0c965333 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -289,18 +289,18 @@ static LIST_HEAD(aha152x_host_list); if(spin_is_locked(&QLOCK)) { \ DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ } \ - DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ spin_lock_irqsave(&QLOCK,flags); \ - DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ QLOCKER=__FUNCTION__; \ QLOCKERL=__LINE__; \ } while(0) #define DO_UNLOCK(flags) \ do { \ - DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ spin_unlock_irqrestore(&QLOCK,flags); \ - DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ QLOCKER="(not locked)"; \ QLOCKERL=0; \ } while(0) @@ -3395,7 +3395,7 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start PDEBUG(debug_datai, "data in"); PDEBUG(debug_datao, "data out"); PDEBUG(debug_eh, "eh"); - PDEBUG(debug_locks, "locks"); + PDEBUG(debug_locking, "locks"); PDEBUG(debug_phases, "phases"); SPRINTF("\n"); diff --git a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h index d2add24d02a3..ac4bfa438bf2 100644 --- a/drivers/scsi/aha152x.h +++ b/drivers/scsi/aha152x.h @@ -298,7 +298,7 @@ typedef union { enum { debug_procinfo = 0x0001, debug_queue = 0x0002, - debug_locks = 0x0004, + debug_locking = 0x0004, debug_intr = 0x0008, debug_selection = 0x0010, debug_msgo = 0x0020, -- cgit v1.2.3 From b1ee0795276f976118f832313488e6daf83ff542 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 29 Jul 2007 22:18:20 +0300 Subject: [SCSI] aha152x: use bounce buffer Cause highmem buffers to be bounced to low memory until this driver supports highmem addresses. Otherwise it just oopses on NULL buffer addresses. Signed-off-by: Randy Dunlap Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 0afc0c965333..c841f11f4e32 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -3474,6 +3474,12 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start return thislength < length ? thislength : length; } +static int aha152x_adjust_queue(struct scsi_device *device) +{ + blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); + return 0; +} + static struct scsi_host_template aha152x_driver_template = { .module = THIS_MODULE, .name = AHA152X_REVID, @@ -3490,6 +3496,7 @@ static struct scsi_host_template aha152x_driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, + .slave_alloc = aha152x_adjust_queue, }; #if !defined(PCMCIA) -- cgit v1.2.3 From 0ceb47987d31f8529c60f1e802e0523fcde9492c Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 29 Jul 2007 22:22:04 +0300 Subject: [SCSI] aha152x: preliminary fixes and some comments hunk by hunk: - CHECK_CONDITION is what happens to cmnd->status >> 1 or after status_byte() macro. But here it is used directly on status which means 0x1 which is an undefined bit in the standard. And is a status that will never return from a target. - in busfree_run at the DONE_SC phase we have 3 distinct operation: 1-if(DONE_SC->SCp.phase & check_condition) The REQUEST_SENSE command return. - Restore original command - Than continue to operation 3. 2-if(DONE_SC->SCp.Status==SAM_STAT_CHECK_CONDITION) A regular command returned with a status. - Internally re-Q a REQUEST_SENSE. - Do not do operation 3. 3- - Complete the command and return it to scsi-ml So the 0x2 in both these operations (1,2) means the scsi check-condition status, hence SAM_STAT_CHECK_CONDITION - Here the code asks about !(DONE_SC->SCp.Status & not_issued) but "not_issued" is an enum belonging to the "phase" member and not to the Status returned from target. The reason this works is because not_issued==1 and Also CHECK_CONDITION==1 (remember from hunk 1). So actually the code was asking !(DONE_SC->SCp.Status & CHECK_CONDITION). Which means "Has the status been read from target yet?" Staus is read at status_run(). "not_issued" is cleared in seldo_run() which is usually earlier than status_run(). So this patch does nothing as far as assembly is concerned but it does let the reader understand what is going on. Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index c841f11f4e32..dc7d84bae96b 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -986,7 +986,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, SCpnt->scsi_done = done; SCpnt->resid = SCpnt->request_bufflen; SCpnt->SCp.phase = not_issued | phase; - SCpnt->SCp.Status = CHECK_CONDITION; + SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */ SCpnt->SCp.Message = 0; SCpnt->SCp.have_data_in = 0; SCpnt->SCp.sent_command = 0; @@ -1574,12 +1574,12 @@ static void busfree_run(struct Scsi_Host *shpnt) cmd->use_sg = sc->use_sg; cmd->cmd_len = sc->cmd_len; - cmd->SCp.Status = 0x02; + cmd->SCp.Status = SAM_STAT_CHECK_CONDITION; HOSTDATA(shpnt)->commands--; if (!HOSTDATA(shpnt)->commands) SETPORT(PORTA, 0); /* turn led off */ - } else if(DONE_SC->SCp.Status==0x02) { + } else if(DONE_SC->SCp.Status==SAM_STAT_CHECK_CONDITION) { #if defined(AHA152X_STAT) HOSTDATA(shpnt)->busfree_with_check_condition++; #endif @@ -1587,7 +1587,7 @@ static void busfree_run(struct Scsi_Host *shpnt) DPRINTK(debug_eh, ERR_LEAD "CHECK CONDITION found\n", CMDINFO(DONE_SC)); #endif - if(!(DONE_SC->SCp.Status & not_issued)) { + if(!(DONE_SC->SCp.phase & not_issued)) { Scsi_Cmnd *ptr = DONE_SC; DONE_SC=NULL; #if 0 -- cgit v1.2.3 From 66acdb0309507950376393f2fb1c8e7482fb4d52 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 29 Jul 2007 22:24:09 +0300 Subject: [SCSI] aha152x: Clean Reset path What Reset code was doing: Save command's important/dangerous Info on stack. NULL those members from scsi_cmnd. Issue a Reset. wait for it to finish than restore members and return. What I do is save or NULL nothing. But use the "resetting" hint in aha152x_internal_queue() to NULL out working members and leave struct scsi_cmnd alone. The indent here looks funny but it will change/drop in last patch and it is clear this way what changed. Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index dc7d84bae96b..d7ca86f9d1f2 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -1022,6 +1022,14 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, SCp.buffer : next buffer SCp.buffers_residual : left buffers in list SCp.phase : current state of the command */ + + if(phase & resetting) { + SCpnt->SCp.ptr = NULL; + SCpnt->SCp.this_residual = 0; + SCpnt->resid = 0; + SCpnt->SCp.buffer = NULL; + SCpnt->SCp.buffers_residual = 0; + } else { if (SCpnt->use_sg) { SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer; SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer); @@ -1033,6 +1041,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, SCpnt->SCp.buffer = NULL; SCpnt->SCp.buffers_residual = 0; } + } DO_LOCK(flags); @@ -1150,9 +1159,6 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) DECLARE_COMPLETION(done); int ret, issued, disconnected; unsigned char old_cmd_len = SCpnt->cmd_len; - unsigned short old_use_sg = SCpnt->use_sg; - void *old_buffer = SCpnt->request_buffer; - unsigned old_bufflen = SCpnt->request_bufflen; unsigned long flags; unsigned long timeleft; @@ -1174,9 +1180,6 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) DO_UNLOCK(flags); SCpnt->cmd_len = 0; - SCpnt->use_sg = 0; - SCpnt->request_buffer = NULL; - SCpnt->request_bufflen = 0; aha152x_internal_queue(SCpnt, &done, resetting, reset_done); @@ -1189,9 +1192,6 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) } SCpnt->cmd_len = old_cmd_len; - SCpnt->use_sg = old_use_sg; - SCpnt->request_buffer = old_buffer; - SCpnt->request_bufflen = old_bufflen; DO_LOCK(flags); -- cgit v1.2.3 From 45333ffa6ffd2f493fc3853481984b6e60b4fb93 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 29 Jul 2007 22:27:06 +0300 Subject: [SCSI] aha152x: Fix check_condition code-path check_condition code-path was similar but more complicated to Reset. It went like this: 1. extra space was allocated at aha152x_scdata for mirroring scsi_cmnd members. 2. At aha152x_internal_queue() every not check_condition (REQUEST_SENSE) command was copied to above members in case of error. 3. At busfree_run() in the DONE_CS phase if a Status of SAM_STAT_CHECK_CONDITION was detected. The command was re-queued Internally using aha152x_internal_queue(,,check_condition,) The old command members are over written with the REQUEST_SENSE info. 4. At busfree_run() in the DONE_CS phase again. If it is a check_condition command, info was restored from mirror made at first call to aha152x_internal_queue() (see 2) and the command is completed. What I did is: 1. Allocate less space in aha152x_scdata only for the 16-byte original command. (which is actually not needed by scsi-ml anymore at this stage. But this is to much knowledge of scsi-ml) 2. If Status == SAM_STAT_CHECK_CONDITION, then like before re-queue a REQUEST_SENSE command. But only now save original command members. (Less of them) 3. In aha152x_internal_queue(), just like for Reset, use the check_condition hint to set differently the working members. execute the command. 4. At busfree_run() in the DONE_CS phase again. restore needed members. While at it. This patch fixes a BUG. Old code when sending a REQUEST_SENSE for a failed command. Would than return with cmd->resid == 0 which was the status of the REQUEST_SENSE. The failing command resid was lost. And when would resid be interesting if not on a failing command? Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 55 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index d7ca86f9d1f2..cf49ed584762 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -552,14 +552,11 @@ struct aha152x_hostdata { struct aha152x_scdata { Scsi_Cmnd *next; /* next sc in queue */ struct completion *done;/* semaphore to block on */ - unsigned char cmd_len; - unsigned char cmnd[MAX_COMMAND_SIZE]; - unsigned short use_sg; - unsigned request_bufflen; - void *request_buffer; + unsigned char aha_orig_cmd_len; + unsigned char aha_orig_cmnd[MAX_COMMAND_SIZE]; + int aha_orig_resid; }; - /* access macros for hostdata */ #define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata) @@ -997,20 +994,11 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, return FAILED; } } else { - struct aha152x_scdata *sc; - SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC); if(SCpnt->host_scribble==0) { printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt)); return FAILED; } - - sc = SCDATA(SCpnt); - memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd)); - sc->request_buffer = SCpnt->request_buffer; - sc->request_bufflen = SCpnt->request_bufflen; - sc->use_sg = SCpnt->use_sg; - sc->cmd_len = SCpnt->cmd_len; } SCNEXT(SCpnt) = NULL; @@ -1023,10 +1011,16 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, SCp.buffers_residual : left buffers in list SCp.phase : current state of the command */ - if(phase & resetting) { - SCpnt->SCp.ptr = NULL; - SCpnt->SCp.this_residual = 0; - SCpnt->resid = 0; + if (phase & (check_condition|resetting)) { + if (phase & check_condition) { + SCpnt->SCp.ptr = SCpnt->sense_buffer; + SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); + SCpnt->resid = sizeof(SCpnt->sense_buffer); + } else { + SCpnt->SCp.ptr = NULL; + SCpnt->SCp.this_residual = 0; + SCpnt->resid = 0; + } SCpnt->SCp.buffer = NULL; SCpnt->SCp.buffers_residual = 0; } else { @@ -1568,11 +1562,9 @@ static void busfree_run(struct Scsi_Host *shpnt) #endif /* restore old command */ - memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd)); - cmd->request_buffer = sc->request_buffer; - cmd->request_bufflen = sc->request_bufflen; - cmd->use_sg = sc->use_sg; - cmd->cmd_len = sc->cmd_len; + memcpy(cmd->cmnd, sc->aha_orig_cmnd, sizeof(cmd->cmnd)); + cmd->cmd_len = sc->aha_orig_cmd_len; + cmd->resid = sc->aha_orig_resid; cmd->SCp.Status = SAM_STAT_CHECK_CONDITION; @@ -1588,12 +1580,22 @@ static void busfree_run(struct Scsi_Host *shpnt) #endif if(!(DONE_SC->SCp.phase & not_issued)) { + struct aha152x_scdata *sc; Scsi_Cmnd *ptr = DONE_SC; DONE_SC=NULL; #if 0 DPRINTK(debug_eh, ERR_LEAD "requesting sense\n", CMDINFO(ptr)); #endif + /* save old command */ + sc = SCDATA(ptr); + /* It was allocated in aha152x_internal_queue? */ + BUG_ON(!sc); + memcpy(sc->aha_orig_cmnd, ptr->cmnd, + sizeof(ptr->cmnd)); + sc->aha_orig_cmd_len = ptr->cmd_len; + sc->aha_orig_resid = ptr->resid; + ptr->cmnd[0] = REQUEST_SENSE; ptr->cmnd[1] = 0; ptr->cmnd[2] = 0; @@ -1601,10 +1603,7 @@ static void busfree_run(struct Scsi_Host *shpnt) ptr->cmnd[4] = sizeof(ptr->sense_buffer); ptr->cmnd[5] = 0; ptr->cmd_len = 6; - ptr->use_sg = 0; - ptr->request_buffer = ptr->sense_buffer; - ptr->request_bufflen = sizeof(ptr->sense_buffer); - + DO_UNLOCK(flags); aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done); DO_LOCK(flags); -- cgit v1.2.3 From 2338545aafbecce55bbc651fb3f63ebf7468b6fb Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 29 Jul 2007 22:29:02 +0300 Subject: [SCSI] aha152x: use data accessors and !use_sg cleanup And finally this is the regular !use_sg cleanup and use of data accessors. Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 91 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index cf49ed584762..d30a30786dda 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -322,6 +322,12 @@ static LIST_HEAD(aha152x_host_list); (cmd) ? ((cmd)->device->id & 0x0f) : -1, \ (cmd) ? ((cmd)->device->lun & 0x07) : -1 +static inline void +CMD_INC_RESID(struct scsi_cmnd *cmd, int inc) +{ + scsi_set_resid(cmd, scsi_get_resid(cmd) + inc); +} + #define DELAY_DEFAULT 1000 #if defined(PCMCIA) @@ -975,13 +981,13 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, #if defined(AHA152X_DEBUG) if (HOSTDATA(shpnt)->debug & debug_queue) { printk(INFO_LEAD "queue: %p; cmd_len=%d pieces=%d size=%u cmnd=", - CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen); + CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len, + scsi_sg_count(SCpnt), scsi_bufflen(SCpnt)); __scsi_print_command(SCpnt->cmnd); } #endif SCpnt->scsi_done = done; - SCpnt->resid = SCpnt->request_bufflen; SCpnt->SCp.phase = not_issued | phase; SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */ SCpnt->SCp.Message = 0; @@ -1011,30 +1017,24 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete, SCp.buffers_residual : left buffers in list SCp.phase : current state of the command */ - if (phase & (check_condition|resetting)) { + if ((phase & (check_condition|resetting)) || !scsi_sglist(SCpnt)) { if (phase & check_condition) { SCpnt->SCp.ptr = SCpnt->sense_buffer; SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); - SCpnt->resid = sizeof(SCpnt->sense_buffer); + scsi_set_resid(SCpnt, sizeof(SCpnt->sense_buffer)); } else { SCpnt->SCp.ptr = NULL; SCpnt->SCp.this_residual = 0; - SCpnt->resid = 0; + scsi_set_resid(SCpnt, 0); } SCpnt->SCp.buffer = NULL; SCpnt->SCp.buffers_residual = 0; } else { - if (SCpnt->use_sg) { - SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer; + scsi_set_resid(SCpnt, scsi_bufflen(SCpnt)); + SCpnt->SCp.buffer = scsi_sglist(SCpnt); SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer); SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; - SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; - } else { - SCpnt->SCp.ptr = (char *) SCpnt->request_buffer; - SCpnt->SCp.this_residual = SCpnt->request_bufflen; - SCpnt->SCp.buffer = NULL; - SCpnt->SCp.buffers_residual = 0; - } + SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1; } DO_LOCK(flags); @@ -1525,8 +1525,8 @@ static void busfree_run(struct Scsi_Host *shpnt) /* target sent DISCONNECT */ DPRINTK(debug_selection, DEBUG_LEAD "target disconnected at %d/%d\n", CMDINFO(CURRENT_SC), - CURRENT_SC->resid, - CURRENT_SC->request_bufflen); + scsi_get_resid(CURRENT_SC), + scsi_bufflen(CURRENT_SC)); #if defined(AHA152X_STAT) HOSTDATA(shpnt)->disconnections++; #endif @@ -1564,7 +1564,7 @@ static void busfree_run(struct Scsi_Host *shpnt) /* restore old command */ memcpy(cmd->cmnd, sc->aha_orig_cmnd, sizeof(cmd->cmnd)); cmd->cmd_len = sc->aha_orig_cmd_len; - cmd->resid = sc->aha_orig_resid; + scsi_set_resid(cmd, sc->aha_orig_resid); cmd->SCp.Status = SAM_STAT_CHECK_CONDITION; @@ -1594,7 +1594,7 @@ static void busfree_run(struct Scsi_Host *shpnt) memcpy(sc->aha_orig_cmnd, ptr->cmnd, sizeof(ptr->cmnd)); sc->aha_orig_cmd_len = ptr->cmd_len; - sc->aha_orig_resid = ptr->resid; + sc->aha_orig_resid = scsi_get_resid(ptr); ptr->cmnd[0] = REQUEST_SENSE; ptr->cmnd[1] = 0; @@ -2179,7 +2179,8 @@ static void datai_init(struct Scsi_Host *shpnt) DATA_LEN=0; DPRINTK(debug_datai, DEBUG_LEAD "datai_init: request_bufflen=%d resid=%d\n", - CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid); + CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC), + scsi_get_resid(CURRENT_SC)); } static void datai_run(struct Scsi_Host *shpnt) @@ -2292,11 +2293,12 @@ static void datai_run(struct Scsi_Host *shpnt) static void datai_end(struct Scsi_Host *shpnt) { - CURRENT_SC->resid -= GETSTCNT(); + CMD_INC_RESID(CURRENT_SC, -GETSTCNT()); DPRINTK(debug_datai, DEBUG_LEAD "datai_end: request_bufflen=%d resid=%d stcnt=%d\n", - CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid, GETSTCNT()); + CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC), + scsi_get_resid(CURRENT_SC), GETSTCNT()); SETPORT(SXFRCTL0, CH1|CLRSTCNT); SETPORT(DMACNTRL0, 0); @@ -2317,11 +2319,12 @@ static void datao_init(struct Scsi_Host *shpnt) SETPORT(SIMODE0, 0); SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE ); - DATA_LEN = CURRENT_SC->resid; + DATA_LEN = scsi_get_resid(CURRENT_SC); DPRINTK(debug_datao, DEBUG_LEAD "datao_init: request_bufflen=%d; resid=%d\n", - CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid); + CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC), + scsi_get_resid(CURRENT_SC)); } static void datao_run(struct Scsi_Host *shpnt) @@ -2345,7 +2348,7 @@ static void datao_run(struct Scsi_Host *shpnt) SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT); SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++); CURRENT_SC->SCp.this_residual--; - CURRENT_SC->resid--; + CMD_INC_RESID(CURRENT_SC, -1); SETPORT(DMACNTRL0,WRITE_READ|ENDMA); } @@ -2354,7 +2357,7 @@ static void datao_run(struct Scsi_Host *shpnt) outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); CURRENT_SC->SCp.ptr += 2 * data_count; CURRENT_SC->SCp.this_residual -= 2 * data_count; - CURRENT_SC->resid -= 2 * data_count; + CMD_INC_RESID(CURRENT_SC, -2 * data_count); } if(CURRENT_SC->SCp.this_residual==0 && CURRENT_SC->SCp.buffers_residual>0) { @@ -2380,35 +2383,34 @@ static void datao_run(struct Scsi_Host *shpnt) static void datao_end(struct Scsi_Host *shpnt) { if(TESTLO(DMASTAT, DFIFOEMP)) { - int data_count = (DATA_LEN - CURRENT_SC->resid) - GETSTCNT(); + int data_count = (DATA_LEN - scsi_get_resid(CURRENT_SC)) - + GETSTCNT(); DPRINTK(debug_datao, DEBUG_LEAD "datao: %d bytes to resend (%d written, %d transferred)\n", CMDINFO(CURRENT_SC), data_count, - DATA_LEN-CURRENT_SC->resid, + DATA_LEN - scsi_get_resid(CURRENT_SC), GETSTCNT()); - CURRENT_SC->resid += data_count; + CMD_INC_RESID(CURRENT_SC, data_count); - if(CURRENT_SC->use_sg) { - data_count -= CURRENT_SC->SCp.ptr - SG_ADDRESS(CURRENT_SC->SCp.buffer); - while(data_count>0) { - CURRENT_SC->SCp.buffer--; - CURRENT_SC->SCp.buffers_residual++; - data_count -= CURRENT_SC->SCp.buffer->length; - } - CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) - data_count; - CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + data_count; - } else { - CURRENT_SC->SCp.ptr -= data_count; - CURRENT_SC->SCp.this_residual += data_count; + data_count -= CURRENT_SC->SCp.ptr - + SG_ADDRESS(CURRENT_SC->SCp.buffer); + while(data_count>0) { + CURRENT_SC->SCp.buffer--; + CURRENT_SC->SCp.buffers_residual++; + data_count -= CURRENT_SC->SCp.buffer->length; } + CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) - + data_count; + CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + + data_count; } DPRINTK(debug_datao, DEBUG_LEAD "datao_end: request_bufflen=%d; resid=%d; stcnt=%d\n", CMDINFO(CURRENT_SC), - CURRENT_SC->request_bufflen, - CURRENT_SC->resid, + scsi_bufflen(CURRENT_SC), + scsi_get_resid(CURRENT_SC), GETSTCNT()); SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT); @@ -2935,7 +2937,7 @@ static void show_command(Scsi_Cmnd *ptr) __scsi_print_command(ptr->cmnd); printk(KERN_DEBUG "); request_bufflen=%d; resid=%d; phase |", - ptr->request_bufflen, ptr->resid); + scsi_bufflen(ptr), scsi_get_resid(ptr)); if (ptr->SCp.phase & not_issued) printk("not issued|"); @@ -3005,7 +3007,8 @@ static int get_command(char *pos, Scsi_Cmnd * ptr) SPRINTF("0x%02x ", ptr->cmnd[i]); SPRINTF("); resid=%d; residual=%d; buffers=%d; phase |", - ptr->resid, ptr->SCp.this_residual, ptr->SCp.buffers_residual); + scsi_get_resid(ptr), ptr->SCp.this_residual, + ptr->SCp.buffers_residual); if (ptr->SCp.phase & not_issued) SPRINTF("not issued|"); -- cgit v1.2.3 From 2b053729a84b6aac197df51b8729bc9fec743bff Mon Sep 17 00:00:00 2001 From: "Salyzyn, Mark" Date: Thu, 2 Aug 2007 15:38:59 -0400 Subject: [SCSI] aacraid: prevent panic on adapter resource failure If the driver fails to allocate the contiguous (DMAable) memory for system reasons, we fail to load the instance, but then we try to free the allocation in the cleanup code and we get a panic in pci_free_consistent(). This is reported against an older kernel, hope this is relevant for latest/greatest. Signed-off-by: Mark Salyzyn Signed-off-by: James Bottomley --- drivers/scsi/aacraid/linit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 813556c60007..a7f42a17b5c7 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1110,7 +1110,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, __aac_shutdown(aac); out_unmap: aac_fib_map_free(aac); - pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); + if (aac->comm_addr) + pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, + aac->comm_phys); kfree(aac->queues); aac_adapter_ioremap(aac, 0); kfree(aac->fibs); -- cgit v1.2.3 From eba84481c7424f03c792d753fe02d9d6d3609fe0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 6 Aug 2007 16:10:54 +0100 Subject: [ARM] pata_icside: fix the FIXMEs Alan Cox suggested that the solution to the FIXMEs in pata_icside is to use a private postreset method to detect the lack of devices on a port, and in such a case, disable the interrupt for the port. This patch implements such a method, and removes the hard coded disable of port 0. Tested as working. Acked-by: Jeff Garzik Signed-off-by: Russell King --- drivers/ata/pata_icside.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 321d98b0bed2..64a711776c45 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -330,17 +330,12 @@ static void ata_dummy_noret(struct ata_port *port) { } -/* - * We need to shut down unused ports to prevent spurious interrupts. - * FIXME: the libata core doesn't call this function for PATA interfaces. - */ -static void pata_icside_port_disable(struct ata_port *ap) +static void pata_icside_postreset(struct ata_port *ap, unsigned int *classes) { struct pata_icside_state *state = ap->host->private_data; - ata_port_printk(ap, KERN_ERR, "disabling icside port\n"); - - ata_port_disable(ap); + if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE) + return ata_std_postreset(ap, classes); state->port[ap->port_no].disabled = 1; @@ -356,6 +351,12 @@ static void pata_icside_port_disable(struct ata_port *ap) } } +static void pata_icside_error_handler(struct ata_port *ap) +{ + ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL, + pata_icside_postreset); +} + static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) { unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; @@ -374,7 +375,7 @@ static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) } static struct ata_port_operations pata_icside_port_ops = { - .port_disable = pata_icside_port_disable, + .port_disable = ata_port_disable, .set_dmamode = pata_icside_set_dmamode, @@ -397,7 +398,7 @@ static struct ata_port_operations pata_icside_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, + .error_handler = pata_icside_error_handler, .post_internal_cmd = pata_icside_bmdma_stop, .irq_clear = ata_dummy_noret, @@ -484,13 +485,6 @@ static int __devinit pata_icside_register_v6(struct pata_icside_info *info) state->port[0].port_sel = sel; state->port[1].port_sel = sel | 1; - /* - * FIXME: work around libata's aversion to calling port_disable. - * This permanently disables interrupts on port 0 - bad luck if - * you have a drive on that port. - */ - state->port[0].disabled = 1; - info->base = easi_base; info->irqops = &pata_icside_ops_arcin_v6; info->nr_ports = 2; -- cgit v1.2.3 From 829ef1f574a979f681959fd17f9bd698e878cda4 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 6 Aug 2007 14:41:59 -0400 Subject: Revert "[PATCH] bcm43xx: Fix deviation from specifications in set_baseband_attenuation" This reverts commit 77548f58070894cf5970a110981e511ffe793369. David Woodhouse wrote: >This broke my shinybook. I seem to get absolutely _no_ outgoing packets, >although I can receive OK. Larry Finger wrote: >Please revert this patch. Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index d779199c30d0..b37f1e348700 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c @@ -1638,7 +1638,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, return; } - if (phy->analog == 1) { + if (phy->analog > 1) { value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C; value |= (baseband_attenuation << 2) & 0x003C; } else { -- cgit v1.2.3 From c43bff43e0617dd56515b4ea42a8037c699c86f1 Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Sun, 15 Jul 2007 17:09:55 -0700 Subject: [PATCH] rtl8187: ensure priv->hwaddr is always valid conf->mac_addr is not guaranteed to be set. This ensures priv->hwaddr is always set to a valid mac address. Thanks to Johannes Berg for finding this problem. Signed-off-by: Michael Wu Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8187_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index cea85894b7f2..e61c6d5ba1a9 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -466,7 +466,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, return -EOPNOTSUPP; } - priv->hwaddr = conf->mac_addr; + priv->hwaddr = conf->mac_addr ? conf->mac_addr : dev->wiphy->perm_addr; return 0; } -- cgit v1.2.3 From 69dad6e563140ce8578749a8c8651b7f1db8cdbc Mon Sep 17 00:00:00 2001 From: Ulrich Kunitz Date: Sat, 21 Jul 2007 22:42:02 +0100 Subject: [PATCH] zd1211rw: fix filter for PSPOLL frames While filling the control set the driver tests for a PSPOLL frame. But it tested only the subtype of the packet. The full type needs to be tested to identify those packets reliably. [dsd@gentoo.org: backport to mainline] Signed-off-by: Ulrich Kunitz Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index f6c487aa8246..26869d107e52 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -822,7 +822,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, cs->control |= ZD_CS_MULTICAST; /* PS-POLL */ - if (stype == IEEE80211_STYPE_PSPOLL) + if (ftype == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL) cs->control |= ZD_CS_PS_POLL_FRAME; /* Unicast data frames over the threshold should have RTS */ -- cgit v1.2.3 From 2584fbc3a61897de5eddd56b39a4fa9cd074eca2 Mon Sep 17 00:00:00 2001 From: Roger So Date: Tue, 31 Jul 2007 23:52:42 +0200 Subject: r8169: PHY power-on fix Fix extracted from Realtek's driver (8.002.00/20070713) for the PHY attached to 8111/8168b chipsets. The check against mac_version is just usual paranoia during the bugfix period of the kernel cycle. -- FR Tested on Asus M2A-VM motherboard by Roger So. No regression on my Asrock 945G DVI either (built-in 8168 + 2x8169). Signed-off-by: Roger So Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bb6896ae3151..ec4f545c491f 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -725,6 +725,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + if (tp->mac_version == RTL_GIGA_MAC_VER_12) { + /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */ + mdio_write(ioaddr, 0x1f, 0x0000); + mdio_write(ioaddr, 0x0e, 0x0000); + } + tp->phy_auto_nego_reg = auto_nego; tp->phy_1000_ctrl_reg = giga_ctrl; -- cgit v1.2.3 From 313b0305b5a1e7e0fb39383befbf79558ce68a9c Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 2 Aug 2007 00:00:48 +0200 Subject: r8169: avoid needless NAPI poll scheduling Theory : though needless, it should not have hurt. Practice: it does not play nice with DEBUG_SHIRQ + LOCKDEP + UP (see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=242572). The patch makes sense in itself but I should dig why it has an effect on #242572 (assuming that NAPI do not change in a near future). Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ec4f545c491f..631e55dbbdd0 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2767,14 +2767,16 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) rtl8169_check_link_status(dev, tp, ioaddr); #ifdef CONFIG_R8169_NAPI - RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); - tp->intr_mask = ~tp->napi_event; - - if (likely(netif_rx_schedule_prep(dev))) - __netif_rx_schedule(dev); - else if (netif_msg_intr(tp)) { - printk(KERN_INFO "%s: interrupt %04x taken in poll\n", - dev->name, status); + if (status & tp->napi_event) { + RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); + tp->intr_mask = ~tp->napi_event; + + if (likely(netif_rx_schedule_prep(dev))) + __netif_rx_schedule(dev); + else if (netif_msg_intr(tp)) { + printk(KERN_INFO "%s: interrupt %04x in poll\n", + dev->name, status); + } } break; #else -- cgit v1.2.3 From 21f16289270447673a7263ccc0b22d562fb01ecb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 7 Aug 2007 09:09:51 +1000 Subject: drm/i915: Fix i965 secured batchbuffer usage This 965G and above chipsets moved the batch buffer non-secure bits to another place. This means that previous drm's allowed in-secure batchbuffers to be submitted to the hardware from non-privileged users who are logged into X and and have access to direct rendering. Signed-off-by: Dave Airlie Signed-off-by: Linus Torvalds --- drivers/char/drm/i915_dma.c | 14 +++++++++++--- drivers/char/drm/i915_drv.h | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 3359cc2b9736..8e7d713a5a15 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c @@ -184,6 +184,8 @@ static int i915_initialize(struct drm_device * dev, * private backbuffer/depthbuffer usage. */ dev_priv->use_mi_batchbuffer_start = 0; + if (IS_I965G(dev)) /* 965 doesn't support older method */ + dev_priv->use_mi_batchbuffer_start = 1; /* Allow hardware batchbuffers unless told otherwise. */ @@ -517,8 +519,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, if (dev_priv->use_mi_batchbuffer_start) { BEGIN_LP_RING(2); - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); + if (IS_I965G(dev)) { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); + OUT_RING(batch->start); + } else { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); + OUT_RING(batch->start | MI_BATCH_NON_SECURE); + } ADVANCE_LP_RING(); } else { BEGIN_LP_RING(4); @@ -735,7 +742,8 @@ static int i915_setparam(DRM_IOCTL_ARGS) switch (param.param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - dev_priv->use_mi_batchbuffer_start = param.value; + if (!IS_I965G(dev)) + dev_priv->use_mi_batchbuffer_start = param.value; break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: dev_priv->tex_lru_log_granularity = param.value; diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index fd918565f4e5..737088bd0780 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -282,6 +282,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define MI_BATCH_BUFFER_START (0x31<<23) #define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_BATCH_NON_SECURE_I965 (1<<8) #define MI_WAIT_FOR_EVENT ((0x3<<23)) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -- cgit v1.2.3 From bac27d35cbbf7c641efcc75b5330df8717d6db65 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 5 Aug 2007 10:16:11 +0300 Subject: KVM: x86 emulator: fix debug reg mov instructions More fallout from the writeback fixes: debug register transfer instructions do their own writeback and thus need to disable the general writeback mechanism. This fixes oopses and some guest failures on AMD machines (the Intel variant decodes the instruction in hardware and thus does not need emulation). Cc: Alistair John Strachan Signed-off-by: Avi Kivity Signed-off-by: Linus Torvalds --- drivers/kvm/x86_emulate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index 1f979cb0df31..4b8a0cc9665e 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c @@ -1217,11 +1217,13 @@ twobyte_insn: } break; case 0x21: /* mov from dr to reg */ + no_wb = 1; if (modrm_mod != 3) goto cannot_emulate; rc = emulator_get_dr(ctxt, modrm_reg, &_regs[modrm_rm]); break; case 0x23: /* mov from reg to dr */ + no_wb = 1; if (modrm_mod != 3) goto cannot_emulate; rc = emulator_set_dr(ctxt, modrm_reg, _regs[modrm_rm]); -- cgit v1.2.3 From cc1ff43b7002b40686f03269b5011d59965737a4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 6 Aug 2007 10:48:18 +1000 Subject: Enable lguest drivers in Kconfig Lguest drivers need to default to "Y" otherwise they're never selected for new builds. (We don't bother prompting, because they're less than 4k combined, and implied by selecting lguest support). Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/lguest/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 888205c3f76b..fd6925f41647 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -21,8 +21,10 @@ config LGUEST_GUEST config LGUEST_NET tristate + default y depends on LGUEST_GUEST && NET config LGUEST_BLOCK tristate + default y depends on LGUEST_GUEST && BLOCK -- cgit v1.2.3 From 5f70bf7510e5e51b0bac32b1470c92e9332452a4 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 5 Aug 2007 15:20:45 -0300 Subject: ACPI: thinkpad-acpi: change thinkpad-acpi input default and kconfig help The current kconfig help text was misleading users. Also, the default for an input-layer-optimized support caused way too many problems without up-to-date userspace in place. So, rework the help text, and change the default to N. Note that distributions are supposed to enable this option as soon as they update HAL to a version that handles the thinkpad-acpi new input layer interface. Signed-off-by: Henrique de Moraes Holschuh Cc: Michael S. Tsirkin Cc: Hugh Dickins Signed-off-by: Len Brown --- drivers/misc/Kconfig | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index aaaa61ea4217..518d5d335464 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -200,14 +200,22 @@ config THINKPAD_ACPI_BAY config THINKPAD_ACPI_INPUT_ENABLED bool "Enable input layer support by default" depends on THINKPAD_ACPI - default y + default n ---help--- - Enables hot key handling over the input layer by default. If unset, - the driver does not enable any hot key handling by default, and also - starts up with a mostly empty keymap. - - If you are not sure, say Y here. Say N to retain the deprecated - behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21. + This option enables thinkpad-acpi hot key handling over the input + layer at driver load time. When it is unset, the driver does not + enable hot key handling by default, and also starts up with a mostly + empty keymap. + + This option should be enabled if you have a new enough HAL or other + userspace support that properly handles the thinkpad-acpi event + device. It auto-tunes the hot key support to those reported by the + firmware and enables it automatically. + + If unsure, say N here to retain the old behaviour of ibm-acpi, and + thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and + set up the thinkpad-acpi hot key handling using the sysfs interace + after loading the driver. endif # MISC_DEVICES -- cgit v1.2.3 From ed3110efb538d7acbf635095c1382118f7414f75 Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Tue, 31 Jul 2007 12:04:31 -0700 Subject: ACPI: fix "Time Problems with 2.6.23-rc1-gf695baf2" Enable C3 without bm control only for CST based C3. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index a898991f77cb..a8634a0655fc 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -969,11 +969,17 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, } if (pr->flags.bm_check) { - /* bus mastering control is necessary */ if (!pr->flags.bm_control) { - /* In this case we enter C3 without bus mastering */ - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C3 support without bus mastering control\n")); + if (pr->flags.has_cst != 1) { + /* bus mastering control is necessary */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C3 support requires BM control\n")); + return; + } else { + /* Here we enter C3 without bus mastering */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C3 support without BM control\n")); + } } } else { /* -- cgit v1.2.3 From 6958e827f187c9c5cd39af075567f74f02bf3dd1 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 6 Aug 2007 17:09:09 +0300 Subject: IPoIB: Fix leak in ipoib_transport_dev_init() error path ipoib_transport_dev_init() calls ipoib_cm_dev_init(), so it needs to call ipoib_cm_dev_cleanup() to unwind that on the error path. Found by Dotan Barak of Mellanox. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 982eb88e27ec..563aeacf9e14 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -211,6 +211,7 @@ out_free_cq: out_free_mr: ib_dereg_mr(priv->mr); + ipoib_cm_dev_cleanup(dev); out_free_pd: ib_dealloc_pd(priv->pd); -- cgit v1.2.3 From 092ed997c0c324a2e5e839da9f49453bb5227703 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 1 Aug 2007 15:48:55 +0900 Subject: net: smc91x: Build fixes for general sh boards. SH boards in general only wire this up in 8 or 16-bit mode, and as we never had the wrappers for 32-bit mode defined, SMC_CAN_USE_32BIT caused build failure for the non-Solution Engine boards. This gets it building again. Also kill off the straggling set_irq_type() definition, this is left over cruft that was missed when the rest of it switched to IRQ flags. Signed-off-by: Paul Mundt -- drivers/net/smc91x.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/smc91x.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index f8429449dc1e..6ff3a1627af8 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -299,7 +299,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_CAN_USE_8BIT 1 #define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 +#define SMC_CAN_USE_32BIT 0 #define SMC_inb(a, r) inb((a) + (r)) #define SMC_inw(a, r) inw((a) + (r)) @@ -310,8 +310,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #endif /* BOARDS */ -#define set_irq_type(irq, type) do {} while (0) - #elif defined(CONFIG_M32R) #define SMC_CAN_USE_8BIT 0 -- cgit v1.2.3 From 5845b677cf7f64a0f104609e1dfe02a439f69f71 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 31 Jul 2007 19:07:02 -0500 Subject: atl1: use spin_trylock_irqsave() use the simpler spin_trylock_irqsave() API to get the adapter lock. [ this is also a fix for -rt where adapter->lock is a sleeping lock. ] Signed-off-by: Ingo Molnar Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik --- drivers/net/atl1/atl1_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 56f6389a300e..3c1984ecf36c 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -1704,10 +1704,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } } - local_irq_save(flags); - if (!spin_trylock(&adapter->lock)) { + if (!spin_trylock_irqsave(&adapter->lock, flags)) { /* Can't get lock - tell upper layer to requeue */ - local_irq_restore(flags); dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx locked\n"); return NETDEV_TX_LOCKED; } -- cgit v1.2.3 From 8eb7ad68bd10d858066ca51713ca5645996e77a5 Mon Sep 17 00:00:00 2001 From: Neil Muller Date: Wed, 1 Aug 2007 17:52:04 +0200 Subject: sis190 check for ISA bridge on SiS966 sis190 driver assumes to find ISA only on SiS965. similar fix is in sis900 driver, see bug report http://bugs.debian.org/435547 Signed-off-by: maximilian attems Signed-off-by: Jeff Garzik --- drivers/net/sis190.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index ec2ad9f0efa2..d470b19c0810 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1593,6 +1593,9 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, pci_name(pdev)); isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL); + if (!isa_bridge) + isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0966, NULL); + if (!isa_bridge) { net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n", pci_name(pdev)); -- cgit v1.2.3 From 76b9cfccb39f542ce48a79b9ad50af25e422506c Mon Sep 17 00:00:00 2001 From: Brian King Date: Fri, 3 Aug 2007 13:55:19 +1000 Subject: ibmveth: Fix rx pool deactivate oops This fixes the following oops which can occur when trying to deallocate receive buffer pools using sysfs with the ibmveth driver. NIP: d00000000024f954 LR: d00000000024fa58 CTR: c0000000000d7478 REGS: c00000000ffef9f0 TRAP: 0300 Not tainted (2.6.22-ppc64) MSR: 8000000000009032 CR: 24242442 XER: 00000010 DAR: 00000000000007f0, DSISR: 0000000042000000 TASK = c000000002f91360[2967] 'bash' THREAD: c00000001398c000 CPU: 2 GPR00: 0000000000000000 c00000000ffefc70 d000000000262d30 c00000001c4087a0 GPR04: 00000003000000fe 0000000000000000 000000000000000f c000000000579d80 GPR08: 0000000000365688 c00000001c408998 00000000000007f0 0000000000000000 GPR12: d000000000251e88 c000000000579d80 00000000200957ec 0000000000000000 GPR16: 00000000100b8808 00000000100feb30 0000000000000000 0000000010084828 GPR20: 0000000000000000 000000001014d4d0 0000000000000010 c00000000ffefeb0 GPR24: c00000001c408000 0000000000000000 c00000001c408000 00000000ffffb054 GPR28: 00000000000000fe 0000000000000003 d000000000262700 c00000001c4087a0 NIP [d00000000024f954] .ibmveth_remove_buffer_from_pool+0x38/0x108 [ibmveth] LR [d00000000024fa58] .ibmveth_rxq_harvest_buffer+0x34/0x78 [ibmveth] Call Trace: [c00000000ffefc70] [c0000000000280a8] .dma_iommu_unmap_single+0x14/0x28 (unreliable) [c00000000ffefd00] [d00000000024fa58] .ibmveth_rxq_harvest_buffer+0x34/0x78 [ibmveth] [c00000000ffefd80] [d000000000250e40] .ibmveth_poll+0xd8/0x434 [ibmveth] [c00000000ffefe40] [c00000000032da8c] .net_rx_action+0xdc/0x248 [c00000000ffefef0] [c000000000068b4c] .__do_softirq+0xa8/0x164 [c00000000ffeff90] [c00000000002789c] .call_do_softirq+0x14/0x24 [c00000001398f6f0] [c00000000000c04c] .do_softirq+0x68/0xac [c00000001398f780] [c000000000068ca0] .irq_exit+0x54/0x6c [c00000001398f800] [c00000000000c8e4] .do_IRQ+0x170/0x1ac [c00000001398f890] [c000000000004790] hardware_interrupt_entry+0x18/0x1c Exception: 501 at .plpar_hcall_norets+0x24/0x94 LR = .veth_pool_store+0x15c/0x298 [ibmveth] [c00000001398fb80] [d000000000250b2c] .veth_pool_store+0x5c/0x298 [ibmveth] (unreliable) [c00000001398fc30] [c000000000145530] .sysfs_write_file+0x140/0x1d8 [c00000001398fcf0] [c0000000000de89c] .vfs_write+0x120/0x208 [c00000001398fd90] [c0000000000df2c8] .sys_write+0x4c/0x8c [c00000001398fe30] [c0000000000086ac] syscall_exit+0x0/0x40 Instruction dump: fba1ffe8 fbe1fff8 789d0022 f8010010 f821ff71 789c0020 1d3d00a8 7b8a1f24 38000000 7c7f1b78 7d291a14 e9690128 <7c0a592a> e8030000 e9690120 80a90100 Signed-off-by: Brian King Signed-off-by: Paul Mackerras Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 24 ++++++++++++++---------- drivers/net/ibmveth.h | 3 --- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index d96eb7229548..cf4a92436aa8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1280,24 +1280,28 @@ const char * buf, size_t count) int i; /* Make sure there is a buffer pool with buffers that can hold a packet of the size of the MTU */ - for(i = 0; irx_buff_pool[i]) continue; if (!adapter->rx_buff_pool[i].active) continue; - if (mtu < adapter->rx_buff_pool[i].buff_size) { - pool->active = 0; - h_free_logical_lan_buffer(adapter-> - vdev-> - unit_address, - pool-> - buff_size); - } + if (mtu <= adapter->rx_buff_pool[i].buff_size) + break; } - if (pool->active) { + + if (i == IbmVethNumBufferPools) { ibmveth_error_printk("no active pool >= MTU\n"); return -EPERM; } + + pool->active = 0; + if (netif_running(netdev)) { + adapter->pool_config = 1; + ibmveth_close(netdev); + adapter->pool_config = 0; + if ((rc = ibmveth_open(netdev))) + return rc; + } } } else if (attr == &veth_num_attr) { if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index bb69ccae8ace..72cc15a6cab7 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -73,9 +73,6 @@ static inline long h_send_logical_lan(unsigned long unit_address, #define h_change_logical_lan_mac(ua, mac) \ plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) -#define h_free_logical_lan_buffer(ua, bufsize) \ - plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize) - #define IbmVethNumBufferPools 5 #define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */ #define IBMVETH_MAX_MTU 68 -- cgit v1.2.3 From f46f6ba99bad942963cc4b4cc4aabcc55a567b4a Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 6 Aug 2007 13:54:29 +0200 Subject: ehea: Fix workqueue handling Fix: Workqueue ehea_driver_wq was not destroyed Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 2 +- drivers/net/ehea/ehea_main.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 8ee2c2c86b42..d67f97bfa3a4 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0072" +#define DRV_VERSION "EHEA_0073" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 58702f54c3fb..d43ab0f4192a 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3099,6 +3099,7 @@ out: static void __exit ehea_module_exit(void) { + destroy_workqueue(ehea_driver_wq); driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); ehea_destroy_busmap(); -- cgit v1.2.3 From 35cf2e2e3b96c070a615d699bf514ffec6afd19e Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 6 Aug 2007 13:55:14 +0200 Subject: ehea: Simplify resource usage check Use shorter method to determine whether adapter has configured ports Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index d43ab0f4192a..36ca32275b45 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2165,24 +2165,18 @@ static int ehea_clean_all_portres(struct ehea_port *port) return ret; } -static void ehea_remove_adapter_mr (struct ehea_adapter *adapter) +static void ehea_remove_adapter_mr(struct ehea_adapter *adapter) { - int i; - - for (i=0; i < EHEA_MAX_PORTS; i++) - if (adapter->port[i]) - return; + if (adapter->active_ports) + return; ehea_rem_mr(&adapter->mr); } -static int ehea_add_adapter_mr (struct ehea_adapter *adapter) +static int ehea_add_adapter_mr(struct ehea_adapter *adapter) { - int i; - - for (i=0; i < EHEA_MAX_PORTS; i++) - if (adapter->port[i]) - return 0; + if (adapter->active_ports) + return 0; return ehea_reg_kernel_mr(adapter, &adapter->mr); } -- cgit v1.2.3 From 44a5b3d539893988dc6b63054c59d031df1fd7bc Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 6 Aug 2007 13:55:44 +0200 Subject: ehea: Eliminated some compiler warnings Fixed wrongly casted pointers Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 36ca32275b45..9756211e83ce 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1326,7 +1326,6 @@ static void write_swqe2_TSO(struct sk_buff *skb, u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0]; int skb_data_size = skb->len - skb->data_len; int headersize; - u64 tmp_addr; /* Packet is TCP with TSO enabled */ swqe->tx_control |= EHEA_SWQE_TSO; @@ -1347,9 +1346,8 @@ static void write_swqe2_TSO(struct sk_buff *skb, /* set sg1entry data */ sg1entry->l_key = lkey; sg1entry->len = skb_data_size - headersize; - - tmp_addr = (u64)(skb->data + headersize); - sg1entry->vaddr = ehea_map_vaddr(tmp_addr); + sg1entry->vaddr = + ehea_map_vaddr(skb->data + headersize); swqe->descriptors++; } } else @@ -1362,7 +1360,6 @@ static void write_swqe2_nonTSO(struct sk_buff *skb, int skb_data_size = skb->len - skb->data_len; u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0]; struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry; - u64 tmp_addr; /* Packet is any nonTSO type * @@ -1379,8 +1376,8 @@ static void write_swqe2_nonTSO(struct sk_buff *skb, /* copy sg1entry data */ sg1entry->l_key = lkey; sg1entry->len = skb_data_size - SWQE2_MAX_IMM; - tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM); - sg1entry->vaddr = ehea_map_vaddr(tmp_addr); + sg1entry->vaddr = + ehea_map_vaddr(skb->data + SWQE2_MAX_IMM); swqe->descriptors++; } } else { @@ -1395,7 +1392,6 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, struct ehea_vsgentry *sg_list, *sg1entry, *sgentry; skb_frag_t *frag; int nfrags, sg1entry_contains_frag_data, i; - u64 tmp_addr; nfrags = skb_shinfo(skb)->nr_frags; sg1entry = &swqe->u.immdata_desc.sg_entry; @@ -1417,9 +1413,9 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, /* copy sg1entry data */ sg1entry->l_key = lkey; sg1entry->len = frag->size; - tmp_addr = (u64)(page_address(frag->page) - + frag->page_offset); - sg1entry->vaddr = ehea_map_vaddr(tmp_addr); + sg1entry->vaddr = + ehea_map_vaddr(page_address(frag->page) + + frag->page_offset); swqe->descriptors++; sg1entry_contains_frag_data = 1; } @@ -1431,10 +1427,9 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, sgentry->l_key = lkey; sgentry->len = frag->size; - - tmp_addr = (u64)(page_address(frag->page) - + frag->page_offset); - sgentry->vaddr = ehea_map_vaddr(tmp_addr); + sgentry->vaddr = + ehea_map_vaddr(page_address(frag->page) + + frag->page_offset); swqe->descriptors++; } } -- cgit v1.2.3 From 163642a24a44d7b1d1e1b3cb8da25a142a919e24 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Tue, 7 Aug 2007 12:12:41 +0200 Subject: phy layer: fix phy_mii_ioctl for autonegotiation Fix a thinko (?) in setting phydev->autoneg. Signed-off-by: Domen Puncer Signed-off-by: Jeff Garzik --- drivers/net/phy/phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index f71dab347667..e323efd4ed18 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -261,7 +261,7 @@ void phy_sanitize_settings(struct phy_device *phydev) /* Sanitize settings based on PHY capabilities */ if ((features & SUPPORTED_Autoneg) == 0) - phydev->autoneg = 0; + phydev->autoneg = AUTONEG_DISABLE; idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex), features); @@ -374,7 +374,7 @@ int phy_mii_ioctl(struct phy_device *phydev, if (mii_data->phy_id == phydev->addr) { switch(mii_data->reg_num) { case MII_BMCR: - if (val & (BMCR_RESET|BMCR_ANENABLE)) + if ((val & (BMCR_RESET|BMCR_ANENABLE)) == 0) phydev->autoneg = AUTONEG_DISABLE; else phydev->autoneg = AUTONEG_ENABLE; -- cgit v1.2.3 From 9dc83afdbefd184bf29f347e8fcbb6d8a2b5e6fe Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Mon, 6 Aug 2007 23:44:03 +0200 Subject: drivers/net/ibmveth.c: memset fix > >> Looks like memset() is zeroing wrong nr of bytes. > > > > Good catch, however, I think we can just remove this memset altogether > > since the memory gets allocated via kzalloc. > > Correct, that memset() is superfluous. Ok. Then this should do it. Signed-off-by: Mariusz Kozlowski drivers/net/ibmveth.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index cf4a92436aa8..acba90f1638e 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -963,7 +963,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ { int rc, i; struct net_device *netdev; - struct ibmveth_adapter *adapter = NULL; + struct ibmveth_adapter *adapter; unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; @@ -997,7 +997,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ SET_MODULE_OWNER(netdev); adapter = netdev->priv; - memset(adapter, 0, sizeof(adapter)); dev->dev.driver_data = netdev; adapter->vdev = dev; -- cgit v1.2.3 From 501092929ccb8a1d2eb0ed700e38df4ae0de7108 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 7 Aug 2007 18:40:30 -0400 Subject: acpi-cpufreq: Fix some x86/x86-64 acpi-cpufreq driver issues This patch addresses some issues in x86/x86-64 acpi-cpufreq driver: 1. Current memory allocation for acpi_perf_data is actually open-coded alloc_percpu(). The patch defines and handles acpi_perf_data as percpu data. The code will be cleaner and easier to be maintained with this change. 2. Won't load driver in acpi_cpufreq_early_init() failure case. 3. Add __init for acpi_cpufreq_early_init(). Signed-off-by: Fenghua Yu Acked-by: Venkatesh Pallipadi Cc: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 41 +++++++++++------------------ drivers/acpi/processor_perflib.c | 6 ++--- include/acpi/processor.h | 2 +- 3 files changed, 19 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 32d04b083e38..705e13a30781 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -68,7 +68,8 @@ struct acpi_cpufreq_data { }; static struct acpi_cpufreq_data *drv_data[NR_CPUS]; -static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; +/* acpi_perf_data is a pointer to percpu data. */ +static struct acpi_processor_performance *acpi_perf_data; static struct cpufreq_driver acpi_cpufreq_driver; @@ -508,24 +509,14 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) * do _PDC and _PSD and find out the processor dependency for the * actual init that will happen later... */ -static int acpi_cpufreq_early_init(void) +static int __init acpi_cpufreq_early_init(void) { - struct acpi_processor_performance *data; - unsigned int i, j; - dprintk("acpi_cpufreq_early_init\n"); - for_each_possible_cpu(i) { - data = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!data) { - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } - return -ENOMEM; - } - acpi_perf_data[i] = data; + acpi_perf_data = alloc_percpu(struct acpi_processor_performance); + if (!acpi_perf_data) { + dprintk("Memory allocation error for acpi_perf_data.\n"); + return -ENOMEM; } /* Do initialization in ACPI core */ @@ -574,14 +565,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) dprintk("acpi_cpufreq_cpu_init\n"); - if (!acpi_perf_data[cpu]) - return -ENODEV; - data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); if (!data) return -ENOMEM; - data->acpi_data = acpi_perf_data[cpu]; + data->acpi_data = percpu_ptr(acpi_perf_data, cpu); drv_data[cpu] = data; if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) @@ -778,24 +766,25 @@ static struct cpufreq_driver acpi_cpufreq_driver = { static int __init acpi_cpufreq_init(void) { + int ret; + dprintk("acpi_cpufreq_init\n"); - acpi_cpufreq_early_init(); + ret = acpi_cpufreq_early_init(); + if (ret) + return ret; return cpufreq_register_driver(&acpi_cpufreq_driver); } static void __exit acpi_cpufreq_exit(void) { - unsigned int i; dprintk("acpi_cpufreq_exit\n"); cpufreq_unregister_driver(&acpi_cpufreq_driver); - for_each_possible_cpu(i) { - kfree(acpi_perf_data[i]); - acpi_perf_data[i] = NULL; - } + free_percpu(acpi_perf_data); + return; } diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index c4efc0c17f8f..463b0247cbc5 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -539,7 +539,7 @@ end: } int acpi_processor_preregister_performance( - struct acpi_processor_performance **performance) + struct acpi_processor_performance *performance) { int count, count_target; int retval = 0; @@ -567,12 +567,12 @@ int acpi_processor_preregister_performance( continue; } - if (!performance || !performance[i]) { + if (!performance || !percpu_ptr(performance, i)) { retval = -EINVAL; continue; } - pr->performance = performance[i]; + pr->performance = percpu_ptr(performance, i); cpu_set(i, pr->performance->shared_cpu_map); if (acpi_processor_get_psd(pr)) { retval = -EINVAL; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index f9f987f8e661..ec3ffdadb4d2 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -232,7 +232,7 @@ struct acpi_processor_errata { extern int acpi_processor_preregister_performance(struct acpi_processor_performance - **performance); + *performance); extern int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu); -- cgit v1.2.3 From b3627bb19f8f0ca12136d985d4d73c437cba0e14 Mon Sep 17 00:00:00 2001 From: Gabriel C Date: Thu, 2 Aug 2007 20:20:44 +0200 Subject: wbsd: fix section mismatch warnings This patch fixes the following section mismatch warnings ... WARNING: vmlinux.o(.init.text+0x29d40): Section mismatch: reference to .exit.text:wbsd_release_resources (between 'wbsd_init' and 'wbsd_probe') WARNING: vmlinux.o(.init.text+0x29d49): Section mismatch: reference to .exit.text:wbsd_free_mmc (between 'wbsd_init' and 'wbsd_probe') WARNING: vmlinux.o(.init.text+0x29f28): Section mismatch: reference to .exit.text:wbsd_free_mmc (between 'wbsd_init' and 'wbsd_probe') ... Signed-off-by: Gabriel Craciunescu Acked-by: Sam Ravnborg Signed-off-by: Pierre Ossman --- drivers/mmc/host/wbsd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index e0c9808fd424..9bf2a877113b 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -1266,7 +1266,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev) return 0; } -static void __devexit wbsd_free_mmc(struct device *dev) +static void wbsd_free_mmc(struct device *dev) { struct mmc_host *mmc; struct wbsd_host *host; @@ -1358,7 +1358,7 @@ static int __devinit wbsd_request_region(struct wbsd_host *host, int base) return 0; } -static void __devexit wbsd_release_regions(struct wbsd_host *host) +static void wbsd_release_regions(struct wbsd_host *host) { if (host->base) release_region(host->base, 8); @@ -1434,7 +1434,7 @@ err: "Falling back on FIFO.\n", dma); } -static void __devexit wbsd_release_dma(struct wbsd_host *host) +static void wbsd_release_dma(struct wbsd_host *host) { if (host->dma_addr) { dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, @@ -1484,7 +1484,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) return 0; } -static void __devexit wbsd_release_irq(struct wbsd_host *host) +static void wbsd_release_irq(struct wbsd_host *host) { if (!host->irq) return; @@ -1535,7 +1535,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host *host, * Release all resources for the host. */ -static void __devexit wbsd_release_resources(struct wbsd_host *host) +static void wbsd_release_resources(struct wbsd_host *host) { wbsd_release_dma(host); wbsd_release_irq(host); -- cgit v1.2.3 From aafabfab26bf4968b5c6423a3c53e920ae8fa406 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 9 Aug 2007 14:28:02 +0200 Subject: mmc: reorganize bounce buffer init Reorganize the code that initializes mmc_block's bounce buffer in order to avoid warnings when MMC_BLOCK_BOUNCE isn't used. Signed-off-by: Pierre Ossman --- drivers/mmc/card/queue.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index c9a289c6c139..b0abc7d92805 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -117,7 +117,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock struct mmc_host *host = card->host; u64 limit = BLK_BOUNCE_HIGH; int ret; - unsigned int bouncesz; if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = *mmc_dev(host)->dma_mask; @@ -134,6 +133,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock #ifdef CONFIG_MMC_BLOCK_BOUNCE if (host->max_hw_segs == 1) { + unsigned int bouncesz; + bouncesz = MMC_QUEUE_BOUNCESZ; if (bouncesz > host->max_req_size) @@ -156,14 +157,14 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock GFP_KERNEL); if (!mq->sg) { ret = -ENOMEM; - goto free_bounce_buf; + goto cleanup_queue; } mq->bounce_sg = kmalloc(sizeof(struct scatterlist) * bouncesz / 512, GFP_KERNEL); if (!mq->bounce_sg) { ret = -ENOMEM; - goto free_sg; + goto cleanup_queue; } } } @@ -197,14 +198,13 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock if (mq->bounce_sg) kfree(mq->bounce_sg); mq->bounce_sg = NULL; - free_sg: - kfree(mq->sg); + cleanup_queue: + if (mq->sg) + kfree(mq->sg); mq->sg = NULL; - free_bounce_buf: if (mq->bounce_buf) kfree(mq->bounce_buf); mq->bounce_buf = NULL; - cleanup_queue: blk_cleanup_queue(mq->queue); return ret; } -- cgit v1.2.3 From 37b758e8bcf705a1bc6fd94bfc53ded2d506116c Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 8 Aug 2007 12:01:44 +0200 Subject: mmc: at91_mci: remove whitespace at the end of lines Some cleanup with whitespace/tab at the end of lines. Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman --- drivers/mmc/host/at91_mci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 62564ccde03a..bfebd2fa7ada 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -83,7 +83,7 @@ #define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \ | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \ - | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE) + | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE) #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) @@ -676,15 +676,15 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) int_status = at91_mci_read(host, AT91_MCI_SR); int_mask = at91_mci_read(host, AT91_MCI_IMR); - + pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask, int_status & int_mask); - + int_status = int_status & int_mask; if (int_status & AT91_MCI_ERRORS) { completed = 1; - + if (int_status & AT91_MCI_UNRE) pr_debug("MMC: Underrun error\n"); if (int_status & AT91_MCI_OVRE) -- cgit v1.2.3 From 37250097e1b730c30da1790e354c0da65e617043 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 9 Aug 2007 20:52:35 +1000 Subject: Fix non-TSC guest clocksource lockup lguest uses a host-supplied wallclock-based clocksource when the TSC is not reliable. As this is already in nanoseconds, I naively used a multiplier of 1 and a shift of 0. But update_wall_time() in its infinite wisdom decides to adjust the clock a little (where does it think it's getting a more accurate time from?) It will happily tweak the multiplier... to 0, then -1. So the "fix" is to use a shift of 22 like everyone else, and a multiplier of 1 << 22. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/lguest/lguest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c index 1bc1546c7fd0..fb17d2757be9 100644 --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c @@ -687,7 +687,8 @@ static struct clocksource lguest_clock = { .rating = 400, .read = lguest_clock_read, .mask = CLOCKSOURCE_MASK(64), - .mult = 1, + .mult = 1 << 22, + .shift = 22, }; /* The "scheduler clock" is just our real clock, adjusted to start at zero */ @@ -770,7 +771,6 @@ static void lguest_time_init(void) * way, the "rating" is initialized so high that it's always chosen * over any other clocksource. */ if (lguest_data.tsc_khz) { - lguest_clock.shift = 22; lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz, lguest_clock.shift); lguest_clock.flags = CLOCK_SOURCE_IS_CONTINUOUS; -- cgit v1.2.3 From 0d027c01cd36b8cff727c78d2e40d334ba9895a8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 9 Aug 2007 20:57:13 +1000 Subject: lguest: Fix Malicious Guest GDT Host Crash If a Guest makes hypercall which sets a GDT entry to not present, we currently set any segment registers using that GDT entry to 0. Unfortunately, this is not sufficient: there are other ways of altering GDT entries which will cause a fault. The correct solution to do what Linux does: let them set any GDT value they want and handle the #GP when popping causes a fault. This has the added benefit of making our Switcher slightly more robust in the case of any other bugs which cause it to fault. We kill the Guest if it causes a fault in the Switcher: it's the Guest's responsibility to make sure it's not using segments when it changes them. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/lguest/core.c | 5 +++ drivers/lguest/interrupts_and_traps.c | 9 +++-- drivers/lguest/lguest.c | 5 ++- drivers/lguest/segments.c | 62 +++-------------------------------- drivers/lguest/switcher.S | 15 +++++---- 5 files changed, 29 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 0a46e8837d9a..4a315f08a567 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -453,6 +453,11 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) * lguest_pages". */ copy_in_guest_info(lg, pages); + /* Set the trap number to 256 (impossible value). If we fault while + * switching to the Guest (bad segment registers or bug), this will + * cause us to abort the Guest. */ + lg->regs->trapnum = 256; + /* Now: we push the "eflags" register on the stack, then do an "lcall". * This is how we change from using the kernel code segment to using * the dedicated lguest code segment, as well as jumping into the diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index 49787e964a0d..49aa55577d0d 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c @@ -195,13 +195,16 @@ static int has_err(unsigned int trap) /* deliver_trap() returns true if it could deliver the trap. */ int deliver_trap(struct lguest *lg, unsigned int num) { - u32 lo = lg->idt[num].a, hi = lg->idt[num].b; + /* Trap numbers are always 8 bit, but we set an impossible trap number + * for traps inside the Switcher, so check that here. */ + if (num >= ARRAY_SIZE(lg->idt)) + return 0; /* Early on the Guest hasn't set the IDT entries (or maybe it put a * bogus one in): if we fail here, the Guest will be killed. */ - if (!idt_present(lo, hi)) + if (!idt_present(lg->idt[num].a, lg->idt[num].b)) return 0; - set_guest_interrupt(lg, lo, hi, has_err(num)); + set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num)); return 1; } diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c index fb17d2757be9..524beea7fb19 100644 --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c @@ -323,9 +323,12 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, * __thread variables). So we have a hypercall specifically for this case. */ static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) { + /* There's one problem which normal hardware doesn't have: the Host + * can't handle us removing entries we're currently using. So we clear + * the GS register here: if it's needed it'll be reloaded anyway. */ + loadsegment(gs, 0); lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0); } -/*:*/ /*G:038 That's enough excitement for now, back to ploughing through each of * the paravirt_ops (we're about 1/3 of the way through). diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c index f675a41a80da..9b81119f46e9 100644 --- a/drivers/lguest/segments.c +++ b/drivers/lguest/segments.c @@ -43,22 +43,6 @@ * begin. */ -/* Is the descriptor the Guest wants us to put in OK? - * - * The flag which Intel says must be zero: must be zero. The descriptor must - * be present, (this is actually checked earlier but is here for thorougness), - * and the descriptor type must be 1 (a memory segment). */ -static int desc_ok(const struct desc_struct *gdt) -{ - return ((gdt->b & 0x00209000) == 0x00009000); -} - -/* Is the segment present? (Otherwise it can't be used by the Guest). */ -static int segment_present(const struct desc_struct *gdt) -{ - return gdt->b & 0x8000; -} - /* There are several entries we don't let the Guest set. The TSS entry is the * "Task State Segment" which controls all kinds of delicate things. The * LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the @@ -71,37 +55,11 @@ static int ignored_gdt(unsigned int num) || num == GDT_ENTRY_DOUBLEFAULT_TSS); } -/* If the Guest asks us to remove an entry from the GDT, we have to be careful. - * If one of the segment registers is pointing at that entry the Switcher will - * crash when it tries to reload the segment registers for the Guest. - * - * It doesn't make much sense for the Guest to try to remove its own code, data - * or stack segments while they're in use: assume that's a Guest bug. If it's - * one of the lesser segment registers using the removed entry, we simply set - * that register to 0 (unusable). */ -static void check_segment_use(struct lguest *lg, unsigned int desc) -{ - /* GDT entries are 8 bytes long, so we divide to get the index and - * ignore the bottom bits. */ - if (lg->regs->gs / 8 == desc) - lg->regs->gs = 0; - if (lg->regs->fs / 8 == desc) - lg->regs->fs = 0; - if (lg->regs->es / 8 == desc) - lg->regs->es = 0; - if (lg->regs->ds / 8 == desc - || lg->regs->cs / 8 == desc - || lg->regs->ss / 8 == desc) - kill_guest(lg, "Removed live GDT entry %u", desc); -} -/*:*/ -/*M:009 We wouldn't need to check for removal of in-use segments if we handled - * faults in the Switcher. However, it's probably not a worthwhile - * optimization. :*/ - -/*H:610 Once the GDT has been changed, we look through the changed entries and - * see if they're OK. If not, we'll call kill_guest() and the Guest will never - * get to use the invalid entries. */ +/*H:610 Once the GDT has been changed, we fix the new entries up a little. We + * don't care if they're invalid: the worst that can happen is a General + * Protection Fault in the Switcher when it restores a Guest segment register + * which tries to use that entry. Then we kill the Guest for causing such a + * mess: the message will be "unhandled trap 256". */ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) { unsigned int i; @@ -112,16 +70,6 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) if (ignored_gdt(i)) continue; - /* We could fault in switch_to_guest if they are using - * a removed segment. */ - if (!segment_present(&lg->gdt[i])) { - check_segment_use(lg, i); - continue; - } - - if (!desc_ok(&lg->gdt[i])) - kill_guest(lg, "Bad GDT descriptor %i", i); - /* Segment descriptors contain a privilege level: the Guest is * sometimes careless and leaves this as 0, even though it's * running at privilege level 1. If so, we fix it here. */ diff --git a/drivers/lguest/switcher.S b/drivers/lguest/switcher.S index d418179ea6b5..7c9c230cc845 100644 --- a/drivers/lguest/switcher.S +++ b/drivers/lguest/switcher.S @@ -47,6 +47,7 @@ // Down here in the depths of assembler code. #include #include +#include #include "lg.h" // We mark the start of the code to copy @@ -182,13 +183,15 @@ ENTRY(switch_to_guest) movl $(LGUEST_DS), %eax; \ movl %eax, %ds; \ /* So where are we? Which CPU, which struct? \ - * The stack is our clue: our TSS sets \ - * It at the end of "struct lguest_pages" \ - * And we then pushed and pushed and pushed Guest regs: \ - * Now stack points atop the "struct lguest_regs". \ - * Subtract that offset, and we find our struct. */ \ + * The stack is our clue: our TSS starts \ + * It at the end of "struct lguest_pages". \ + * Or we may have stumbled while restoring \ + * Our Guest segment regs while in switch_to_guest, \ + * The fault pushed atop that part-unwound stack. \ + * If we round the stack down to the page start \ + * We're at the start of "struct lguest_pages". */ \ movl %esp, %eax; \ - subl $LGUEST_PAGES_regs, %eax; \ + andl $(~(1 << PAGE_SHIFT - 1)), %eax; \ /* Save our trap number: the switch will obscure it \ * (The Guest regs are not mapped here in the Host) \ * %ebx holds it safe for deliver_to_host */ \ -- cgit v1.2.3 From 5693ce6f9b9f08942e55e3825db014f8b1205772 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 10 Aug 2007 14:32:26 +0200 Subject: [S390] cio: avoid memory leak on error in css_alloc_subchannel(). sch->lock has been allocated in cio_validate_subchannel(), it must be freed if cio_modify() fails. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 1c27a5a06b49..5635e656c1a3 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -79,6 +79,7 @@ css_alloc_subchannel(struct subchannel_id schid) sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; ret = cio_modify(sch); if (ret) { + kfree(sch->lock); kfree(sch); return ERR_PTR(ret); } -- cgit v1.2.3 From c6d0e8014a59b641c0669cf5df151667144f220e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 10 Aug 2007 14:32:28 +0200 Subject: [S390] qdio: make sure data structures are correctly aligned. The slsb structure contained at the beginning of the qdio_q structure must start on a 256 byte boundary. To make sure this is the case even if slab debugging is turned on create an own slab cache for qdio_q structures. Besides that don't use the slab allocator to allocate whole pages. Use the page allocator instead. Also fix a few memory leaks in error handling code. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio.c | 92 +++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index ed026a1dc324..03347aed2b3e 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -81,6 +81,7 @@ static __u32 volatile spare_indicator; static atomic_t spare_indicator_usecount; #define QDIO_MEMPOOL_SCSSC_ELEMENTS 2 static mempool_t *qdio_mempool_scssc; +static struct kmem_cache *qdio_q_cache; static debug_info_t *qdio_dbf_setup; static debug_info_t *qdio_dbf_sbal; @@ -1617,23 +1618,21 @@ static void qdio_release_irq_memory(struct qdio_irq *irq_ptr) { int i; + struct qdio_q *q; - for (i=0;iinput_qs[i]) - goto next; - - kfree(irq_ptr->input_qs[i]->slib); - kfree(irq_ptr->input_qs[i]); - -next: - if (!irq_ptr->output_qs[i]) - continue; - - kfree(irq_ptr->output_qs[i]->slib); - kfree(irq_ptr->output_qs[i]); - + for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) { + q = irq_ptr->input_qs[i]; + if (q) { + free_page((unsigned long) q->slib); + kmem_cache_free(qdio_q_cache, q); + } + q = irq_ptr->output_qs[i]; + if (q) { + free_page((unsigned long) q->slib); + kmem_cache_free(qdio_q_cache, q); + } } - kfree(irq_ptr->qdr); + free_page((unsigned long) irq_ptr->qdr); free_page((unsigned long) irq_ptr); } @@ -1680,44 +1679,35 @@ qdio_alloc_qs(struct qdio_irq *irq_ptr, { int i; struct qdio_q *q; - int result=-ENOMEM; - - for (i=0;islib = kmalloc(PAGE_SIZE, GFP_KERNEL); + q->slib = (struct slib *) __get_free_page(GFP_KERNEL); if (!q->slib) { - QDIO_PRINT_ERR("kmalloc of slib failed!\n"); - goto out; + kmem_cache_free(qdio_q_cache, q); + return -ENOMEM; } - irq_ptr->input_qs[i]=q; } - for (i=0;islib=kmalloc(PAGE_SIZE,GFP_KERNEL); + q->slib = (struct slib *) __get_free_page(GFP_KERNEL); if (!q->slib) { - QDIO_PRINT_ERR("kmalloc of slib failed!\n"); - goto out; + kmem_cache_free(qdio_q_cache, q); + return -ENOMEM; } - irq_ptr->output_qs[i]=q; } - - result=0; -out: - return result; + return 0; } static void @@ -2985,17 +2975,17 @@ qdio_allocate(struct qdio_initialize *init_data) QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*)); if (!irq_ptr) { - QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n"); + QDIO_PRINT_ERR("allocation of irq_ptr failed!\n"); return -ENOMEM; } init_MUTEX(&irq_ptr->setting_up_sema); /* QDR must be in DMA area since CCW data address is only 32 bit */ - irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA); + irq_ptr->qdr = (struct qdr *) __get_free_page(GFP_KERNEL | GFP_DMA); if (!(irq_ptr->qdr)) { free_page((unsigned long) irq_ptr); - QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n"); + QDIO_PRINT_ERR("allocation of irq_ptr->qdr failed!\n"); return -ENOMEM; } QDIO_DBF_TEXT0(0,setup,"qdr:"); @@ -3004,6 +2994,7 @@ qdio_allocate(struct qdio_initialize *init_data) if (qdio_alloc_qs(irq_ptr, init_data->no_input_qs, init_data->no_output_qs)) { + QDIO_PRINT_ERR("queue allocation failed!\n"); qdio_release_irq_memory(irq_ptr); return -ENOMEM; } @@ -3895,9 +3886,19 @@ init_QDIO(void) if (res) return res; + qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q), + 256, 0, NULL); + if (!qdio_q_cache) { + qdio_release_qdio_memory(); + return -ENOMEM; + } + res = qdio_register_dbf_views(); - if (res) + if (res) { + kmem_cache_destroy(qdio_q_cache); + qdio_release_qdio_memory(); return res; + } QDIO_DBF_TEXT0(0,setup,"initQDIO"); res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); @@ -3929,6 +3930,7 @@ cleanup_QDIO(void) qdio_release_qdio_memory(); qdio_unregister_dbf_views(); mempool_destroy(qdio_mempool_scssc); + kmem_cache_destroy(qdio_q_cache); bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); printk("qdio: %s: module removed\n",version); } -- cgit v1.2.3 From 1eade380c5f3e69348531ade5e9f9c5ae6485874 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 10 Aug 2007 14:32:30 +0200 Subject: [S390] vmur: allocate single record buffers instead of one big data buffer vmur allocates one contiguous kernel buffer to copy user data when creating ccw programs for punch or printer. If big block sizes are used, under memory pressure it can happen, that we do not get memory in one chunk. Now we allocate memory for each single record to avoid high order allocations. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 75 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 161867cebd8c..1b758b51d7ed 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -119,10 +119,12 @@ static void urdev_put(struct urdev *urd) /* * Low-level functions to do I/O to a ur device. * alloc_chan_prog + * free_chan_prog * do_ur_io * ur_int_handler * * alloc_chan_prog allocates and builds the channel program + * free_chan_prog frees memory of the channel program * * do_ur_io issues the channel program to the device and blocks waiting * on a completion event it publishes at urd->io_done. The function @@ -137,6 +139,16 @@ static void urdev_put(struct urdev *urd) * address pointer that alloc_chan_prog returned. */ +static void free_chan_prog(struct ccw1 *cpa) +{ + struct ccw1 *ptr = cpa; + + while (ptr->cda) { + kfree((void *)(addr_t) ptr->cda); + ptr++; + } + kfree(cpa); +} /* * alloc_chan_prog @@ -144,44 +156,45 @@ static void urdev_put(struct urdev *urd) * with a final NOP CCW command-chained on (which ensures that CE and DE * are presented together in a single interrupt instead of as separate * interrupts unless an incorrect length indication kicks in first). The - * data length in each CCW is reclen. The caller must ensure that count - * is an integral multiple of reclen. - * The channel program pointer returned by this function must be freed - * with kfree. The caller is responsible for checking that - * count/reclen is not ridiculously large. + * data length in each CCW is reclen. */ -static struct ccw1 *alloc_chan_prog(char *buf, size_t count, size_t reclen) +static struct ccw1 *alloc_chan_prog(const char __user *ubuf, int rec_count, + int reclen) { - size_t num_ccws; struct ccw1 *cpa; + void *kbuf; int i; - TRACE("alloc_chan_prog(%p, %zu, %zu)\n", buf, count, reclen); + TRACE("alloc_chan_prog(%p, %i, %i)\n", ubuf, rec_count, reclen); /* * We chain a NOP onto the writes to force CE+DE together. * That means we allocate room for CCWs to cover count/reclen * records plus a NOP. */ - num_ccws = count / reclen + 1; - cpa = kmalloc(num_ccws * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); + cpa = kzalloc((rec_count + 1) * sizeof(struct ccw1), + GFP_KERNEL | GFP_DMA); if (!cpa) - return NULL; + return ERR_PTR(-ENOMEM); - for (i = 0; count; i++) { + for (i = 0; i < rec_count; i++) { cpa[i].cmd_code = WRITE_CCW_CMD; cpa[i].flags = CCW_FLAG_CC | CCW_FLAG_SLI; cpa[i].count = reclen; - cpa[i].cda = __pa(buf); - buf += reclen; - count -= reclen; + kbuf = kmalloc(reclen, GFP_KERNEL | GFP_DMA); + if (!kbuf) { + free_chan_prog(cpa); + return ERR_PTR(-ENOMEM); + } + cpa[i].cda = (u32)(addr_t) kbuf; + if (copy_from_user(kbuf, ubuf, reclen)) { + free_chan_prog(cpa); + return ERR_PTR(-EFAULT); + } + ubuf += reclen; } /* The following NOP CCW forces CE+DE to be presented together */ cpa[i].cmd_code = CCW_CMD_NOOP; - cpa[i].flags = 0; - cpa[i].count = 0; - cpa[i].cda = 0; - return cpa; } @@ -325,24 +338,11 @@ static ssize_t do_write(struct urdev *urd, const char __user *udata, size_t count, size_t reclen, loff_t *ppos) { struct ccw1 *cpa; - char *buf; int rc; - /* Data buffer must be under 2GB line for fmt1 CCWs: hence GFP_DMA */ - buf = kmalloc(count, GFP_KERNEL | GFP_DMA); - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, udata, count)) { - rc = -EFAULT; - goto fail_kfree_buf; - } - - cpa = alloc_chan_prog(buf, count, reclen); - if (!cpa) { - rc = -ENOMEM; - goto fail_kfree_buf; - } + cpa = alloc_chan_prog(udata, count / reclen, reclen); + if (IS_ERR(cpa)) + return PTR_ERR(cpa); rc = do_ur_io(urd, cpa); if (rc) @@ -354,10 +354,9 @@ static ssize_t do_write(struct urdev *urd, const char __user *udata, } *ppos += count; rc = count; + fail_kfree_cpa: - kfree(cpa); -fail_kfree_buf: - kfree(buf); + free_chan_prog(cpa); return rc; } -- cgit v1.2.3 From 278bc68c4bfcd1af97972f5c4458acf3b9b19c37 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 10 Aug 2007 14:32:31 +0200 Subject: [S390] vmur: use DECLARE_COMPLETION_ONSTACK to keep lockdep happy INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. 000000000ff9fb08 000000000ff9fb18 0000000000000002 0000000000000000 000000000ff9fbb8 000000000ff9fb30 000000000ff9fb30 0000000000104198 0000000000000000 0000000000000002 0000000000000000 0000000000000000 000000000ff9fb18 000000000000000c 000000000ff9fb18 000000000ff9fb88 0000000000448db0 0000000000104198 000000000ff9fb18 000000000ff9fb68 Call Trace: ([<00000000001040ea>] show_trace+0x12e/0x170) [<00000000001041f2>] show_stack+0xc6/0xf8 [<0000000000104252>] dump_stack+0x2e/0x3c [<0000000000155f9c>] __lock_acquire+0x460/0x1048 [<0000000000156c16>] lock_acquire+0x92/0xb8 [<000000000043f406>] _spin_lock_irqsave+0x62/0x80 [<0000000000121382>] complete+0x32/0x78 [<000000001082b468>] ur_int_handler+0xc8/0xec [vmur] [<0000000000313216>] ccw_device_call_handler+0xae/0xd4 [<0000000000310da4>] ccw_device_irq+0x5c/0x130 [<0000000000312c84>] io_subchannel_irq+0x8c/0x118 [<000000000030a88c>] do_IRQ+0x16c/0x194 [<0000000000111a62>] io_no_vtime+0x16/0x1c [<0000000080001394>] 0x80001394 Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 1b758b51d7ed..27b8bf927415 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -202,7 +202,7 @@ static int do_ur_io(struct urdev *urd, struct ccw1 *cpa) { int rc; struct ccw_device *cdev = urd->cdev; - DECLARE_COMPLETION(event); + DECLARE_COMPLETION_ONSTACK(event); TRACE("do_ur_io: cpa=%p\n", cpa); -- cgit v1.2.3 From f2405598e0678e9c93dd780f2a12fc562ece3d13 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 10 Aug 2007 14:32:32 +0200 Subject: [S390] vmur: reject open on z/VM reader files with status HOLD If a reader file with HOLD status is at the top of the reader queue, currently all read requests will return data of the second file in the queue. But the semantics of vmur is that always the topmost file is read. With this fix -EPERM is returned on open, if the topmost reader file is in HOLD status. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 4 +++- drivers/s390/char/vmur.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 27b8bf927415..04395c0f99d8 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -556,7 +556,9 @@ static int verify_device(struct urdev *urd) rc = diag_read_next_file_info(&fcb, 0); if (rc) return rc; - + /* if file is in hold status, we do not read it */ + if (fcb.file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) + return -EPERM; /* open file on virtual reader */ buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h index 16d0a4e38e40..522a9dfaa275 100644 --- a/drivers/s390/char/vmur.h +++ b/drivers/s390/char/vmur.h @@ -50,7 +50,9 @@ struct file_control_block { char rest[200]; } __attribute__ ((packed)); -#define FLG_CP_DUMP 0x10 +#define FLG_SYSTEM_HOLD 0x04 +#define FLG_CP_DUMP 0x10 +#define FLG_USER_HOLD 0x20 /* * A struct urdev is created for each ur device that is made available -- cgit v1.2.3 From 4eac34529bce2b4cca9be90a6903c965baa8193c Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 10 Aug 2007 14:32:33 +0200 Subject: [S390] vmur: add "top of queue" sanity check for reader open If the z/VM reader is already open, it can happen that after opening the Linux reader device, not the topmost file is processed. According the semantics of the Linux z/VM unit record device driver, always the topmost file has to be processed. With this fix an error is returned if that is not the case. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 7 ++++++- drivers/s390/char/vmur.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 04395c0f99d8..a9d58629e795 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -565,9 +565,14 @@ static int verify_device(struct urdev *urd) return -ENOMEM; rc = diag_read_file(urd->dev_id.devno, buf); kfree(buf); - if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */ return rc; + /* check if the file on top of the queue is open now */ + rc = diag_read_next_file_info(&fcb, 0); + if (rc) + return rc; + if (!(fcb.file_stat & FLG_IN_USE)) + return -EMFILE; return 0; default: return -ENOTSUPP; diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h index 522a9dfaa275..2b3c564e0472 100644 --- a/drivers/s390/char/vmur.h +++ b/drivers/s390/char/vmur.h @@ -53,6 +53,7 @@ struct file_control_block { #define FLG_SYSTEM_HOLD 0x04 #define FLG_CP_DUMP 0x10 #define FLG_USER_HOLD 0x20 +#define FLG_IN_USE 0x80 /* * A struct urdev is created for each ur device that is made available -- cgit v1.2.3 From 3eed13cc3beaa9ee07b126a662def88f7281394e Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 10 Aug 2007 14:32:34 +0200 Subject: [S390] vmur: diag14 only works with buffers below 2GB If memory buffers above 2GB are used, diagnose 14 raises a specification exception. This fix ensures that buffer allocation is done below the 2GB boundary. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 106 +++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index a9d58629e795..04b19bdc09da 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -472,7 +472,7 @@ static ssize_t diag14_read(struct file *file, char __user *ubuf, size_t count, return rc; len = min((size_t) PAGE_SIZE, count); - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + buf = (char *) __get_free_page(GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; @@ -499,7 +499,7 @@ static ssize_t diag14_read(struct file *file, char __user *ubuf, size_t count, *offs += copied; rc = copied; fail: - kfree(buf); + free_page((unsigned long) buf); return rc; } @@ -542,63 +542,97 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) } } -static int verify_device(struct urdev *urd) +static int verify_uri_device(struct urdev *urd) { - struct file_control_block fcb; + struct file_control_block *fcb; char *buf; int rc; + fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA); + if (!fcb) + return -ENOMEM; + + /* check for empty reader device (beginning of chain) */ + rc = diag_read_next_file_info(fcb, 0); + if (rc) + goto fail_free_fcb; + + /* if file is in hold status, we do not read it */ + if (fcb->file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) { + rc = -EPERM; + goto fail_free_fcb; + } + + /* open file on virtual reader */ + buf = (char *) __get_free_page(GFP_KERNEL | GFP_DMA); + if (!buf) { + rc = -ENOMEM; + goto fail_free_fcb; + } + rc = diag_read_file(urd->dev_id.devno, buf); + if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */ + goto fail_free_buf; + + /* check if the file on top of the queue is open now */ + rc = diag_read_next_file_info(fcb, 0); + if (rc) + goto fail_free_buf; + if (!(fcb->file_stat & FLG_IN_USE)) { + rc = -EMFILE; + goto fail_free_buf; + } + rc = 0; + +fail_free_buf: + free_page((unsigned long) buf); +fail_free_fcb: + kfree(fcb); + return rc; +} + +static int verify_device(struct urdev *urd) +{ switch (urd->class) { case DEV_CLASS_UR_O: return 0; /* no check needed here */ case DEV_CLASS_UR_I: - /* check for empty reader device (beginning of chain) */ - rc = diag_read_next_file_info(&fcb, 0); - if (rc) - return rc; - /* if file is in hold status, we do not read it */ - if (fcb.file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) - return -EPERM; - /* open file on virtual reader */ - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - rc = diag_read_file(urd->dev_id.devno, buf); - kfree(buf); - if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */ - return rc; - /* check if the file on top of the queue is open now */ - rc = diag_read_next_file_info(&fcb, 0); - if (rc) - return rc; - if (!(fcb.file_stat & FLG_IN_USE)) - return -EMFILE; - return 0; + return verify_uri_device(urd); default: return -ENOTSUPP; } } -static int get_file_reclen(struct urdev *urd) +static int get_uri_file_reclen(struct urdev *urd) { - struct file_control_block fcb; + struct file_control_block *fcb; int rc; + fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA); + if (!fcb) + return -ENOMEM; + rc = diag_read_next_file_info(fcb, 0); + if (rc) + goto fail_free; + if (fcb->file_stat & FLG_CP_DUMP) + rc = 0; + else + rc = fcb->rec_len; + +fail_free: + kfree(fcb); + return rc; +} + +static int get_file_reclen(struct urdev *urd) +{ switch (urd->class) { case DEV_CLASS_UR_O: return 0; case DEV_CLASS_UR_I: - rc = diag_read_next_file_info(&fcb, 0); - if (rc) - return rc; - break; + return get_uri_file_reclen(urd); default: return -ENOTSUPP; } - if (fcb.file_stat & FLG_CP_DUMP) - return 0; - - return fcb.rec_len; } static int ur_open(struct inode *inode, struct file *file) -- cgit v1.2.3 From cbea66d9788a344e16e161f22a6e0c4deef2c0ed Mon Sep 17 00:00:00 2001 From: Melissa Howland Date: Fri, 10 Aug 2007 14:32:35 +0200 Subject: [S390] monwriter: Serialization bug for multithreaded applications. Locking added so that multithreaded applications can now do writes from different threads without the risk of storage corruption. Signed-off-by: Melissa Howland Signed-off-by: Martin Schwidefsky --- drivers/s390/char/monwriter.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 268598ef3efe..20442fbf9346 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ struct mon_private { size_t hdr_to_read; size_t data_to_read; struct mon_buf *current_buf; + struct mutex thread_mutex; }; /* @@ -179,6 +181,7 @@ static int monwrite_open(struct inode *inode, struct file *filp) return -ENOMEM; INIT_LIST_HEAD(&monpriv->list); monpriv->hdr_to_read = sizeof(monpriv->hdr); + mutex_init(&monpriv->thread_mutex); filp->private_data = monpriv; return nonseekable_open(inode, filp); } @@ -209,6 +212,7 @@ static ssize_t monwrite_write(struct file *filp, const char __user *data, void *to; int rc; + mutex_lock(&monpriv->thread_mutex); for (written = 0; written < count; ) { if (monpriv->hdr_to_read) { len = min(count - written, monpriv->hdr_to_read); @@ -247,11 +251,13 @@ static ssize_t monwrite_write(struct file *filp, const char __user *data, } monpriv->hdr_to_read = sizeof(monpriv->hdr); } + mutex_unlock(&monpriv->thread_mutex); return written; out_error: monpriv->data_to_read = 0; monpriv->hdr_to_read = sizeof(struct monwrite_hdr); + mutex_unlock(&monpriv->thread_mutex); return rc; } -- cgit v1.2.3 From 393cdad6267bc2abf75973d15310168ff3e15441 Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Thu, 9 Aug 2007 08:12:46 -0400 Subject: hwmon: fix w83781d temp sensor type setting Commit 348753379a7704087603dad403603e825422fd9a introduced a regression that caused temp2 and temp3 sensor type settings to be written to temp1 instead. The result is that temp sensor readings could be way off. Signed-off-by: Mark M. Hoffman --- drivers/hwmon/w83781d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index f85b48fea1c4..c95909cc1d21 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -740,9 +740,9 @@ store_sensor(struct device *dev, struct device_attribute *da, static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_sensor, store_sensor, 0); static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 1); static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 2); /* I2C devices get this name attribute automatically, but for ISA devices we must create it by ourselves. */ -- cgit v1.2.3 From c7149d6bce2561aeaa48caaa1700aa8b3b22008f Mon Sep 17 00:00:00 2001 From: "Alan D. Brunelle" Date: Tue, 7 Aug 2007 15:30:23 +0200 Subject: Fix remap handling by blktrace This patch provides more information concerning REMAP operations on block IOs. The additional information provides clearer details at the user level, and supports post-processing analysis in btt. o Adds in partition remaps on the same device. o Fixed up the remap information in DM to be in the right order o Sent up mapped-from and mapped-to device information Signed-off-by: Alan D. Brunelle Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 4 ++++ drivers/md/dm.c | 4 ++-- include/linux/blktrace_api.h | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 8c2caff87cc3..a15845c164f2 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3047,6 +3047,10 @@ static inline void blk_partition_remap(struct bio *bio) bio->bi_sector += p->start_sect; bio->bi_bdev = bdev->bd_contains; + + blk_add_trace_remap(bdev_get_queue(bio->bi_bdev), bio, + bdev->bd_dev, bio->bi_sector, + bio->bi_sector - p->start_sect); } } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 141ff9fa296e..2120155929a6 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -580,8 +580,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, /* the bio has been remapped so dispatch it */ blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, - tio->io->bio->bi_bdev->bd_dev, sector, - clone->bi_sector); + tio->io->bio->bi_bdev->bd_dev, + clone->bi_sector, sector); generic_make_request(clone); } else if (r < 0 || r == DM_MAPIO_REQUEUE) { diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 90874a5d7d78..7b5d56b82b59 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -105,7 +105,7 @@ struct blk_io_trace { */ struct blk_io_trace_remap { __be32 device; - u32 __pad; + __be32 device_from; __be64 sector; }; @@ -272,6 +272,7 @@ static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio, return; r.device = cpu_to_be32(dev); + r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev); r.sector = cpu_to_be64(to); __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r); -- cgit v1.2.3 From 9b99628f8e9e0b5f5ecacce558defe529a6e00c1 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 11 Aug 2007 22:34:27 +0200 Subject: Clean up duplicate includes in drivers/block/ This patch cleans up duplicate includes in drivers/block/ Signed-off-by: Jesper Juhl Acked-by: Stephen Rothwell Cc: Satyam Sharma Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/viodasd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 85916e2665d4..af3969a9c963 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From 1aebe18787ca2e915eb8204d365ba2484d53223b Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sat, 11 Aug 2007 22:34:29 +0200 Subject: drivers/block/cciss.c: kmalloc + memset conversion to kzalloc drivers/block/cciss.c | 104285 -> 104168 (-117 bytes) drivers/block/cciss.o | 277400 -> 277124 (-276 bytes) Signed-off-by: Mariusz Kozlowski Acked-by: Mike Miller Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a11b2bd54bbe..084358a828e9 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1977,12 +1977,13 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, { ReadCapdata_struct *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (buf == NULL) { + + buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (!buf) { printk(KERN_WARNING "cciss: out of memory\n"); return; } - memset(buf, 0, sizeof(ReadCapdata_struct)); + if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf, sizeof(ReadCapdata_struct), @@ -2003,7 +2004,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, printk(KERN_INFO " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); - return; } static void @@ -2011,12 +2011,13 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, { ReadCapdata_struct_16 *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); - if (buf == NULL) { + + buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); + if (!buf) { printk(KERN_WARNING "cciss: out of memory\n"); return; } - memset(buf, 0, sizeof(ReadCapdata_struct_16)); + if (withirq) { return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, ctlr, buf, sizeof(ReadCapdata_struct_16), @@ -2038,7 +2039,6 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, printk(KERN_INFO " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); - return; } static int cciss_revalidate(struct gendisk *disk) -- cgit v1.2.3 From 2e4934aa4586832c35e077191849a06f93e4a9a0 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sat, 11 Aug 2007 22:34:30 +0200 Subject: drivers/block/cpqarray.c: better error handling and kmalloc + memset conversion to k[cz]alloc This patch removes some redundant casts, does the kmalloc + memset to k[cz]alloc conversion and it changes the error path to use goto (to avoid code duplication). drivers/block/cpqarray.c | 49567 -> 48623 (-944 bytes) drivers/block/cpqarray.o | 178820 -> 178288 (-532 bytes) Signed-off-by: Mariusz Kozlowski Acked-by: Mike Miller Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cpqarray.c | 78 ++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index be4e3477d83b..eb9799acf65b 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -420,18 +420,17 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) goto Enomem2; } - hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( + hba[i]->cmd_pool = pci_alloc_consistent( hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = kmalloc( - ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), + hba[i]->cmd_pool_bits = kcalloc( + (NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long), GFP_KERNEL); if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool) goto Enomem1; memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long)); printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname); @@ -1660,45 +1659,30 @@ static void getgeometry(int ctlr) info_p->log_drv_map = 0; - id_ldrive = kmalloc(sizeof(id_log_drv_t), GFP_KERNEL); - if(id_ldrive == NULL) - { + id_ldrive = kzalloc(sizeof(id_log_drv_t), GFP_KERNEL); + if (!id_ldrive) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_0; } - id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL); - if(id_ctlr_buf == NULL) - { - kfree(id_ldrive); + id_ctlr_buf = kzalloc(sizeof(id_ctlr_t), GFP_KERNEL); + if (!id_ctlr_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_1; } - id_lstatus_buf = kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); - if(id_lstatus_buf == NULL) - { - kfree(id_ctlr_buf); - kfree(id_ldrive); + id_lstatus_buf = kzalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); + if (!id_lstatus_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_2; } - sense_config_buf = kmalloc(sizeof(config_t), GFP_KERNEL); - if(sense_config_buf == NULL) - { - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); + sense_config_buf = kzalloc(sizeof(config_t), GFP_KERNEL); + if (!sense_config_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_3; } - memset(id_ldrive, 0, sizeof(id_log_drv_t)); - memset(id_ctlr_buf, 0, sizeof(id_ctlr_t)); - memset(id_lstatus_buf, 0, sizeof(sense_log_drv_stat_t)); - memset(sense_config_buf, 0, sizeof(config_t)); - info_p->phys_drives = 0; info_p->log_drv_map = 0; info_p->drv_assign_map = 0; @@ -1712,13 +1696,8 @@ static void getgeometry(int ctlr) * so the idastubopen will fail on all logical drives * on the controller. */ - /* Free all the buffers and return */ printk(KERN_ERR "cpqarray: error sending ID controller\n"); - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; + goto err_4; } info_p->log_drives = id_ctlr_buf->nr_drvs; @@ -1764,12 +1743,7 @@ static void getgeometry(int ctlr) " failed to report status of logical drive %d\n" "Access to this controller has been disabled\n", ctlr, log_unit); - /* Free all the buffers and return */ - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; + goto err_4; } /* Make sure the logical drive is configured @@ -1798,14 +1772,8 @@ static void getgeometry(int ctlr) sizeof(config_t), 0, 0, log_unit); if (ret_code == IO_ERROR) { info_p->log_drv_map = 0; - /* Free all the buffers and return */ printk(KERN_ERR "cpqarray: error sending sense config\n"); - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; - + goto err_4; } info_p->phys_drives = @@ -1820,12 +1788,18 @@ static void getgeometry(int ctlr) log_index = log_index + 1; } /* end of if logical drive configured */ } /* end of for log_unit */ + + /* Free all the buffers and return */ +err_4: kfree(sense_config_buf); - kfree(id_ldrive); +err_3: kfree(id_lstatus_buf); +err_2: kfree(id_ctlr_buf); +err_1: + kfree(id_ldrive); +err_0: return; - } static void __exit cpqarray_exit(void) -- cgit v1.2.3 From a6b3a93e15b2925a151e9ae13dcb93ad7b3e48aa Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 11 Aug 2007 22:34:31 +0200 Subject: sysace: HDIO_GETGEO has it's own method for ages The way this driver tries to implement HDIO_GETGEO it'll never be called. Then again on ppc it probably will never be called anyway because it's utterly pointless. Signed-off-by: Christoph Hellwig Cc: Grant Likely Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/xsysace.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index cb27e8863d7c..3ede0b63da13 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -902,26 +902,17 @@ static int ace_release(struct inode *inode, struct file *filp) return 0; } -static int ace_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo) { - struct ace_device *ace = inode->i_bdev->bd_disk->private_data; - struct hd_geometry __user *geo = (struct hd_geometry __user *)arg; - struct hd_geometry g; - dev_dbg(ace->dev, "ace_ioctl()\n"); - - switch (cmd) { - case HDIO_GETGEO: - g.heads = ace->cf_id.heads; - g.sectors = ace->cf_id.sectors; - g.cylinders = ace->cf_id.cyls; - g.start = 0; - return copy_to_user(geo, &g, sizeof(g)) ? -EFAULT : 0; + struct ace_device *ace = bdev->bd_disk->private_data; - default: - return -ENOTTY; - } - return -ENOTTY; + dev_dbg(ace->dev, "ace_getgeo()\n"); + + geo->heads = ace->cf_id.heads; + geo->sectors = ace->cf_id.sectors; + geo->cylinders = ace->cf_id.cyls; + + return 0; } static struct block_device_operations ace_fops = { @@ -930,7 +921,7 @@ static struct block_device_operations ace_fops = { .release = ace_release, .media_changed = ace_media_changed, .revalidate_disk = ace_revalidate_disk, - .ioctl = ace_ioctl, + .getgeo = ace_getgeo, }; /* -------------------------------------------------------------------- -- cgit v1.2.3 From 04a3f959f691fd3eea42be37bc7a8cf32c1bd899 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 10 Aug 2007 13:00:45 -0700 Subject: stifb: detect cards in double buffer mode more reliably Visualize-EG, Graffiti and A4450A graphics cards on PARISC can be configured in double-buffer and standard mode, but the stifb driver supports standard mode only. This patch detects double-buffered cards more reliable. It is a real bugfix for a very nasty problem for all parisc users which have wrongly configured their graphic card. The problem: The stifb graphics driver will not detect that the card is wrongly configured and then nevertheless just enables the graphics mode, which it shouldn't. In the end, the user will see no further updates / boot messages on the screen. We had documented this problem already on our FAQ (http://parisc-linux.org/faq/index.html#viseg "Why do I get corrupted graphics with my Vis-EG/Graffiti/A4450A card?") but people still run into this problem. So having this fix in as early as possible can help us. Signed-off-by: Helge Deller Signed-off-by: Antonino Daplas Cc: Cc: Kyle McMartin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/stifb.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index c97709ecbad0..e7c8db2eb49b 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1100,13 +1100,18 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) /* only supported cards are allowed */ switch (fb->id) { case CRT_ID_VISUALIZE_EG: - /* look for a double buffering device like e.g. the - "INTERNAL_EG_DX1024" in the RDI precisionbook laptop - which won't work. The same device in non-double - buffering mode returns "INTERNAL_EG_X1024". */ - if (strstr(sti->outptr.dev_name, "EG_DX")) { - printk(KERN_WARNING - "stifb: ignoring '%s'. Disable double buffering in IPL menu.\n", + /* Visualize cards can run either in "double buffer" or + "standard" mode. Depending on the mode, the card reports + a different device name, e.g. "INTERNAL_EG_DX1024" in double + buffer mode and "INTERNAL_EG_X1024" in standard mode. + Since this driver only supports standard mode, we check + if the device name contains the string "DX" and tell the + user how to reconfigure the card. */ + if (strstr(sti->outptr.dev_name, "DX")) { + printk(KERN_WARNING "WARNING: stifb framebuffer driver does not " + "support '%s' in double-buffer mode.\n" + KERN_WARNING "WARNING: Please disable the double-buffer mode " + "in IPL menu (the PARISC-BIOS).\n", sti->outptr.dev_name); goto out_err0; } -- cgit v1.2.3 From 4769a9a53b39f3b6a7e4d0b3c5e6b9598560818d Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 10 Aug 2007 13:00:46 -0700 Subject: fbcon: Kill compile warning Fix compile warning ('map_override unused') if fbcon is compiled as a module and CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=n. [akpm@linux-foundation.org: cleanup] Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index decfdc8eb9cc..e58c87b3e3a0 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -127,8 +127,20 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; static int fbcon_has_exited; static int primary_device = -1; + +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY static int map_override; +static inline void fbcon_map_override(void) +{ + map_override = 1; +} +#else +static inline void fbcon_map_override(void) +{ +} +#endif /* CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY */ + /* font data */ static char fontname[40]; @@ -506,7 +518,7 @@ static int __init fb_console_setup(char *this_opt) (options[j++]-'0') % FB_MAX; } - map_override = 1; + fbcon_map_override(); } return 1; -- cgit v1.2.3 From 9cd1c67434544b1d9a4fb4a4cdec15608167a233 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 10 Aug 2007 13:00:47 -0700 Subject: pvr2fb: Fix oops when pseudo_palette is written Reported by: Adrian McMenamin This driver will oops when the pseudo_palette[] is written as u32 but not when written as u16. When written as u32, it corrupts the adjacent 'mmio_base' field of struct pvr2fb_par. Fix by using framebuffer_alloc()/release() to allocate struct fb_info and struct pvr2fb_par, and create the pseudo_palette[] as part of struct pvr2fb_par. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/pvr2fb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index f9300266044d..a72921b552dc 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -143,6 +143,7 @@ static struct pvr2fb_par { unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */ unsigned long mmio_base; /* MMIO base */ + u32 palette[16]; } *currentpar; static struct fb_info *fb_info; @@ -790,7 +791,7 @@ static int __devinit pvr2fb_common_init(void) fb_info->fbops = &pvr2fb_ops; fb_info->fix = pvr2_fix; fb_info->par = currentpar; - fb_info->pseudo_palette = (void *)(fb_info->par + 1); + fb_info->pseudo_palette = currentpar->palette; fb_info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; if (video_output == VO_VGA) @@ -1082,14 +1083,15 @@ static int __init pvr2fb_init(void) #endif size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32); - fb_info = kzalloc(size, GFP_KERNEL); + fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL); + if (!fb_info) { printk(KERN_ERR "Failed to allocate memory for fb_info\n"); return -ENOMEM; } - currentpar = (struct pvr2fb_par *)(fb_info + 1); + currentpar = fb_info->par; for (i = 0; i < ARRAY_SIZE(board_driver); i++) { struct pvr2_board *pvr_board = board_driver + i; @@ -1102,7 +1104,7 @@ static int __init pvr2fb_init(void) if (ret != 0) { printk(KERN_ERR "pvr2fb: Failed init of %s device\n", pvr_board->name); - kfree(fb_info); + framebuffer_release(fb_info); break; } } @@ -1126,7 +1128,7 @@ static void __exit pvr2fb_exit(void) #endif unregister_framebuffer(fb_info); - kfree(fb_info); + framebuffer_release(fb_info); } module_init(pvr2fb_init); -- cgit v1.2.3 From 306c869c237a66fe85580f60558f105e3305d465 Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Fri, 10 Aug 2007 13:00:48 -0700 Subject: pvr2fb: Consolidated cleanup of pvr2fb.c - better handling of the pvr2 registers based on more up to date information. Testing shows that it seems to work pretty well at 16bpp, 24bpp and 32bpp - including proper rendering of the boot logo at all levels (previously this was a bit broken even at 16bpp) and giving white against black text. Really detailed testing (eg with X11) requires support for the maple bus - which isn't (currently - next project assuming this is okay) available, but I have no reason to think this is broken. Signed-off by: Adrian McMenamin Acked-by: Paul Mundt Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/pvr2fb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index a72921b552dc..7d6c29800d14 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -94,6 +94,7 @@ #define DISP_DIWCONF (DISP_BASE + 0xe8) #define DISP_DIWHSTRT (DISP_BASE + 0xec) #define DISP_DIWVSTRT (DISP_BASE + 0xf0) +#define DISP_PIXDEPTH (DISP_BASE + 0x108) /* Pixel clocks, one for TV output, doubled for VGA output */ #define TV_CLK 74239 @@ -600,6 +601,7 @@ static void pvr2_init_display(struct fb_info *info) /* bits per pixel */ fb_writel(fb_readl(DISP_DIWMODE) | (--bytesperpixel << 2), DISP_DIWMODE); + fb_writel(bytesperpixel << 2, DISP_PIXDEPTH); /* video enable, color sync, interlace, * hsync and vsync polarity (currently unused) */ @@ -808,6 +810,8 @@ static int __devinit pvr2fb_common_init(void) if (register_framebuffer(fb_info) < 0) goto out_err; + /*Must write PIXDEPTH to register before anything is displayed - so force init */ + pvr2_init_display(fb_info); modememused = get_line_length(fb_info->var.xres_virtual, fb_info->var.bits_per_pixel); -- cgit v1.2.3 From e798bd95b61918e653f3d28f9176237236f2d103 Mon Sep 17 00:00:00 2001 From: "Paul A. Clarke" Date: Fri, 10 Aug 2007 13:00:49 -0700 Subject: matroxfb: rectify jitter (G450/G550) This builds upon my previous attempts to resolve some jitter problems seen with the Matrox G450 and G550 -based cards, including odd disparities observed between x86 and Power -based machines in a somewhat less hackish way (removing the hacked ifdefs). Apparently, preference should be given to use the DVI PLL when frequencies permit, the Standard PLL otherwise. The max pixel clock for the panellink interface is extracted from the PInS information on the card and used as a limit to determine which PLL to use. Signed-off-by: Paul A. Clarke Acked-by: Petr Vandrovec Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/matrox/g450_pll.c | 23 +++++++++++++---------- drivers/video/matrox/matroxfb_DAC1064.h | 15 +++++++++++++++ drivers/video/matrox/matroxfb_base.h | 1 + drivers/video/matrox/matroxfb_misc.c | 1 + 4 files changed, 30 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c index 7c76e079ca7d..d42346e7fdda 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/matrox/g450_pll.c @@ -331,16 +331,19 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, tmp |= M1064_XPIXCLKCTRL_PLL_UP; } matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); -#ifdef __powerpc__ - /* This is necessary to avoid jitter on PowerPC - * (OpenFirmware) systems, but apparently - * introduces jitter, at least on a x86-64 - * using DVI. - * A simple workaround is disable for non-PPC. - */ - matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); -#endif /* __powerpc__ */ - matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); + /* DVI PLL preferred for frequencies up to + panel link max, standard PLL otherwise */ + if (fout >= MINFO->max_pixel_clock_panellink) + tmp = 0; + else tmp = + M1064_XDVICLKCTRL_DVIDATAPATHSEL | + M1064_XDVICLKCTRL_C1DVICLKSEL | + M1064_XDVICLKCTRL_C1DVICLKEN | + M1064_XDVICLKCTRL_DVILOOPCTL | + M1064_XDVICLKCTRL_P1LOOPBWDTCTL; + matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); + matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, + xpwrctrl); matroxfb_DAC_unlock_irqrestore(flags); } diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h index df39c3193735..7a98ce8043d7 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/matrox/matroxfb_DAC1064.h @@ -33,6 +33,21 @@ void DAC1064_global_restore(WPMINFO2); #define M1064_XCURCTRL_3COLOR 0x01 /* transparent, 0, 1, 2 */ #define M1064_XCURCTRL_XGA 0x02 /* 0, 1, transparent, complement */ #define M1064_XCURCTRL_XWIN 0x03 /* transparent, transparent, 0, 1 */ + /* drive DVI by standard(0)/DVI(1) PLL */ + /* if set(1), C?DVICLKEN and C?DVICLKSEL must be set(1) */ +#define M1064_XDVICLKCTRL_DVIDATAPATHSEL 0x01 + /* drive CRTC1 by standard(0)/DVI(1) PLL */ +#define M1064_XDVICLKCTRL_C1DVICLKSEL 0x02 + /* drive CRTC2 by standard(0)/DVI(1) PLL */ +#define M1064_XDVICLKCTRL_C2DVICLKSEL 0x04 + /* pixel clock allowed to(0)/blocked from(1) driving CRTC1 */ +#define M1064_XDVICLKCTRL_C1DVICLKEN 0x08 + /* DVI PLL loop filter bandwidth selection bits */ +#define M1064_XDVICLKCTRL_DVILOOPCTL 0x30 + /* CRTC2 pixel clock allowed to(0)/blocked from(1) driving CRTC2 */ +#define M1064_XDVICLKCTRL_C2DVICLKEN 0x40 + /* P1PLL loop filter bandwith selection */ +#define M1064_XDVICLKCTRL_P1LOOPBWDTCTL 0x80 #define M1064_XCURCOL0RED 0x08 #define M1064_XCURCOL0GREEN 0x09 #define M1064_XCURCOL0BLUE 0x0A diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index d59577c8de86..f3107ad7e545 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -424,6 +424,7 @@ struct matrox_fb_info { } mmio; unsigned int max_pixel_clock; + unsigned int max_pixel_clock_panellink; struct matrox_switch* hw_switch; diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index 5948e54b9ef9..ab7fb50bc1de 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c @@ -658,6 +658,7 @@ static int parse_pins5(WPMINFO const struct matrox_bios* bd) { MINFO->values.reg.mctlwtst_core = (MINFO->values.reg.mctlwtst & ~7) | wtst_xlat[MINFO->values.reg.mctlwtst & 7]; } + MINFO->max_pixel_clock_panellink = bd->pins[47] * 4000; return 0; } -- cgit v1.2.3 From 925796e0ed6fe529770ba71454c58c8d4d8a5ac4 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Fri, 10 Aug 2007 13:00:58 -0700 Subject: drivers/char/pcmcia/cm40x0_cs.c: fix release function call cm4000_cs.c and cm4040_cs.c call the internal release function with an argument of wrong type. this fixes bug #8485 Signed-off-by: Daniel Ritz Cc: Bill McConnaughey Cc: Natalie Protasevich Cc: Harald Welte Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/pcmcia/cm4000_cs.c | 5 ++--- drivers/char/pcmcia/cm4040_cs.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index fee58e03dbe2..4177f6db83e9 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1629,7 +1629,7 @@ static int cmm_open(struct inode *inode, struct file *filp) { struct cm4000_dev *dev; struct pcmcia_device *link; - int rc, minor = iminor(inode); + int minor = iminor(inode); if (minor >= CM4000_MAX_DEV) return -ENODEV; @@ -1668,7 +1668,6 @@ static int cmm_open(struct inode *inode, struct file *filp) start_monitor(dev); link->open = 1; /* only one open per device */ - rc = 0; DEBUGP(2, dev, "<- cmm_open\n"); return nonseekable_open(inode, filp); @@ -1824,7 +1823,7 @@ static int cm4000_resume(struct pcmcia_device *link) static void cm4000_release(struct pcmcia_device *link) { - cmm_cm4000_release(link->priv); /* delay release until device closed */ + cmm_cm4000_release(link); /* delay release until device closed */ pcmcia_disable_device(link); } diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index af88181a17f4..b24a3e7bbb9f 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -599,7 +599,7 @@ cs_release: static void reader_release(struct pcmcia_device *link) { - cm4040_reader_release(link->priv); + cm4040_reader_release(link); pcmcia_disable_device(link); } -- cgit v1.2.3 From e24a4d1ee337e3a67a502f3f19cdec3ffc45ad05 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 10 Aug 2007 13:01:01 -0700 Subject: spi_mpc83xx: in "QE mode", use sysclk/2 For MPC8349E input to the SPI Baud Rate Generator is SYSCLK, but it's SYSCLK/2 for MPC8323E (SPI in QE). Fix this, and remove confusion by renaming the mpc83xx_spi->sysclk member as mpc83xx_spi->spibrg. Signed-off-by: Anton Vorontsov Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi_mpc83xx.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index 0c16a2b39b41..fe69e94043e1 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c @@ -86,7 +86,7 @@ struct mpc83xx_spi { unsigned nsecs; /* (clock cycle time)/2 */ - u32 sysclk; + u32 spibrg; /* SPIBRG input clock */ u32 rx_shift; /* RX data reg shift when in qe mode */ u32 tx_shift; /* TX data reg shift when in qe mode */ @@ -169,17 +169,18 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) regval |= SPMODE_LEN(len); - if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64); + if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) { + u8 pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64); if (pm > 0x0f) { - printk(KERN_WARNING "MPC83xx SPI: SPICLK can't be less then a SYSCLK/1024!\n" - "Requested SPICLK is %d Hz. Will use %d Hz instead.\n", - spi->max_speed_hz, mpc83xx_spi->sysclk / 1024); + dev_err(&spi->dev, "Requested speed is too " + "low: %d Hz. Will use %d Hz instead.\n", + spi->max_speed_hz, + mpc83xx_spi->spibrg / 1024); pm = 0x0f; } regval |= SPMODE_PM(pm) | SPMODE_DIV16; } else { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4); + u8 pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4); regval |= SPMODE_PM(pm); } @@ -429,13 +430,17 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect; mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer; mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs; - mpc83xx_spi->sysclk = pdata->sysclk; mpc83xx_spi->activate_cs = pdata->activate_cs; mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; mpc83xx_spi->qe_mode = pdata->qe_mode; mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; + if (mpc83xx_spi->qe_mode) + mpc83xx_spi->spibrg = pdata->sysclk / 2; + else + mpc83xx_spi->spibrg = pdata->sysclk; + mpc83xx_spi->rx_shift = 0; mpc83xx_spi->tx_shift = 0; if (mpc83xx_spi->qe_mode) { -- cgit v1.2.3 From a44648b057f5331fe6c0e863dc693ed335490e7a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 10 Aug 2007 13:01:02 -0700 Subject: spi_mpc83xx: fix prescale modulus calculation Long ago I've noticed (but didn't pay much attention) that spi_mpc83xx using PM calculations that differs from what specs describe. I.e. u8 pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4); While specs says: "The SPI baud rate generator clock source (either system clock or system clock divided by 16, depending on DIV16 bit) is divided by 4 * ([PM] + 1), a range from 4 to 64.". Thus " - 1" is missing in the spi_mpc83xx's formula. Why nobody noticed that bug? Probably because sysclk usually less then user expects, e.g. you expect 200 MHz, but real clock is 198 MHz, and integer rounding helps when this formula is used. Suppose it's SPI in QE, SYSCLK at 198 MHz, thus SPIBRG at 99MHz, 25 MHz requested. PM = (99MHz / ( 25 MHz * 4 )), PM == 0, output SPICLK will be 24.75 MHz At lower frequencies this bug is more noticeable, though. And this bug shows itself in all its beauty if SYSCLK is equal or a bit more than you expect (200 MHz SYSCLK, 100 MHz SPIBRG): PM = (100MHz / ( 25 MHz * 4 )), PM == 1, output SPICLK will be 12.625 MHz! Signed-off-by: Anton Vorontsov Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi_mpc83xx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index fe69e94043e1..2adf856e44c2 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c @@ -148,6 +148,8 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) if (value == BITBANG_CS_ACTIVE) { u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); u32 len = spi->bits_per_word; + u8 pm; + if (len == 32) len = 0; else @@ -170,7 +172,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) regval |= SPMODE_LEN(len); if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) { - u8 pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64); + pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1; if (pm > 0x0f) { dev_err(&spi->dev, "Requested speed is too " "low: %d Hz. Will use %d Hz instead.\n", @@ -180,7 +182,9 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) } regval |= SPMODE_PM(pm) | SPMODE_DIV16; } else { - u8 pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4); + pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4); + if (pm) + pm--; regval |= SPMODE_PM(pm); } -- cgit v1.2.3 From 42fd552e8647316757ded0176466c41d17934dcf Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 10 Aug 2007 13:01:05 -0700 Subject: fix serial buffer memory leak Patch c5c34d4862e18ef07c1276d233507f540fb5a532 (tty: flush flip buffer on ldisc input queue flush) introduces a race condition which can lead to memory leaks. The problem can be triggered when tcflush() is called when data are being pushed to the line discipline driver by flush_to_ldisc(). flush_to_ldisc() releases tty->buf.lock when calling the line discipline receive_buf function. At that poing tty_buffer_flush() kicks in and sets both tty->buf.head and tty->buf.tail to NULL. When flush_to_ldisc() finishes, it restores tty->buf.head but doesn't touch tty->buf.tail. This corrups the buffer queue, and the next call to tty_buffer_request_room() will allocate a new buffer and overwrite tty->buf.head. The previous buffer is then lost forever without being released. (Thanks to Laurent for the above text, for finding, disgnosing and reporting the bug) - Use tty->flags bits for the flush status. - Wait for the flag to clear again before returning - Fix the doc error noted - Fix flush of empty queue leaving stale flushpending [akpm@linux-foundation.org: cleanup] Signed-off-by: Alan Cox Acked-by: Paul Fulghum Cc: Laurent Pinchart Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tty_io.c | 56 +++++++++++++++++++++++++++++++++++++++++++++------ include/linux/tty.h | 2 ++ 2 files changed, 52 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index de37ebc3a4cf..51ea93cab6c4 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -369,25 +369,54 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) } /** - * tty_buffer_flush - flush full tty buffers + * __tty_buffer_flush - flush full tty buffers * @tty: tty to flush * - * flush all the buffers containing receive data + * flush all the buffers containing receive data. Caller must + * hold the buffer lock and must have ensured no parallel flush to + * ldisc is running. * - * Locking: none + * Locking: Caller must hold tty->buf.lock */ -static void tty_buffer_flush(struct tty_struct *tty) +static void __tty_buffer_flush(struct tty_struct *tty) { struct tty_buffer *thead; - unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); while((thead = tty->buf.head) != NULL) { tty->buf.head = thead->next; tty_buffer_free(tty, thead); } tty->buf.tail = NULL; +} + +/** + * tty_buffer_flush - flush full tty buffers + * @tty: tty to flush + * + * flush all the buffers containing receive data. If the buffer is + * being processed by flush_to_ldisc then we defer the processing + * to that function + * + * Locking: none + */ + +static void tty_buffer_flush(struct tty_struct *tty) +{ + unsigned long flags; + spin_lock_irqsave(&tty->buf.lock, flags); + + /* If the data is being pushed to the tty layer then we can't + process it here. Instead set a flag and the flush_to_ldisc + path will process the flush request before it exits */ + if (test_bit(TTY_FLUSHING, &tty->flags)) { + set_bit(TTY_FLUSHPENDING, &tty->flags); + spin_unlock_irqrestore(&tty->buf.lock, flags); + wait_event(tty->read_wait, + test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); + return; + } else + __tty_buffer_flush(tty); spin_unlock_irqrestore(&tty->buf.lock, flags); } @@ -3594,6 +3623,7 @@ static void flush_to_ldisc(struct work_struct *work) return; spin_lock_irqsave(&tty->buf.lock, flags); + set_bit(TTY_FLUSHING, &tty->flags); /* So we know a flush is running */ head = tty->buf.head; if (head != NULL) { tty->buf.head = NULL; @@ -3607,6 +3637,11 @@ static void flush_to_ldisc(struct work_struct *work) tty_buffer_free(tty, tbuf); continue; } + /* Ldisc or user is trying to flush the buffers + we are feeding to the ldisc, stop feeding the + line discipline as we want to empty the queue */ + if (test_bit(TTY_FLUSHPENDING, &tty->flags)) + break; if (!tty->receive_room) { schedule_delayed_work(&tty->buf.work, 1); break; @@ -3620,8 +3655,17 @@ static void flush_to_ldisc(struct work_struct *work) disc->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } + /* Restore the queue head */ tty->buf.head = head; } + /* We may have a deferred request to flush the input buffer, + if so pull the chain under the lock and empty the queue */ + if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { + __tty_buffer_flush(tty); + clear_bit(TTY_FLUSHPENDING, &tty->flags); + wake_up(&tty->read_wait); + } + clear_bit(TTY_FLUSHING, &tty->flags); spin_unlock_irqrestore(&tty->buf.lock, flags); tty_ldisc_deref(disc); diff --git a/include/linux/tty.h b/include/linux/tty.h index 691a1748d9d2..6570719eafdf 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -274,6 +274,8 @@ struct tty_struct { #define TTY_PTY_LOCK 16 /* pty private */ #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_HUPPED 18 /* Post driver->hangup() */ +#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */ +#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) -- cgit v1.2.3 From 0c1eafdb063a3701eff24d21eb245e3b1d4ac7df Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 10 Aug 2007 13:01:06 -0700 Subject: mtdchar build fix sh: drivers/mtd/mtdchar.c: In function `mtd_mmap': drivers/mtd/mtdchar.c:817: error: dereferencing pointer to incomplete type drivers/mtd/mtdchar.c:817: error: `VM_SHARED' undeclared (first use in this function) drivers/mtd/mtdchar.c:817: error: (Each undeclared identifier is reported only once Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/mtdchar.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8c86b802f212..d091b2430b48 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 96ddbf504a05502800e7cbeb4d08abbcc206c51c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 10 Aug 2007 13:01:09 -0700 Subject: spidev warning fix Git rid of "warning: passing arg 2 of `access_ok' makes pointer from integer without a cast" reported on SH ... most architectures use macros in that test, SH uses inlined functions. Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spidev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 630f781aeb19..c55459c592b8 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -183,7 +183,9 @@ static int spidev_message(struct spidev_data *spidev, if (u_tmp->rx_buf) { k_tmp->rx_buf = buf; - if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len)) + if (!access_ok(VERIFY_WRITE, (u8 __user *) + (ptrdiff_t) u_tmp->rx_buf, + u_tmp->len)) goto done; } if (u_tmp->tx_buf) { -- cgit v1.2.3 From cd5bfea278987ebfe60f3ff92a01696b17c4f978 Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Fri, 10 Aug 2007 13:01:10 -0700 Subject: fix compilation with gcc 4.2 gcc-4.2 is a lot more picky about its symbol handling. EXPORT_SYMBOL no longer works on symbols that are undefined or defined with static scope. For example, with CONFIG_PROFILE off, I see: kernel/profile.c:206: error: __ksymtab_profile_event_unregister causes a section type conflict kernel/profile.c:205: error: __ksymtab_profile_event_register causes a section type conflict This patch moves the EXPORTs inside the #ifdef CONFIG_PROFILE, so we only try to export symbols that are defined. Also, in kernel/kprobes.c there's an EXPORT_SYMBOL_GPL() for jprobes_return, which if CONFIG_JPROBES is undefined is a static inline and gives the same error. And in drivers/acpi/resources/rsxface.c, there's an ACPI_EXPORT_SYMBOPL() for a static symbol. If it's static, it's not accessible from outside the compilation unit, so should bot be exported. These three changes allow building a zx1_defconfig kernel with gcc 4.2 on IA64. [akpm@linux-foundation.org: export jpobe_return properly] Signed-off-by: Peter Chubb Cc: Prasanna S Panchamukhi Cc: Ananth N Mavinakayanahalli Cc: Anil S Keshavamurthy Cc: "Luck, Tony" Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/resources/rsxface.c | 2 -- kernel/kprobes.c | 5 +++++ kernel/profile.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index f63813a358c5..4c3fd4cdaf73 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -474,8 +474,6 @@ acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) return (AE_CTRL_TERMINATE); } -ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource) - /******************************************************************************* * * FUNCTION: acpi_walk_resources diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3e9f513a728d..4b8a4493c541 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1063,6 +1063,11 @@ EXPORT_SYMBOL_GPL(register_kprobe); EXPORT_SYMBOL_GPL(unregister_kprobe); EXPORT_SYMBOL_GPL(register_jprobe); EXPORT_SYMBOL_GPL(unregister_jprobe); +#ifdef CONFIG_KPROBES EXPORT_SYMBOL_GPL(jprobe_return); +#endif + +#ifdef CONFIG_KPROBES EXPORT_SYMBOL_GPL(register_kretprobe); EXPORT_SYMBOL_GPL(unregister_kretprobe); +#endif diff --git a/kernel/profile.c b/kernel/profile.c index 5b20fe977bed..cb1e37d2dac3 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -199,11 +199,11 @@ EXPORT_SYMBOL_GPL(register_timer_hook); EXPORT_SYMBOL_GPL(unregister_timer_hook); EXPORT_SYMBOL_GPL(task_handoff_register); EXPORT_SYMBOL_GPL(task_handoff_unregister); +EXPORT_SYMBOL_GPL(profile_event_register); +EXPORT_SYMBOL_GPL(profile_event_unregister); #endif /* CONFIG_PROFILING */ -EXPORT_SYMBOL_GPL(profile_event_register); -EXPORT_SYMBOL_GPL(profile_event_unregister); #ifdef CONFIG_SMP /* -- cgit v1.2.3 From b1a47190a6000d0e75ee4ffa75f3f6b16dd60a0b Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Aug 2007 13:01:11 -0700 Subject: lguest files should explicitly include asm/paravirt.h Files using bits from paravirt.h should explicitly include it rather than relying on it being pulled in by something else. Signed-off-by: Jes Sorensen Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hvc_lguest.c | 1 + drivers/lguest/lguest_bus.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c index feeccbaec438..3d6bd0baa56d 100644 --- a/drivers/char/hvc_lguest.c +++ b/drivers/char/hvc_lguest.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "hvc_console.h" /*D:340 This is our single console input buffer, with associated "struct diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c index 55a7940ca732..9e7752cc8002 100644 --- a/drivers/lguest/lguest_bus.c +++ b/drivers/lguest/lguest_bus.c @@ -5,6 +5,7 @@ #include #include #include +#include static ssize_t type_show(struct device *_dev, struct device_attribute *attr, char *buf) -- cgit v1.2.3 From ab144f5ec64c42218a555ec1dbde6b60cf2982d6 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 10 Aug 2007 22:31:03 +0200 Subject: i386: Make patching more robust, fix paravirt issue Commit 19d36ccdc34f5ed444f8a6af0cbfdb6790eb1177 "x86: Fix alternatives and kprobes to remap write-protected kernel text" uses code which is being patched for patching. In particular, paravirt_ops does patching in two stages: first it calls paravirt_ops.patch, then it fills any remaining instructions with nop_out(). nop_out calls text_poke() which calls lookup_address() which calls pgd_val() (aka paravirt_ops.pgd_val): that call site is one of the places we patch. If we always do patching as one single call to text_poke(), we only need make sure we're not patching the memcpy in text_poke itself. This means the prototype to paravirt_ops.patch needs to change, to marshal the new code into a buffer rather than patching in place as it does now. It also means all patching goes through text_poke(), which is known to be safe (apply_alternatives is also changed to make a single patch). AK: fix compilation on x86-64 (bad rusty!) AK: fix boot on x86-64 (sigh) AK: merged with other patches Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- arch/i386/kernel/alternative.c | 33 +++++++++++++++++---------- arch/i386/kernel/paravirt.c | 52 +++++++++++++++++++++--------------------- arch/i386/kernel/vmi.c | 35 ++++++++++++++++------------ arch/i386/xen/enlighten.c | 12 ++++++---- drivers/lguest/lguest.c | 9 ++++---- include/asm-i386/paravirt.h | 16 ++++++++----- 6 files changed, 90 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index c85598acb8fd..27a6b0c9a7cc 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -11,6 +11,8 @@ #include #include +#define MAX_PATCH_LEN (255-1) + #ifdef CONFIG_HOTPLUG_CPU static int smp_alt_once; @@ -148,7 +150,8 @@ static unsigned char** find_nop_table(void) #endif /* CONFIG_X86_64 */ -static void nop_out(void *insns, unsigned int len) +/* Use this to add nops to a buffer, then text_poke the whole buffer. */ +static void add_nops(void *insns, unsigned int len) { unsigned char **noptable = find_nop_table(); @@ -156,7 +159,7 @@ static void nop_out(void *insns, unsigned int len) unsigned int noplen = len; if (noplen > ASM_NOP_MAX) noplen = ASM_NOP_MAX; - text_poke(insns, noptable[noplen], noplen); + memcpy(insns, noptable[noplen], noplen); insns += noplen; len -= noplen; } @@ -174,15 +177,15 @@ extern u8 *__smp_locks[], *__smp_locks_end[]; void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { struct alt_instr *a; - u8 *instr; - int diff; + char insnbuf[MAX_PATCH_LEN]; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { + u8 *instr = a->instr; BUG_ON(a->replacementlen > a->instrlen); + BUG_ON(a->instrlen > sizeof(insnbuf)); if (!boot_cpu_has(a->cpuid)) continue; - instr = a->instr; #ifdef CONFIG_X86_64 /* vsyscall code is not mapped yet. resolve it manually. */ if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { @@ -191,9 +194,10 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) __FUNCTION__, a->instr, instr); } #endif - memcpy(instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - nop_out(instr + a->replacementlen, diff); + memcpy(insnbuf, a->replacement, a->replacementlen); + add_nops(insnbuf + a->replacementlen, + a->instrlen - a->replacementlen); + text_poke(instr, insnbuf, a->instrlen); } } @@ -215,16 +219,18 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { u8 **ptr; + char insn[1]; if (noreplace_smp) return; + add_nops(insn, 1); for (ptr = start; ptr < end; ptr++) { if (*ptr < text) continue; if (*ptr > text_end) continue; - nop_out(*ptr, 1); + text_poke(*ptr, insn, 1); }; } @@ -351,6 +357,7 @@ void apply_paravirt(struct paravirt_patch_site *start, struct paravirt_patch_site *end) { struct paravirt_patch_site *p; + char insnbuf[MAX_PATCH_LEN]; if (noreplace_paravirt) return; @@ -358,13 +365,15 @@ void apply_paravirt(struct paravirt_patch_site *start, for (p = start; p < end; p++) { unsigned int used; - used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, - p->len); + BUG_ON(p->len > MAX_PATCH_LEN); + used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf, + (unsigned long)p->instr, p->len); BUG_ON(used > p->len); /* Pad the rest with nops */ - nop_out(p->instr + used, p->len - used); + add_nops(insnbuf + used, p->len - used); + text_poke(p->instr, insnbuf, p->len); } } extern struct paravirt_patch_site __start_parainstructions[], diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index ea962c0667d5..739cfb207dd7 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -69,7 +69,8 @@ DEF_NATIVE(read_tsc, "rdtsc"); DEF_NATIVE(ud2a, "ud2a"); -static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned native_patch(u8 type, u16 clobbers, void *ibuf, + unsigned long addr, unsigned len) { const unsigned char *start, *end; unsigned ret; @@ -90,7 +91,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) #undef SITE patch_site: - ret = paravirt_patch_insns(insns, len, start, end); + ret = paravirt_patch_insns(ibuf, len, start, end); break; case PARAVIRT_PATCH(make_pgd): @@ -107,7 +108,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) break; default: - ret = paravirt_patch_default(type, clobbers, insns, len); + ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); break; } @@ -129,68 +130,67 @@ struct branch { u32 delta; } __attribute__((packed)); -unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, - void *site, u16 site_clobbers, +unsigned paravirt_patch_call(void *insnbuf, + const void *target, u16 tgt_clobbers, + unsigned long addr, u16 site_clobbers, unsigned len) { - unsigned char *call = site; - unsigned long delta = (unsigned long)target - (unsigned long)(call+5); - struct branch b; + struct branch *b = insnbuf; + unsigned long delta = (unsigned long)target - (addr+5); if (tgt_clobbers & ~site_clobbers) return len; /* target would clobber too much for this site */ if (len < 5) return len; /* call too long for patch site */ - b.opcode = 0xe8; /* call */ - b.delta = delta; - BUILD_BUG_ON(sizeof(b) != 5); - text_poke(call, (unsigned char *)&b, 5); + b->opcode = 0xe8; /* call */ + b->delta = delta; + BUILD_BUG_ON(sizeof(*b) != 5); return 5; } -unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) +unsigned paravirt_patch_jmp(const void *target, void *insnbuf, + unsigned long addr, unsigned len) { - unsigned char *jmp = site; - unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); - struct branch b; + struct branch *b = insnbuf; + unsigned long delta = (unsigned long)target - (addr+5); if (len < 5) return len; /* call too long for patch site */ - b.opcode = 0xe9; /* jmp */ - b.delta = delta; - text_poke(jmp, (unsigned char *)&b, 5); + b->opcode = 0xe9; /* jmp */ + b->delta = delta; return 5; } -unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len) +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) { void *opfunc = *((void **)¶virt_ops + type); unsigned ret; if (opfunc == NULL) /* If there's no function, patch it with a ud2a (BUG) */ - ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a); + ret = paravirt_patch_insns(insnbuf, len, start_ud2a, end_ud2a); else if (opfunc == paravirt_nop) /* If the operation is a nop, then nop the callsite */ ret = paravirt_patch_nop(); else if (type == PARAVIRT_PATCH(iret) || type == PARAVIRT_PATCH(irq_enable_sysexit)) /* If operation requires a jmp, then jmp */ - ret = paravirt_patch_jmp(opfunc, site, len); + ret = paravirt_patch_jmp(opfunc, insnbuf, addr, len); else /* Otherwise call the function; assume target could clobber any caller-save reg */ - ret = paravirt_patch_call(opfunc, CLBR_ANY, - site, clobbers, len); + ret = paravirt_patch_call(insnbuf, opfunc, CLBR_ANY, + addr, clobbers, len); return ret; } -unsigned paravirt_patch_insns(void *site, unsigned len, +unsigned paravirt_patch_insns(void *insnbuf, unsigned len, const char *start, const char *end) { unsigned insn_len = end - start; @@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *site, unsigned len, if (insn_len > len || start == NULL) insn_len = len; else - memcpy(site, start, insn_len); + memcpy(insnbuf, start, insn_len); return insn_len; } diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 72042bb7ec94..18673e0f193b 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -87,12 +87,14 @@ struct vmi_timer_ops vmi_timer_ops; #define IRQ_PATCH_INT_MASK 0 #define IRQ_PATCH_DISABLE 5 -static inline void patch_offset(unsigned char *eip, unsigned char *dest) +static inline void patch_offset(void *insnbuf, + unsigned long eip, unsigned long dest) { - *(unsigned long *)(eip+1) = dest-eip-5; + *(unsigned long *)(insnbuf+1) = dest-eip-5; } -static unsigned patch_internal(int call, unsigned len, void *insns) +static unsigned patch_internal(int call, unsigned len, void *insnbuf, + unsigned long eip) { u64 reloc; struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; @@ -100,14 +102,14 @@ static unsigned patch_internal(int call, unsigned len, void *insns) switch(rel->type) { case VMI_RELOCATION_CALL_REL: BUG_ON(len < 5); - *(char *)insns = MNEM_CALL; - patch_offset(insns, rel->eip); + *(char *)insnbuf = MNEM_CALL; + patch_offset(insnbuf, eip, (unsigned long)rel->eip); return 5; case VMI_RELOCATION_JUMP_REL: BUG_ON(len < 5); - *(char *)insns = MNEM_JMP; - patch_offset(insns, rel->eip); + *(char *)insnbuf = MNEM_JMP; + patch_offset(insnbuf, eip, (unsigned long)rel->eip); return 5; case VMI_RELOCATION_NOP: @@ -128,21 +130,26 @@ static unsigned patch_internal(int call, unsigned len, void *insns) * Apply patch if appropriate, return length of new instruction * sequence. The callee does nop padding for us. */ -static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, + unsigned long eip, unsigned len) { switch (type) { case PARAVIRT_PATCH(irq_disable): - return patch_internal(VMI_CALL_DisableInterrupts, len, insns); + return patch_internal(VMI_CALL_DisableInterrupts, len, + insns, eip); case PARAVIRT_PATCH(irq_enable): - return patch_internal(VMI_CALL_EnableInterrupts, len, insns); + return patch_internal(VMI_CALL_EnableInterrupts, len, + insns, eip); case PARAVIRT_PATCH(restore_fl): - return patch_internal(VMI_CALL_SetInterruptMask, len, insns); + return patch_internal(VMI_CALL_SetInterruptMask, len, + insns, eip); case PARAVIRT_PATCH(save_fl): - return patch_internal(VMI_CALL_GetInterruptMask, len, insns); + return patch_internal(VMI_CALL_GetInterruptMask, len, + insns, eip); case PARAVIRT_PATCH(iret): - return patch_internal(VMI_CALL_IRET, len, insns); + return patch_internal(VMI_CALL_IRET, len, insns, eip); case PARAVIRT_PATCH(irq_enable_sysexit): - return patch_internal(VMI_CALL_SYSEXIT, len, insns); + return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip); default: break; } diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c index 9a8c1181c001..f0c37511d8da 100644 --- a/arch/i386/xen/enlighten.c +++ b/arch/i386/xen/enlighten.c @@ -842,7 +842,8 @@ void __init xen_setup_vcpu_info_placement(void) } } -static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) { char *start, *end, *reloc; unsigned ret; @@ -869,7 +870,7 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) if (start == NULL || (end-start) > len) goto default_patch; - ret = paravirt_patch_insns(insns, len, start, end); + ret = paravirt_patch_insns(insnbuf, len, start, end); /* Note: because reloc is assigned from something that appears to be an array, gcc assumes it's non-null, @@ -877,8 +878,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) end. */ if (reloc > start && reloc < end) { int reloc_off = reloc - start; - long *relocp = (long *)(insns + reloc_off); - long delta = start - (char *)insns; + long *relocp = (long *)(insnbuf + reloc_off); + long delta = start - (char *)addr; *relocp += delta; } @@ -886,7 +887,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) default_patch: default: - ret = paravirt_patch_default(type, clobbers, insns, len); + ret = paravirt_patch_default(type, clobbers, insnbuf, + addr, len); break; } diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c index 524beea7fb19..6e135ac0834f 100644 --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c @@ -936,23 +936,24 @@ static const struct lguest_insns /* Now our patch routine is fairly simple (based on the native one in * paravirt.c). If we have a replacement, we copy it in and return how much of * the available space we used. */ -static unsigned lguest_patch(u8 type, u16 clobber, void *insns, unsigned len) +static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf, + unsigned long addr, unsigned len) { unsigned int insn_len; /* Don't do anything special if we don't have a replacement */ if (type >= ARRAY_SIZE(lguest_insns) || !lguest_insns[type].start) - return paravirt_patch_default(type, clobber, insns, len); + return paravirt_patch_default(type, clobber, ibuf, addr, len); insn_len = lguest_insns[type].end - lguest_insns[type].start; /* Similarly if we can't fit replacement (shouldn't happen, but let's * be thorough). */ if (len < insn_len) - return paravirt_patch_default(type, clobber, insns, len); + return paravirt_patch_default(type, clobber, ibuf, addr, len); /* Copy in our instructions. */ - memcpy(insns, lguest_insns[type].start, insn_len); + memcpy(ibuf, lguest_insns[type].start, insn_len); return insn_len; } diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 7df88be2dd9e..9fa3fa9e62d1 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -47,7 +47,8 @@ struct paravirt_ops * The patch function should return the number of bytes of code * generated, as we nop pad the rest in generic code. */ - unsigned (*patch)(u8 type, u16 clobber, void *firstinsn, unsigned len); + unsigned (*patch)(u8 type, u16 clobber, void *insnbuf, + unsigned long addr, unsigned len); /* Basic arch-specific setup */ void (*arch_setup)(void); @@ -253,13 +254,16 @@ extern struct paravirt_ops paravirt_ops; unsigned paravirt_patch_nop(void); unsigned paravirt_patch_ignore(unsigned len); -unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, - void *site, u16 site_clobbers, +unsigned paravirt_patch_call(void *insnbuf, + const void *target, u16 tgt_clobbers, + unsigned long addr, u16 site_clobbers, unsigned len); -unsigned paravirt_patch_jmp(void *target, void *site, unsigned len); -unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len); +unsigned paravirt_patch_jmp(const void *target, void *insnbuf, + unsigned long addr, unsigned len); +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len); -unsigned paravirt_patch_insns(void *site, unsigned len, +unsigned paravirt_patch_insns(void *insnbuf, unsigned len, const char *start, const char *end); int paravirt_disable_iospace(void); -- cgit v1.2.3 From 1e6a20c9c7848fefa64731ac3d1d88279c447371 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 7 Aug 2007 19:03:27 +0100 Subject: [ARM] 4544/1: arm: fix section mismatch in pxa fb Fix following section mismatch warning: WARNING: drivers/built-in.o(.text+0x73d0): Section mismatch: reference to .init.data: (between 'pxafb_setup' and 'pxafb_init') The warning are caused by __devinit pxafb_setup() that refers to a variable marked __initdata. In a hotplug scenario we would have a reference to the freed .init.data section. Fix this by declaring g_options __devinitdata. Signed-off-by: Sam Ravnborg Signed-off-by: Russell King --- drivers/video/pxafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 81e571d59b50..a280a52f8efe 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -66,7 +66,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); #ifdef CONFIG_FB_PXA_PARAMETERS #define PXAFB_OPTIONS_SIZE 256 -static char g_options[PXAFB_OPTIONS_SIZE] __initdata = ""; +static char g_options[PXAFB_OPTIONS_SIZE] __devinitdata = ""; #endif static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state) -- cgit v1.2.3 From 7aa763cb56b6efdfa5c1b83c336abf1be914afcd Mon Sep 17 00:00:00 2001 From: Stephan Berberig Date: Fri, 10 Aug 2007 13:10:31 -0700 Subject: ACPI: bay: send envp with uevent - fix There must not be a new-line character in the uevent. Otherwise, udev gets confused. Thanks to Kay Sievers for pointing it out. Signed-off-by: Stephan Berberig Cc: Kristen Carlson Accardi Signed-off-by: Andrew Morton Acked-by: Greg Kroah-Hartman Signed-off-by: Len Brown --- drivers/acpi/bay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index 56a5b3fffeb3..6daf6088ac88 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c @@ -337,7 +337,7 @@ static void bay_notify(acpi_handle handle, u32 event, void *data) char *envp[] = { event_string, NULL }; bay_dprintk(handle, "Bay event"); - sprintf(event_string, "BAY_EVENT=%d\n", event); + sprintf(event_string, "BAY_EVENT=%d", event); kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); } -- cgit v1.2.3 From 66b568218ab73be161dc109b913e6fa7dda44e16 Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Fri, 10 Aug 2007 13:10:32 -0700 Subject: ACPI: dock: Send key=value pair instead of plain value Send key=value pair along with the uevent instead of a plain value so that userspace (udev) can handle it like common environment variables. Signed-off-by: Holger Macht Acked-by: Kristen Carlson Accardi Cc: Stephan Berberig Signed-off-by: Andrew Morton Acked-by: Greg Kroah-Hartman Signed-off-by: Len Brown --- drivers/acpi/dock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 6192c8be66df..1dabdf4c07b3 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -336,13 +336,13 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) static void dock_event(struct dock_station *ds, u32 event, int num) { struct device *dev = &dock_device->dev; - char event_string[7]; + char event_string[13]; char *envp[] = { event_string, NULL }; if (num == UNDOCK_EVENT) - sprintf(event_string, "UNDOCK"); + sprintf(event_string, "EVENT=undock"); else - sprintf(event_string, "DOCK"); + sprintf(event_string, "EVENT=dock"); /* * Indicate that the status of the dock station has -- cgit v1.2.3 From 199e9e7d1106686a85ee9fdf6a824051aa82682e Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 10 Aug 2007 13:45:18 -0700 Subject: ACPI EC: remove potential deadlock from EC Signed-off-by: Alexey Starikovskiy Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index b28b56524f0b..2300d81bbc4e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -710,9 +710,7 @@ static int acpi_ec_add(struct acpi_device *device) /* Check if we found the boot EC */ if (boot_ec) { if (boot_ec->gpe == ec->gpe) { - mutex_lock(&boot_ec->lock); ec_remove_handlers(boot_ec); - mutex_unlock(&boot_ec->lock); mutex_destroy(&boot_ec->lock); kfree(boot_ec); first_ec = boot_ec = NULL; -- cgit v1.2.3 From e13d87473284131a7ead8121d5d29345101f68a4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 10 Aug 2007 13:45:18 -0700 Subject: ACPI: static Make the needlessly global "acpi_event_seqnum" static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index dfa5853b17f0..95637a4ff782 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -108,7 +108,7 @@ static const struct file_operations acpi_system_event_ops = { }; #ifdef CONFIG_NET -unsigned int acpi_event_seqnum; +static unsigned int acpi_event_seqnum; struct acpi_genl_event { acpi_device_class device_class; char bus_id[15]; -- cgit v1.2.3 From 72b33ef8bb1ac7f6c5a16d23304ab25ddc73d93d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 12 Aug 2007 00:12:17 -0400 Subject: ACPI: thermal: create "thermal.off=1" to disable ACPI thermal support "thermal.off=1" disables all ACPI thermal support at boot time. CONFIG_ACPI_THERMAL=n can do this at build time. "# rmmod thermal" can do this at run time, as long as thermal is built as a module. WARNING: On some systems, disabling ACPI thermal support will cause the system to run hotter and reduce the lifetime of the hardware. Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 3 +++ drivers/acpi/thermal.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a326487a3ab5..de3300c9056a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1820,6 +1820,9 @@ and is between 256 and 4096 characters. It is defined in the file thash_entries= [KNL,NET] Set number of hash buckets for TCP connection + thermal.off= [HW,ACPI] + 1: disable ACPI thermal control + time Show timing data prefixed to each printk message line [deprecated, see 'printk.time'] diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5a62de1b7f2a..61337d969d7f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -78,6 +78,10 @@ static int tzp; module_param(tzp, int, 0); MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); +static int off; +module_param(off, int, 0); +MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); + static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); static int acpi_thermal_resume(struct acpi_device *device); @@ -1285,7 +1289,10 @@ static int __init acpi_thermal_init(void) { int result = 0; - + if (off) { + printk(KERN_NOTICE "ACPI: thermal control disabled\n"); + return -ENODEV; + } acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); if (!acpi_thermal_dir) return -ENODEV; -- cgit v1.2.3 From 730ff34de766a6fddee25ac1c32bc49c1a2fd758 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 12 Aug 2007 00:12:26 -0400 Subject: ACPI: thermal: expose "thermal.tzp=" to set global polling frequency Thermal Zone Polling frequency (_TZP) is an optional ACPI object recommending the rate that the OS should poll the associated thermal zone. If _TZP is 0, no polling should be used. If _TZP is non-zero, then the platform recommends that the OS poll the thermal zone at the specified rate. The minimum period is 30 seconds. The maximum period is 5 minutes. (note _TZP and thermal.tzp units are in deci-seconds, so _TZP = 300 corresponds to 30 seconds) If _TZP is not present, ACPI 3.0b recommends that the thermal zone be polled at an "OS provided default frequency". However, common industry practice is: 1. The BIOS never specifies any _TZP 2. High volume OS's from this century never poll any thermal zones Ie. The OS depends on the platform's ability to provoke thermal events when necessary, and the "OS provided default frequency" is "never":-) There is a proposal that ACPI 4.0 be updated to reflect common industry practice -- ie. no _TZP, no polling. The Linux kernel already follows this practice -- thermal zones are not polled unless _TZP is present and non-zero. But thermal zone polling is useful as a workaround for systems which have ACPI thermal control, but have an issue preventing thermal events. Indeed, some Linux distributions still set a non-zero thermal polling frequency for this reason. But rather than ask the user to write a polling frequency into all the /proc/acpi/thermal_zone/*/polling_frequency files, here we simply document and expose the already existing module parameter to do the same at system level, to simplify debugging those broken platforms. Note that thermal.tzp is a module-load time parameter only. Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 5 +++++ drivers/acpi/thermal.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index de3300c9056a..ed7d7913af8c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1823,6 +1823,11 @@ and is between 256 and 4096 characters. It is defined in the file thermal.off= [HW,ACPI] 1: disable ACPI thermal control + thermal.tzp= [HW,ACPI] + Specify global default ACPI thermal zone polling rate + : poll all this frequency + 0: no polling (default) + time Show timing data prefixed to each printk message line [deprecated, see 'printk.time'] diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 61337d969d7f..b6b3bec84547 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -75,7 +75,7 @@ MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); MODULE_LICENSE("GPL"); static int tzp; -module_param(tzp, int, 0); +module_param(tzp, int, 0444); MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); static int off; -- cgit v1.2.3 From a70cdc5200b0eb9fc3ef64efb29baac9b2cf2431 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 12 Aug 2007 00:12:35 -0400 Subject: ACPI: thermal: create "thermal.psv=" to override passive trip points "thermal.psv=-1" disables passive trip points for all ACPI thermal zones. "thermal.psv=C", where 'C' is degrees Celsius, overrides all existing passive trip points for all ACPI thermal zones. thermal.psv is checked at module load time, and in response to trip-point change events. Note that if the system does not deliver thermal zone temperature change events near the new trip-point, then it will not be noticed. To force your custom trip point to be noticed, you may need to enable polling: eg. thermal.tzp=3000 invokes polling every 5 minutes. Note that once passive thermal throttling is invoked, it has its own internal Thermal Sampling Period (_TSP), that is unrelated to _TZP. WARNING: disabling or raising a thermal trip point may result in increased running temperature and shorter hardware lifetime on some systems. Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 4 ++++ drivers/acpi/thermal.c | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ed7d7913af8c..52e1c2d26a25 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1823,6 +1823,10 @@ and is between 256 and 4096 characters. It is defined in the file thermal.off= [HW,ACPI] 1: disable ACPI thermal control + thermal.psv= [HW,ACPI] + -1: disable all passive trip points + : override all passive trip points to this value + thermal.tzp= [HW,ACPI] Specify global default ACPI thermal zone polling rate : poll all this frequency diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index b6b3bec84547..74e25be8abc9 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -82,6 +82,10 @@ static int off; module_param(off, int, 0); MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); +static int psv; +module_param(psv, int, 0644); +MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n"); + static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); static int acpi_thermal_resume(struct acpi_device *device); @@ -343,9 +347,16 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) /* Passive: Processors (optional) */ - status = - acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, - &tz->trips.passive.temperature); + if (psv == -1) { + status = AE_SUPPORT; + } else if (psv > 0) { + tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv); + status = AE_OK; + } else { + status = acpi_evaluate_integer(tz->device->handle, + "_PSV", NULL, &tz->trips.passive.temperature); + } + if (ACPI_FAILURE(status)) { tz->trips.passive.flags.valid = 0; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); -- cgit v1.2.3 From f54871456162aff557d57bec51639b1288d4a84b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 12 Aug 2007 00:12:44 -0400 Subject: ACPI: thermal: create "thermal.nocrt" to disable critical actions thermal.nocrt=1 disables actions on _CRT and _HOT ACPI thermal zone trip-points. They will be marked as in /proc/acpi/thermal_zone/*/trip_points. There are two cases where this option is used: 1. Debugging a hot system crossing valid trip point. If your system fan is spinning at full speed, be sure that the vent is not clogged with dust. Many laptops have very fine thermal fins that are easily blocked. Check that the processor fan-sink is properly seated, has the proper thermal grease, and is really spinning. Check for fan related options in BIOS SETUP. Sometimes there is a performance vs quiet option. Defaults are generally the most conservative. If your fan is not spinning, yet /proc/acpi/fan/ has files in it, please file a Linux/ACPI bug. WARNING: you risk shortening the lifetime of your hardware if you use this parameter on a hot system. Note that this refers to all system components, including the disk drive. 2. Working around a cool system crossing critical trip point due to erroneous temperature reading. Try again with CONFIG_HWMON=n There is known potential for conflict between the the hwmon sub-system and the ACPI BIOS. If this fixes it, notify lm-sensors@lm-sensors.org and linux-acpi@vger.kernel.org Otherwise, file a Linux/ACPI bug, or notify just linux-acpi@vger.kernel.org. Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 4 ++++ drivers/acpi/thermal.c | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 52e1c2d26a25..4c7d2774d2a4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1820,6 +1820,10 @@ and is between 256 and 4096 characters. It is defined in the file thash_entries= [KNL,NET] Set number of hash buckets for TCP connection + thermal.nocrt= [HW,ACPI] + Set to disable actions on ACPI thermal zone + critical and hot trip points. + thermal.off= [HW,ACPI] 1: disable ACPI thermal control diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 74e25be8abc9..57d05ff44dd1 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -78,6 +78,10 @@ static int tzp; module_param(tzp, int, 0444); MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); +static int nocrt; +module_param(nocrt, int, 0); +MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n"); + static int off; module_param(off, int, 0); MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); @@ -442,7 +446,7 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz) static int acpi_thermal_critical(struct acpi_thermal *tz) { - if (!tz || !tz->trips.critical.flags.valid) + if (!tz || !tz->trips.critical.flags.valid || nocrt) return -EINVAL; if (tz->temperature >= tz->trips.critical.temperature) { @@ -464,7 +468,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) static int acpi_thermal_hot(struct acpi_thermal *tz) { - if (!tz || !tz->trips.hot.flags.valid) + if (!tz || !tz->trips.hot.flags.valid || nocrt) return -EINVAL; if (tz->temperature >= tz->trips.hot.temperature) { @@ -839,12 +843,14 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) goto end; if (tz->trips.critical.flags.valid) - seq_printf(seq, "critical (S5): %ld C\n", - KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); + seq_printf(seq, "critical (S5): %ld C%s", + KELVIN_TO_CELSIUS(tz->trips.critical.temperature), + nocrt ? " \n" : "\n"); if (tz->trips.hot.flags.valid) - seq_printf(seq, "hot (S4): %ld C\n", - KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); + seq_printf(seq, "hot (S4): %ld C%s", + KELVIN_TO_CELSIUS(tz->trips.hot.temperature), + nocrt ? " \n" : "\n"); if (tz->trips.passive.flags.valid) { seq_printf(seq, -- cgit v1.2.3 From f8707ec9643769957065405b5090e4aa64fd8214 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 12 Aug 2007 00:12:54 -0400 Subject: ACPI: thermal: create "thermal.act=" to disable or override active trip point thermal.act=-1 disables all active trip points in all ACPI thermal zones. thermal.act=C, where C > 0, overrides all lowest temperature active trip points in all thermal zones to C degrees Celsius. Raising this trip-point may allow you to keep your system silent up to a higher temperature. However, it will not allow you to raise the lowest temperature trip point above the next higher trip point (if there is one). Lowering this trip point may kick in the fan sooner. Note that overriding this trip-point will disable any BIOS attempts to implement hysteresis around the lowest temperature trip point. This may result in the fan starting and stopping frequently if temperature frequently crosses C. WARNING: raising trip points above the manufacturer's defaults may cause the system to run at higher temperature and shorten its life. Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 4 ++++ drivers/acpi/thermal.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4c7d2774d2a4..06db892b558a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1820,6 +1820,10 @@ and is between 256 and 4096 characters. It is defined in the file thash_entries= [KNL,NET] Set number of hash buckets for TCP connection + thermal.act= [HW,ACPI] + -1: disable all active trip points in all thermal zones + : override all lowest active trip points + thermal.nocrt= [HW,ACPI] Set to disable actions on ACPI thermal zone critical and hot trip points. diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 57d05ff44dd1..3521c37bbd33 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -74,6 +74,10 @@ MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); MODULE_LICENSE("GPL"); +static int act; +module_param(act, int, 0644); +MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n"); + static int tzp; module_param(tzp, int, 0444); MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); @@ -405,11 +409,33 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; - status = - acpi_evaluate_integer(tz->device->handle, name, NULL, - &tz->trips.active[i].temperature); - if (ACPI_FAILURE(status)) + if (act == -1) + break; /* disable all active trip points */ + + status = acpi_evaluate_integer(tz->device->handle, + name, NULL, &tz->trips.active[i].temperature); + + if (ACPI_FAILURE(status)) { + if (i == 0) /* no active trip points */ + break; + if (act <= 0) /* no override requested */ + break; + if (i == 1) { /* 1 trip point */ + tz->trips.active[0].temperature = + CELSIUS_TO_KELVIN(act); + } else { /* multiple trips */ + /* + * Don't allow override higher than + * the next higher trip point + */ + tz->trips.active[i - 1].temperature = + (tz->trips.active[i - 2].temperature < + CELSIUS_TO_KELVIN(act) ? + tz->trips.active[i - 2].temperature : + CELSIUS_TO_KELVIN(act)); + } break; + } name[2] = 'L'; status = -- cgit v1.2.3 From 0b5bfa1cbefdc6e4c60f30ed545389b5ffe0f75f Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 12 Aug 2007 00:13:02 -0400 Subject: ACPI: thermal: add DMI hooks to handle AOpen's broken Award BIOS Use DMI to: 1. enable polling (BIOS thermal events are broken) 2. disable active trip points (BIOS fan control is broken) 3. disable passive trip point (BIOS hard-codes it too low) The actual temperature reading does work, and with the aid of polling, the critical trip point should work too. http://bugzilla.kernel.org/show_bug.cgi?id=8842 Signed-off-by: Len Brown --- drivers/acpi/thermal.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 3521c37bbd33..1e06159fd9c4 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -1328,10 +1329,74 @@ static int acpi_thermal_resume(struct acpi_device *device) return AE_OK; } +#ifdef CONFIG_DMI +static int thermal_act(struct dmi_system_id *d) { + + if (act == 0) { + printk(KERN_NOTICE "ACPI: %s detected: " + "disabling all active thermal trip points\n", d->ident); + act = -1; + } + return 0; +} +static int thermal_tzp(struct dmi_system_id *d) { + + if (tzp == 0) { + printk(KERN_NOTICE "ACPI: %s detected: " + "enabling thermal zone polling\n", d->ident); + tzp = 300; /* 300 dS = 30 Seconds */ + } + return 0; +} +static int thermal_psv(struct dmi_system_id *d) { + + if (psv == 0) { + printk(KERN_NOTICE "ACPI: %s detected: " + "disabling all passive thermal trip points\n", d->ident); + psv = -1; + } + return 0; +} + +static struct dmi_system_id thermal_dmi_table[] __initdata = { + /* + * Award BIOS on this AOpen makes thermal control almost worthless. + * http://bugzilla.kernel.org/show_bug.cgi?id=8842 + */ + { + .callback = thermal_act, + .ident = "AOpen i915GMm-HFS", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), + DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), + }, + }, + { + .callback = thermal_psv, + .ident = "AOpen i915GMm-HFS", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), + DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), + }, + }, + { + .callback = thermal_tzp, + .ident = "AOpen i915GMm-HFS", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), + DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), + }, + }, + {} +}; +#endif /* CONFIG_DMI */ + static int __init acpi_thermal_init(void) { int result = 0; + dmi_check_system(thermal_dmi_table); + if (off) { printk(KERN_NOTICE "ACPI: thermal control disabled\n"); return -ENODEV; -- cgit v1.2.3 From ea7be66c44e56b6b7f1d61befc300871e855d43a Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sun, 5 Aug 2007 12:19:01 -0400 Subject: hwmon: (w83627ehf) read fan_div values during probe This patch forces the driver to read the fan divider values during early init. Otherwise, a call to store_fan_min() could access uninitialized variables. Signed-off-by: Mark M. Hoffman Signed-off-by: Jean Delvare --- drivers/hwmon/w83627ehf.c | 48 ++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index c51ae2e17758..bca7fbcfbece 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -421,6 +421,31 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) } } +static void w83627ehf_update_fan_div(struct w83627ehf_data *data) +{ + int i; + + i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); + data->fan_div[0] = (i >> 4) & 0x03; + data->fan_div[1] = (i >> 6) & 0x03; + i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); + data->fan_div[2] = (i >> 6) & 0x03; + i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); + data->fan_div[0] |= (i >> 3) & 0x04; + data->fan_div[1] |= (i >> 4) & 0x04; + data->fan_div[2] |= (i >> 5) & 0x04; + if (data->has_fan & ((1 << 3) | (1 << 4))) { + i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); + data->fan_div[3] = i & 0x03; + data->fan_div[4] = ((i >> 2) & 0x03) + | ((i >> 5) & 0x04); + } + if (data->has_fan & (1 << 3)) { + i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); + data->fan_div[3] |= (i >> 5) & 0x04; + } +} + static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) { struct w83627ehf_data *data = dev_get_drvdata(dev); @@ -432,25 +457,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ/2) || !data->valid) { /* Fan clock dividers */ - i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); - data->fan_div[0] = (i >> 4) & 0x03; - data->fan_div[1] = (i >> 6) & 0x03; - i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); - data->fan_div[2] = (i >> 6) & 0x03; - i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); - data->fan_div[0] |= (i >> 3) & 0x04; - data->fan_div[1] |= (i >> 4) & 0x04; - data->fan_div[2] |= (i >> 5) & 0x04; - if (data->has_fan & ((1 << 3) | (1 << 4))) { - i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); - data->fan_div[3] = i & 0x03; - data->fan_div[4] = ((i >> 2) & 0x03) - | ((i >> 5) & 0x04); - } - if (data->has_fan & (1 << 3)) { - i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); - data->fan_div[3] |= (i >> 5) & 0x04; - } + w83627ehf_update_fan_div(data); /* Measured voltages and limits */ for (i = 0; i < data->in_num; i++) { @@ -1312,6 +1319,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) if (!(i & (1 << 1)) && (!fan5pin)) data->has_fan |= (1 << 4); + /* Read fan clock dividers immediately */ + w83627ehf_update_fan_div(data); + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) if ((err = device_create_file(dev, -- cgit v1.2.3 From 0956895aa6f8dc6a33210967252fd7787652537d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 11 Aug 2007 13:57:05 +0200 Subject: hwmon: (w83627ehf) don't assume bank 0 Don't assume that the default bank is 0. For one thing, we don't even set it to 0 when the driver is loaded, so the initial state might be different. For another, something (say, the BIOS) might access the chip and leave with the bank set to something different, so assuming that the bank value is 0 is not safe. Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/w83627ehf.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index bca7fbcfbece..d9a9ec7dd84a 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -309,18 +309,16 @@ static inline int is_word_sized(u16 reg) || (reg & 0x00ff) == 0x55)); } -/* We assume that the default bank is 0, thus the following two functions do - nothing for registers which live in bank 0. For others, they respectively - set the bank register to the correct value (before the register is - accessed), and back to 0 (afterwards). */ +/* Registers 0x50-0x5f are banked */ static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) { - if (reg & 0xff00) { + if ((reg & 0x00f0) == 0x50) { outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); } } +/* Not strictly necessary, but play it safe for now */ static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) { if (reg & 0xff00) { -- cgit v1.2.3 From 68a50b567895ea677645ca3cebc484674123532d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 12 Aug 2007 13:58:50 +0200 Subject: hwmon: (smsc47m1) restore missing name attribute The smsc47m1 driver no longer creates the name attribute used by libsensors to identify chip types. It was lost during the conversion to a platform driver. I was fooled by the fact that we do have a group with all attributes, but only to delete them all at once. The group is not used to create the attributes, so we have to explicitly create the name attribute. This fixes lm-sensors ticket #2236: http://lm-sensors.org/ticket/2236 Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/smsc47m1.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 338ee4f54614..d3181967f167 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -585,6 +585,8 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) if ((err = device_create_file(dev, &dev_attr_alarms))) goto error_remove_files; + if ((err = device_create_file(dev, &dev_attr_name))) + goto error_remove_files; data->class_dev = hwmon_device_register(dev); if (IS_ERR(data->class_dev)) { -- cgit v1.2.3 From 947b2a8083a03e6fff448ce8928956015614855e Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 13 Aug 2007 17:57:03 +0300 Subject: mlx4_core: Wait 1 second after reset before accessing device Put a 1000 msec delay after resetting the device before attempting to do config cycles on it. Not waiting causes system hangs on some chipsets, e.g. Intel E7520, when the driver is loaded. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier --- drivers/net/mlx4/reset.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c index e4dfd4b11a4a..e199715fabd0 100644 --- a/drivers/net/mlx4/reset.c +++ b/drivers/net/mlx4/reset.c @@ -119,6 +119,9 @@ int mlx4_reset(struct mlx4_dev *dev) writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET); iounmap(reset); + /* Docs say to wait one second before accessing device */ + msleep(1000); + end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES; do { if (!pci_read_config_word(dev->pdev, PCI_VENDOR_ID, &vendor) && -- cgit v1.2.3 From c019b1933015ee31366eeaa085bad3ee9516991c Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 14 Aug 2007 01:03:42 -0400 Subject: ACPI: EC: Fix "no battery" regression Restore deleted call to register query methods. http://bugzilla.kernel.org/show_bug.cgi?id=8886 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 2300d81bbc4e..56bee9e065cf 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -651,6 +651,19 @@ static struct acpi_ec *make_acpi_ec(void) return ec; } +static acpi_status +acpi_ec_register_query_methods(acpi_handle handle, u32 level, + void *context, void **return_value) +{ + struct acpi_namespace_node *node = handle; + struct acpi_ec *ec = context; + int value = 0; + if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { + acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); + } + return AE_OK; +} + static acpi_status ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) { @@ -668,6 +681,10 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) if (ACPI_FAILURE(status)) return status; + /* Find and register all query methods */ + acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, + acpi_ec_register_query_methods, ec, NULL); + /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); -- cgit v1.2.3 From b47157f00414f368f2847697ce48b76f1a5e5110 Mon Sep 17 00:00:00 2001 From: Dustin Marquess Date: Fri, 10 Aug 2007 14:05:15 -0700 Subject: via-rhine: disable rx_copybreak on archs that don't allow unaligned DMA access Patch to disable the rx_copybreak feature on hardware architectures that don't allow unaligned DMA access. #ifdef code taken from tulip_core.c. Problem pointed out by Ivan Kokshaysky. Signed-off-by: Dustin Marquess Cc: Francois Romieu Cc: Ivan Kokshaysky Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/via-rhine.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index c3fe230695a0..b56dff26772d 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -42,7 +42,13 @@ static int max_interrupt_work = 20; /* Set the copy breakpoint for the copy-only-tiny-frames scheme. Setting to > 1518 effectively disables this feature. */ +#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ + || defined(CONFIG_SPARC) || defined(__ia64__) \ + || defined(__sh__) || defined(__mips__) +static int rx_copybreak = 1518; +#else static int rx_copybreak; +#endif /* Work-around for broken BIOSes: they are unable to get the chip back out of power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */ -- cgit v1.2.3 From 626fda948839fc2f488f527076b8f42b1b7a4687 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 9 Aug 2007 09:02:14 +0200 Subject: myri10ge: Use the pause counter to avoid a needless device reset Use the pause counter to avoid a needless device reset, and print a message telling the admin that our link partner is flow controlling us down to 0 pkts/sec. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index deca65330b0f..ae9bb7b7fd67 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -191,6 +191,7 @@ struct myri10ge_priv { struct timer_list watchdog_timer; int watchdog_tx_done; int watchdog_tx_req; + int watchdog_pause; int watchdog_resets; int tx_linearized; int pause; @@ -2800,6 +2801,7 @@ static void myri10ge_watchdog(struct work_struct *work) static void myri10ge_watchdog_timer(unsigned long arg) { struct myri10ge_priv *mgp; + u32 rx_pause_cnt; mgp = (struct myri10ge_priv *)arg; @@ -2816,19 +2818,28 @@ static void myri10ge_watchdog_timer(unsigned long arg) myri10ge_fill_thresh) mgp->rx_big.watchdog_needed = 0; } + rx_pause_cnt = ntohl(mgp->fw_stats->dropped_pause); if (mgp->tx.req != mgp->tx.done && mgp->tx.done == mgp->watchdog_tx_done && - mgp->watchdog_tx_req != mgp->watchdog_tx_done) + mgp->watchdog_tx_req != mgp->watchdog_tx_done) { /* nic seems like it might be stuck.. */ - schedule_work(&mgp->watchdog_work); - else - /* rearm timer */ - mod_timer(&mgp->watchdog_timer, - jiffies + myri10ge_watchdog_timeout * HZ); - + if (rx_pause_cnt != mgp->watchdog_pause) { + if (net_ratelimit()) + printk(KERN_WARNING "myri10ge %s:" + "TX paused, check link partner\n", + mgp->dev->name); + } else { + schedule_work(&mgp->watchdog_work); + return; + } + } + /* rearm timer */ + mod_timer(&mgp->watchdog_timer, + jiffies + myri10ge_watchdog_timeout * HZ); mgp->watchdog_tx_done = mgp->tx.done; mgp->watchdog_tx_req = mgp->tx.req; + mgp->watchdog_pause = rx_pause_cnt; } static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3 From b4efe22cc987f4cd68ff838556580c0cc8c64cbc Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 10 Aug 2007 14:05:21 -0700 Subject: ax88796 printk fixes drivers/net/ax88796.c: In function `ax_probe': drivers/net/ax88796.c:825: warning: size_t format, different type arg (arg 4) drivers/net/ax88796.c:825: warning: size_t format, different type arg (arg 5) resource_size_t isn't size_t. Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/ax88796.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 83da1770bafb..90e0734e6037 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -821,8 +821,9 @@ static int ax_probe(struct platform_device *pdev) dev->base_addr = (unsigned long)ei_status.mem; if (ei_status.mem == NULL) { - dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n", - res->start, res->end); + dev_err(&pdev->dev, "Cannot ioremap area (%08llx,%08llx)\n", + (unsigned long long)res->start, + (unsigned long long)res->end); ret = -ENXIO; goto exit_req; -- cgit v1.2.3 From c76720cf7ba63a3d179b6da8675653c8b01b6c0b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 10 Aug 2007 14:05:23 -0700 Subject: natsemi: fix netdev error acounting When a detailed netdev error is counted, we also must account for it in the aggregated error count. Addresses http://bugzilla.kernel.org/show_bug.cgi?id=8106 Cc: Tim Hockin Cc: Jeff Garzik Cc: Chongfeng Hu Cc: Natalie Protasevich Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/natsemi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 6bb48ba80964..b47a12d684f9 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -2438,13 +2438,16 @@ static void netdev_error(struct net_device *dev, int intr_status) dev->name); } np->stats.rx_fifo_errors++; + np->stats.rx_errors++; } /* Hmmmmm, it's not clear how to recover from PCI faults. */ if (intr_status & IntrPCIErr) { printk(KERN_NOTICE "%s: PCI error %#08x\n", dev->name, intr_status & IntrPCIErr); np->stats.tx_fifo_errors++; + np->stats.tx_errors++; np->stats.rx_fifo_errors++; + np->stats.rx_errors++; } spin_unlock(&np->lock); } -- cgit v1.2.3 From 373492d0bdc66680ee598fd5a63e1914631b2522 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Fri, 10 Aug 2007 14:05:26 -0700 Subject: 3c59x: fix duplex configuration A special sequence of ifconfig up/down and plug/unplug the cable can break the duplex configuration of the driver. Setting vp->mii.full_duplex = vp->full_duplex in vortex_up should fix this. Addresses Bug 8575 3c59x duplex configuration broken http://bugzilla.kernel.org/show_bug.cgi?id=8575 Cc: Martin Buck Signed-off-by: Steffen Klassert Cc: Natalie Protasevich Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/3c59x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 001c66dd3a94..a8c0f436cdd2 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1555,6 +1555,7 @@ vortex_up(struct net_device *dev) mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); + vp->mii.full_duplex = vp->full_duplex; vortex_check_media(dev, 1); } -- cgit v1.2.3 From 10a273a67343e1f317652d69b09a212ee0284b44 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 13 Aug 2007 12:54:37 -0700 Subject: xen-netfront: Avoid deref'ing skbafter it is potentially freed. xennet_tx_bug_gc can free the skb before we use it, so make sure we don't. Signed-off-by: Keir Fraser Signed-off-by: Jeremy Fitzhardinge Cc: Jeff Garzik Signed-off-by: Jeff Garzik --- drivers/net/xen-netfront.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 489f69c5d6ca..4445810335a8 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -566,6 +566,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (notify) notify_remote_via_irq(np->netdev->irq); + np->stats.tx_bytes += skb->len; + np->stats.tx_packets++; + + /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc(dev); if (!netfront_tx_slot_available(np)) @@ -573,9 +577,6 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irq(&np->tx_lock); - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++; - return 0; drop: -- cgit v1.2.3 From 8aee929eda10b2502fd76c0bf2003f89f7992820 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 10 Aug 2007 15:14:18 -0700 Subject: [ATM]: fore200e_param_bs_queue() must be __devinit WARNING: drivers/built-in.o(.text+0x6203bb): Section mismatch: reference to .init.text:fore200e_param_bs_queue (between 'fore200e_initialize' and 'fore200e_monitor_putc') Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/fore200e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 405ee5e09221..8b12925fe7a4 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2435,7 +2435,7 @@ fore200e_init_cmd_queue(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_param_bs_queue(struct fore200e* fore200e, enum buffer_scheme scheme, enum buffer_magn magn, int queue_length, int pool_size, int supply_blksize) -- cgit v1.2.3 From af3502184aee8a0af6da8678e84c3d5bc5cdb83f Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 10 Aug 2007 15:15:55 -0700 Subject: [ATM]: Clean up duplicate includes in drivers/atm/ This patch cleans up duplicate includes in drivers/atm/ Signed-off-by: Jesper Juhl Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/lanai.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 55fd1b4543fd..144a49f15220 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -65,7 +65,6 @@ #include #include #include -#include /* -------------------- TUNABLE PARAMATERS: */ -- cgit v1.2.3 From 1ee325438cdbe374ebea6e3d2f19204072c15038 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 15:24:50 -0700 Subject: [WAN] drivers/net/wan/hdlc_fr.c: kmalloc + memset conversion to kzalloc drivers/net/wan/hdlc_fr.c | 31260 -> 31223 (-37 bytes) drivers/net/wan/hdlc_fr.o | 144872 -> 144728 (-144 bytes) Signed-off-by: Mariusz Kozlowski Acked-by: Krzysztof Halasa Signed-off-by: Andrew Morton --- drivers/net/wan/hdlc_fr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 15b6e07a4382..071a64cacd5c 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -212,14 +212,13 @@ static pvc_device* add_pvc(struct net_device *dev, u16 dlci) pvc_p = &(*pvc_p)->next; } - pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); + pvc = kzalloc(sizeof(pvc_device), GFP_ATOMIC); #ifdef DEBUG_PVC printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev); #endif if (!pvc) return NULL; - memset(pvc, 0, sizeof(pvc_device)); pvc->dlci = dlci; pvc->frad = dev; pvc->next = *pvc_p; /* Put it in the chain */ -- cgit v1.2.3 From 48e3eeb1a1a89a3ea256cf6d3c898e753787cfaa Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 15:25:40 -0700 Subject: [IRDA] irda-usb.c: mostly kmalloc + memset conversion to k[cz]alloc drivers/net/irda/irda-usb.c | 59694 -> 59541 (-153 bytes) drivers/net/irda/irda-usb.o | 170588 -> 169256 (-1332 bytes) Signed-off-by: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/irda/irda-usb.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 0ac240ca905b..3b0fd83fa266 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1561,10 +1561,9 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf struct irda_class_desc *desc; int ret; - desc = kmalloc(sizeof (*desc), GFP_KERNEL); - if (desc == NULL) + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) return NULL; - memset(desc, 0, sizeof(*desc)); /* USB-IrDA class spec 1.0: * 6.1.3: Standard "Get Descriptor" Device Request is not @@ -1617,7 +1616,7 @@ static int irda_usb_probe(struct usb_interface *intf, { struct net_device *net; struct usb_device *dev = interface_to_usbdev(intf); - struct irda_usb_cb *self = NULL; + struct irda_usb_cb *self; struct usb_host_interface *interface; struct irda_class_desc *irda_desc; int ret = -ENOMEM; @@ -1655,7 +1654,7 @@ static int irda_usb_probe(struct usb_interface *intf, self->header_length = USB_IRDA_HEADER; } - self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), + self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), GFP_KERNEL); for (i = 0; i < self->max_rx_urb; i++) { @@ -1715,7 +1714,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Find IrDA class descriptor */ irda_desc = irda_usb_find_class_desc(intf); ret = -ENODEV; - if (irda_desc == NULL) + if (!irda_desc) goto err_out_3; if (self->needspatch) { @@ -1738,15 +1737,13 @@ static int irda_usb_probe(struct usb_interface *intf, /* Don't change this buffer size and allocation without doing * some heavy and complete testing. Don't ask why :-( * Jean II */ - self->speed_buff = kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL); - if (self->speed_buff == NULL) + self->speed_buff = kzalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL); + if (!self->speed_buff) goto err_out_3; - memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); - self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length, GFP_KERNEL); - if (self->tx_buff == NULL) + if (!self->tx_buff) goto err_out_4; ret = irda_usb_open(self); @@ -1767,12 +1764,11 @@ static int irda_usb_probe(struct usb_interface *intf, /* replace IrDA class descriptor with what patched device is now reporting */ irda_desc = irda_usb_find_class_desc (self->usbintf); - if (irda_desc == NULL) { + if (!irda_desc) { ret = -ENODEV; goto err_out_6; } - if (self->irda_desc) - kfree (self->irda_desc); + kfree(self->irda_desc); self->irda_desc = irda_desc; irda_usb_init_qos(self); } -- cgit v1.2.3 From f71417614d63932cf56ed98a0947568d6259d11e Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 15:26:18 -0700 Subject: [ATM] drivers/atm/iphase.c: mostly kmalloc + memset conversion to kzalloc drivers/atm/iphase.c | 111508 -> 111431 (-77 bytes) drivers/atm/iphase.o | 254740 -> 254260 (-480 bytes) Signed-off-by: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/iphase.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index a3b605a0ca17..ef52452640e0 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -1601,14 +1601,14 @@ static int rx_init(struct atm_dev *dev) skb_queue_head_init(&iadev->rx_dma_q); iadev->rx_free_desc_qhead = NULL; - iadev->rx_open = kmalloc(4*iadev->num_vc,GFP_KERNEL); - if (!iadev->rx_open) - { + + iadev->rx_open = kzalloc(4 * iadev->num_vc, GFP_KERNEL); + if (!iadev->rx_open) { printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n", dev->number); goto err_free_dle; } - memset(iadev->rx_open, 0, 4*iadev->num_vc); + iadev->rxing = 1; iadev->rx_pkt_cnt = 0; /* Mode Register */ @@ -3171,12 +3171,12 @@ static int __devinit ia_init_one(struct pci_dev *pdev, unsigned long flags; int ret; - iadev = kmalloc(sizeof(*iadev), GFP_KERNEL); + iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); if (!iadev) { ret = -ENOMEM; goto err_out; } - memset(iadev, 0, sizeof(*iadev)); + iadev->pci = pdev; IF_INIT(printk("ia detected at bus:%d dev: %d function:%d\n", -- cgit v1.2.3 From 7f353bf29e162459f2f1e2ca25e41011fae65241 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 10 Aug 2007 15:47:58 -0700 Subject: [NET]: Share correct feature code between bridging and bonding http://bugzilla.kernel.org/show_bug.cgi?id=8797 shows that the bonding driver may produce bogus combinations of the checksum flags and SG/TSO. For example, if you bond devices with NETIF_F_HW_CSUM and NETIF_F_IP_CSUM you'll end up with a bonding device that has neither flag set. If both have TSO then this produces an illegal combination. The bridge device on the other hand has the correct code to deal with this. In fact, the same code can be used for both. So this patch moves that logic into net/core/dev.c and uses it for both bonding and bridging. In the process I've made small adjustments such as only setting GSO_ROBUST if at least one constituent device supports it. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 34 +++++++++++++--------------------- include/linux/netdevice.h | 2 ++ net/bridge/br_device.c | 2 +- net/bridge/br_if.c | 36 ++++-------------------------------- net/core/dev.c | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 070b78d959cc..1afda3230def 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1202,43 +1202,35 @@ static int bond_sethwaddr(struct net_device *bond_dev, return 0; } -#define BOND_INTERSECT_FEATURES \ - (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) +#define BOND_VLAN_FEATURES \ + (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \ + NETIF_F_HW_VLAN_FILTER) /* * Compute the common dev->feature set available to all slaves. Some - * feature bits are managed elsewhere, so preserve feature bits set on - * master device that are not part of the examined set. + * feature bits are managed elsewhere, so preserve those feature bits + * on the master device. */ static int bond_compute_features(struct bonding *bond) { - unsigned long features = BOND_INTERSECT_FEATURES; struct slave *slave; struct net_device *bond_dev = bond->dev; + unsigned long features = bond_dev->features; unsigned short max_hard_header_len = ETH_HLEN; int i; + features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); + features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | + NETIF_F_GSO_MASK | NETIF_F_NO_CSUM; + bond_for_each_slave(bond, slave, i) { - features &= (slave->dev->features & BOND_INTERSECT_FEATURES); + features = netdev_compute_features(features, + slave->dev->features); if (slave->dev->hard_header_len > max_hard_header_len) max_hard_header_len = slave->dev->hard_header_len; } - if ((features & NETIF_F_SG) && - !(features & NETIF_F_ALL_CSUM)) - features &= ~NETIF_F_SG; - - /* - * features will include NETIF_F_TSO (NETIF_F_UFO) iff all - * slave devices support NETIF_F_TSO (NETIF_F_UFO), which - * implies that all slaves also support scatter-gather - * (NETIF_F_SG), which implies that features also includes - * NETIF_F_SG. So no need to check whether we have an - * illegal combination of NETIF_F_{TSO,UFO} and - * !NETIF_F_SG - */ - - features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); + features |= (bond_dev->features & BOND_VLAN_FEATURES); bond_dev->features = features; bond_dev->hard_header_len = max_hard_header_len; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4a616d73cc25..e679b2751665 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1131,6 +1131,8 @@ extern void dev_seq_stop(struct seq_file *seq, void *v); extern void linkwatch_run_queue(void); +extern int netdev_compute_features(unsigned long all, unsigned long one); + static inline int net_gso_ok(int features, int gso_type) { int feature = gso_type << NETIF_F_GSO_SHIFT; diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 5e1892d8d874..0eded176ce99 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -179,5 +179,5 @@ void br_dev_setup(struct net_device *dev) dev->priv_flags = IFF_EBRIDGE; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | - NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST; + NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX; } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b40dada002bf..749f0e8f541d 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -349,43 +349,15 @@ int br_min_mtu(const struct net_bridge *br) void br_features_recompute(struct net_bridge *br) { struct net_bridge_port *p; - unsigned long features, checksum; + unsigned long features; - checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; - features = br->feature_mask & ~NETIF_F_ALL_CSUM; + features = br->feature_mask; list_for_each_entry(p, &br->port_list, list) { - unsigned long feature = p->dev->features; - - /* if device needs checksumming, downgrade to hw checksumming */ - if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM)) - checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; - - /* if device can't do all checksum, downgrade to ipv4/ipv6 */ - if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM)) - checksum ^= NETIF_F_HW_CSUM - | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - - if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM)) - checksum &= ~NETIF_F_IPV6_CSUM; - - if (!(feature & NETIF_F_IP_CSUM)) - checksum = 0; - - if (feature & NETIF_F_GSO) - feature |= NETIF_F_GSO_SOFTWARE; - feature |= NETIF_F_GSO; - - features &= feature; + features = netdev_compute_features(features, p->dev->features); } - if (!(checksum & NETIF_F_ALL_CSUM)) - features &= ~NETIF_F_SG; - if (!(features & NETIF_F_SG)) - features &= ~NETIF_F_GSO_MASK; - - br->dev->features = features | checksum | NETIF_F_LLTX | - NETIF_F_GSO_ROBUST; + br->dev->features = features; } /* called with RTNL */ diff --git a/net/core/dev.c b/net/core/dev.c index 6cc8a70350ac..a76021c71207 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3993,6 +3993,45 @@ static int __init netdev_dma_register(void) static int __init netdev_dma_register(void) { return -ENODEV; } #endif /* CONFIG_NET_DMA */ +/** + * netdev_compute_feature - compute conjunction of two feature sets + * @all: first feature set + * @one: second feature set + * + * Computes a new feature set after adding a device with feature set + * @one to the master device with current feature set @all. Returns + * the new feature set. + */ +int netdev_compute_features(unsigned long all, unsigned long one) +{ + /* if device needs checksumming, downgrade to hw checksumming */ + if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) + all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; + + /* if device can't do all checksum, downgrade to ipv4/ipv6 */ + if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM)) + all ^= NETIF_F_HW_CSUM + | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + + if (one & NETIF_F_GSO) + one |= NETIF_F_GSO_SOFTWARE; + one |= NETIF_F_GSO; + + /* If even one device supports robust GSO, enable it for all. */ + if (one & NETIF_F_GSO_ROBUST) + all |= NETIF_F_GSO_ROBUST; + + all &= one | NETIF_F_LLTX; + + if (!(all & NETIF_F_ALL_CSUM)) + all &= ~NETIF_F_SG; + if (!(all & NETIF_F_SG)) + all &= ~NETIF_F_GSO_MASK; + + return all; +} +EXPORT_SYMBOL(netdev_compute_features); + /* * Initialize the DEV module. At boot time this walks the device list and * unhooks any devices that fail to initialise (normally hardware not -- cgit v1.2.3 From ce57a02c64052c3f1c62f30a902a937e6c316d88 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 9 Aug 2007 14:09:34 -0700 Subject: e1000: Add device IDs of new 82571 board variants This patch adds support for 2 new board variants: - A Quad port fiber 82571 board - A blade version of the 82571 quad copper board Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 2 ++ drivers/net/e1000/e1000_hw.c | 5 +++++ drivers/net/e1000/e1000_hw.h | 3 +++ drivers/net/e1000/e1000_main.c | 4 ++++ 4 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index c90c92e72d2a..4c3785c9d4b8 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1706,6 +1706,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82546GB_QUAD_COPPER: case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82571EB_SERDES_QUAD: /* these don't support WoL at all */ wol->supported = 0; break; @@ -1723,6 +1724,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol retval = 0; break; case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_FIBER: case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: /* quad port adapters only support WoL on port A */ diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 9be44699300b..ba120f7fb0be 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -384,7 +384,10 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82571EB_COPPER: case E1000_DEV_ID_82571EB_FIBER: case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82571EB_SERDES_DUAL: + case E1000_DEV_ID_82571EB_SERDES_QUAD: case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_FIBER: case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: hw->mac_type = e1000_82571; break; @@ -485,6 +488,8 @@ e1000_set_media_type(struct e1000_hw *hw) case E1000_DEV_ID_82545GM_SERDES: case E1000_DEV_ID_82546GB_SERDES: case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82571EB_SERDES_DUAL: + case E1000_DEV_ID_82571EB_SERDES_QUAD: case E1000_DEV_ID_82572EI_SERDES: case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: hw->media_type = e1000_media_type_internal_serdes; diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index bd000b802ee7..fe8714655c90 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -475,7 +475,10 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #define E1000_DEV_ID_82571EB_FIBER 0x105F #define E1000_DEV_ID_82571EB_SERDES 0x1060 #define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 #define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA #define E1000_DEV_ID_82572EI_COPPER 0x107D #define E1000_DEV_ID_82572EI_FIBER 0x107E #define E1000_DEV_ID_82572EI_SERDES 0x107F diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index f48b659e0c2b..4a225950fb43 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -100,6 +100,7 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x1099), INTEL_E1000_ETHERNET_DEVICE(0x109A), INTEL_E1000_ETHERNET_DEVICE(0x10A4), + INTEL_E1000_ETHERNET_DEVICE(0x10A5), INTEL_E1000_ETHERNET_DEVICE(0x10B5), INTEL_E1000_ETHERNET_DEVICE(0x10B9), INTEL_E1000_ETHERNET_DEVICE(0x10BA), @@ -107,6 +108,8 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x10BC), INTEL_E1000_ETHERNET_DEVICE(0x10C4), INTEL_E1000_ETHERNET_DEVICE(0x10C5), + INTEL_E1000_ETHERNET_DEVICE(0x10D9), + INTEL_E1000_ETHERNET_DEVICE(0x10DA), /* required last entry */ {0,} }; @@ -1096,6 +1099,7 @@ e1000_probe(struct pci_dev *pdev, break; case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_FIBER: case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: /* if quad port adapter, disable WoL on all but port A */ if (global_quad_port_a != 0) -- cgit v1.2.3 From 002cf63191eb8b68b7fed48f014b87c456188acc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 14 Aug 2007 18:37:13 +0200 Subject: i2c-i801: Typo: erroneous Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-i801.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 8f5c686123b8..289816db52ae 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -272,11 +272,11 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, /* Make sure the SMBus host is ready to start transmitting */ temp = inb_p(SMBHSTSTS); if (i == 1) { - /* Erronenous conditions before transaction: + /* Erroneous conditions before transaction: * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ errmask = 0x9f; } else { - /* Erronenous conditions during transaction: + /* Erroneous conditions during transaction: * Failed, Bus_Err, Dev_Err, Intr */ errmask = 0x1e; } -- cgit v1.2.3 From 322454a65371477bed0eb1d189c50d781ebd7f85 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 14 Aug 2007 18:37:14 +0200 Subject: i2c-mpc: Pass correct dev_id to free_irq on error path Signed-off-by: Scott Wood Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-mpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 851c3ed513d0..f7a81e999672 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -362,7 +362,7 @@ static int fsl_i2c_probe(struct platform_device *pdev) fail_add: if (i2c->irq != 0) - free_irq(i2c->irq, NULL); + free_irq(i2c->irq, i2c); fail_irq: iounmap(i2c->base); fail_map: -- cgit v1.2.3 From 25da383d26a1dcca4f0205769a24e5eac79c6d35 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 14 Aug 2007 18:37:14 +0200 Subject: i2c/isp1301_omap: Build fixes, whitespace Build fixes for isp1301_omap driver. I think an earlier version of this must have gotten lost somewhere, or maybe it only went into the Linux-OMAP tree. Also, some whitespace fixes to bring this more into sync with the version of this found in the Linux-OMAP tree. (That version has updates for the OTG controller on the OMAP 1710 which break that functionality on OMAP 161x boards like the H2, so merging all of it is not currently an option.) Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- drivers/i2c/chips/isp1301_omap.c | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 9fafadb92510..fe04e46991aa 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -18,8 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#undef DEBUG -#undef VERBOSE #include #include @@ -44,7 +42,7 @@ #define DRIVER_VERSION "24 August 2004" -#define DRIVER_NAME (isp1301_driver.name) +#define DRIVER_NAME (isp1301_driver.driver.name) MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver"); MODULE_LICENSE("GPL"); @@ -55,6 +53,7 @@ struct isp1301 { void (*i2c_release)(struct device *dev); int irq; + int irq_type; u32 last_otg_ctrl; unsigned working:1; @@ -63,7 +62,7 @@ struct isp1301 { /* use keventd context to change the state for us */ struct work_struct work; - + unsigned long todo; # define WORK_UPDATE_ISP 0 /* update ISP from OTG */ # define WORK_UPDATE_OTG 1 /* update OTG from ISP */ @@ -94,7 +93,7 @@ struct isp1301 { /* board-specific PM hooks */ -#include +#include #include #include @@ -291,7 +290,7 @@ static void power_up(struct isp1301 *isp) { // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG); - + /* do this only when cpu is driving transceiver, * so host won't see a low speed device... */ @@ -799,7 +798,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) /* role is host */ } else { if (!(otg_ctrl & OTG_ID)) { - otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ; } @@ -1100,9 +1099,9 @@ static u8 isp1301_clear_latch(struct isp1301 *isp) } static void -isp1301_work(void *data) +isp1301_work(struct work_struct *work) { - struct isp1301 *isp = data; + struct isp1301 *isp = container_of(work, struct isp1301, work); int stop; /* implicit lock: we're the only task using this device */ @@ -1244,7 +1243,7 @@ static int isp1301_detach_client(struct i2c_client *i2c) * - DEVICE mode, for when there's a B/Mini-B (device) connector * * As a rule, you won't have an isp1301 chip unless it's there to - * support the OTG mode. Other modes help testing USB controllers + * support the OTG mode. Other modes help testing USB controllers * in isolation from (full) OTG support, or maybe so later board * revisions can help to support those feature. */ @@ -1260,9 +1259,9 @@ static int isp1301_otg_enable(struct isp1301 *isp) * a few more interrupts than are strictly needed. */ isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); dev_info(&isp->client.dev, "ready for dual-role USB ...\n"); @@ -1306,9 +1305,9 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) dev_info(&isp->client.dev, "A-Host sessions ok\n"); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_ID_GND); + INTR_ID_GND); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_ID_GND); + INTR_ID_GND); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, especially with @@ -1368,9 +1367,9 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_SESS_VLD); + INTR_SESS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD); + INTR_VBUS_VLD); dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __FUNCTION__); @@ -1494,7 +1493,7 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) if (!isp) return 0; - INIT_WORK(&isp->work, isp1301_work, isp); + INIT_WORK(&isp->work, isp1301_work); init_timer(&isp->timer); isp->timer.function = isp1301_timer; isp->timer.data = (unsigned long) isp; @@ -1572,13 +1571,14 @@ fail1: /* IRQ wired at M14 */ omap_cfg_reg(M14_1510_GPIO2); isp->irq = OMAP_GPIO_IRQ(2); - omap_request_gpio(2); - omap_set_gpio_direction(2, 1); - omap_set_gpio_edge_ctrl(2, OMAP_GPIO_FALLING_EDGE); + if (gpio_request(2, "isp1301") == 0) + gpio_direction_input(2); + isp->irq_type = IRQF_TRIGGER_FALLING; } + isp->irq_type |= IRQF_SAMPLE_RANDOM; status = request_irq(isp->irq, isp1301_irq, - IRQF_SAMPLE_RANDOM, DRIVER_NAME, isp); + isp->irq_type, DRIVER_NAME, isp); if (status < 0) { dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", isp->irq, status); -- cgit v1.2.3 From 432ca994bf7107e88916fd9606ca7402a4571359 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Tue, 14 Aug 2007 18:37:14 +0200 Subject: i2c-iop3xx: Set I2C_CLASS_HWMON to adapter class In order to be able to use sensors on the IOP3xx SoCs, one needs to set the adapter class to I2C_CLASS_HWMON. Signed-off-by: Arnaud Patard Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-iop3xx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 440342bc62e1..ace644e21b14 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -490,6 +490,7 @@ iop3xx_i2c_probe(struct platform_device *pdev) memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); new_adapter->id = I2C_HW_IOP3XX; new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON; new_adapter->dev.parent = &pdev->dev; new_adapter->nr = pdev->id; -- cgit v1.2.3 From 5af0e07f87e7d9be2a9db514af1e338341240f6d Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Tue, 14 Aug 2007 18:37:14 +0200 Subject: i2c-mpc: Don't disable I2C module on stop condition Disabling module on stop doesn't work on some CPUs (ie. mpc8241, as reported by Guennadi Liakhovetski), so remove that. Disable I2C module on errors/interrupts to prevent it from locking up on mpc5200b. Signed-off-by: Domen Puncer Acked-by: Guennadi Liakhovetski Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-mpc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f7a81e999672..d8de4ac88b7d 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -105,6 +105,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) schedule(); if (time_after(jiffies, orig_jiffies + timeout)) { pr_debug("I2C: timeout\n"); + writeccr(i2c, 0); result = -EIO; break; } @@ -116,10 +117,12 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) result = wait_event_interruptible_timeout(i2c->queue, (i2c->interrupt & CSR_MIF), timeout * HZ); - if (unlikely(result < 0)) + if (unlikely(result < 0)) { pr_debug("I2C: wait interrupted\n"); - else if (unlikely(!(i2c->interrupt & CSR_MIF))) { + writeccr(i2c, 0); + } else if (unlikely(!(i2c->interrupt & CSR_MIF))) { pr_debug("I2C: wait timeout\n"); + writeccr(i2c, 0); result = -ETIMEDOUT; } @@ -172,7 +175,6 @@ static void mpc_i2c_start(struct mpc_i2c *i2c) static void mpc_i2c_stop(struct mpc_i2c *i2c) { writeccr(i2c, CCR_MEN); - writeccr(i2c, 0); } static int mpc_write(struct mpc_i2c *i2c, int target, @@ -261,6 +263,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) { if (signal_pending(current)) { pr_debug("I2C: Interrupted\n"); + writeccr(i2c, 0); return -EINTR; } if (time_after(jiffies, orig_jiffies + HZ)) { -- cgit v1.2.3 From a07ad1cc0300931bfd76bfcd2da3ddad743f4a89 Mon Sep 17 00:00:00 2001 From: Dale Farnsworth Date: Tue, 14 Aug 2007 18:37:14 +0200 Subject: i2c-mv64xxx: Reinitialize hw and driver on I2C bus hang Under certain conditions, the mv64xxx I2C bus can hang preventing further operation. To make the driver more robust, we now reset the I2C hardware and the driver state machine when such hangs are detected. Signed-off-by: Dale Farnsworth Acked-by: Mark A. Greer Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-mv64xxx.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 251154ae5d97..bb7bf68a7fb6 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -107,6 +107,21 @@ struct mv64xxx_i2c_data { * ***************************************************************************** */ + +/* Reset hardware and initialize FSM */ +static void +mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data) +{ + writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET); + writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)), + drv_data->reg_base + MV64XXX_I2C_REG_BAUD); + writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR); + writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR); + writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + drv_data->state = MV64XXX_I2C_STATE_IDLE; +} + static void mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) { @@ -203,7 +218,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) drv_data->state, status, drv_data->msg->addr, drv_data->msg->flags); drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; - drv_data->state = MV64XXX_I2C_STATE_IDLE; + mv64xxx_i2c_hw_init(drv_data); drv_data->rc = -EIO; } } @@ -367,6 +382,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) "mv64xxx: I2C bus locked, block: %d, " "time_left: %d\n", drv_data->block, (int)time_left); + mv64xxx_i2c_hw_init(drv_data); } } else spin_unlock_irqrestore(&drv_data->lock, flags); @@ -443,19 +459,6 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = { * ***************************************************************************** */ -static void __devinit -mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data) -{ - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET); - writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)), - drv_data->reg_base + MV64XXX_I2C_REG_BAUD); - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR); - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR); - writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP, - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); - drv_data->state = MV64XXX_I2C_STATE_IDLE; -} - static int __devinit mv64xxx_i2c_map_regs(struct platform_device *pd, struct mv64xxx_i2c_data *drv_data) -- cgit v1.2.3 From c1147cc6d18389f6530bae27741b9b2665e862e6 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 14 Aug 2007 18:37:14 +0200 Subject: i2c/menelaus: Build fix Fix Menelaus build error, and remove needless "#define DEBUG". Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- drivers/i2c/chips/menelaus.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c index 48a7e2f0bdd3..d9c92c5e0077 100644 --- a/drivers/i2c/chips/menelaus.c +++ b/drivers/i2c/chips/menelaus.c @@ -1,4 +1,3 @@ -#define DEBUG /* * Copyright (C) 2004 Texas Instruments, Inc. * @@ -933,7 +932,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t) return status; status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday)); if (status < 0) { - dev_err(&the_menelaus->client->dev, "rtc write reg %02x", + dev_err(&the_menelaus->client->dev, "rtc write reg %02x " "err %d\n", MENELAUS_RTC_WKDAY, status); return status; } -- cgit v1.2.3 From b5d0b4ba389711183b5af71438fe21b40ee32d6d Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 14 Aug 2007 18:37:15 +0200 Subject: i2c-s3c2410: Build fix Fixup the include files after the arch moves that where included in 2.6.23. Signed-off-by: Ben Dooks Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-s3c2410.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index e4540fcf6476..c44ada5f4292 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -39,8 +39,8 @@ #include #include -#include -#include +#include +#include /* i2c controller state */ -- cgit v1.2.3 From 54a09feb0ebb018dadaebeb51e860154198abc83 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 14 Aug 2007 17:36:31 -0700 Subject: [IOAT]: Remove redundant struct member to avoid descriptor cache miss The layout for struct ioat_desc_sw is non-optimal and causes an extra cache hit for every descriptor processed. By tightening up the struct layout and removing one item, we pull in the fields that get used in the speedpath and get a little better performance. Before: ------- struct ioat_desc_sw { struct ioat_dma_descriptor * hw; /* 0 8 */ struct list_head node; /* 8 16 */ int tx_cnt; /* 24 4 */ /* XXX 4 bytes hole, try to pack */ dma_addr_t src; /* 32 8 */ __u32 src_len; /* 40 4 */ /* XXX 4 bytes hole, try to pack */ dma_addr_t dst; /* 48 8 */ __u32 dst_len; /* 56 4 */ /* XXX 4 bytes hole, try to pack */ /* --- cacheline 1 boundary (64 bytes) --- */ struct dma_async_tx_descriptor async_tx; /* 64 144 */ /* --- cacheline 3 boundary (192 bytes) was 16 bytes ago --- */ /* size: 208, cachelines: 4 */ /* sum members: 196, holes: 3, sum holes: 12 */ /* last cacheline: 16 bytes */ }; /* definitions: 1 */ After: ------ struct ioat_desc_sw { struct ioat_dma_descriptor * hw; /* 0 8 */ struct list_head node; /* 8 16 */ int tx_cnt; /* 24 4 */ __u32 len; /* 28 4 */ dma_addr_t src; /* 32 8 */ dma_addr_t dst; /* 40 8 */ struct dma_async_tx_descriptor async_tx; /* 48 144 */ /* --- cacheline 3 boundary (192 bytes) --- */ /* size: 192, cachelines: 3 */ }; /* definitions: 1 */ Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/dma/ioatdma.c | 7 +++---- drivers/dma/ioatdma.h | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 5fbe56b5cea0..2d1f17865b64 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c @@ -347,8 +347,7 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en) new->async_tx.ack = 0; /* client is in control of this ack */ new->async_tx.cookie = -EBUSY; - pci_unmap_len_set(new, src_len, orig_len); - pci_unmap_len_set(new, dst_len, orig_len); + pci_unmap_len_set(new, len, orig_len); spin_unlock_bh(&ioat_chan->desc_lock); return new ? &new->async_tx : NULL; @@ -423,11 +422,11 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) */ pci_unmap_page(chan->device->pdev, pci_unmap_addr(desc, dst), - pci_unmap_len(desc, dst_len), + pci_unmap_len(desc, len), PCI_DMA_FROMDEVICE); pci_unmap_page(chan->device->pdev, pci_unmap_addr(desc, src), - pci_unmap_len(desc, src_len), + pci_unmap_len(desc, len), PCI_DMA_TODEVICE); } diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h index d3726478031a..bf4dad70e0f5 100644 --- a/drivers/dma/ioatdma.h +++ b/drivers/dma/ioatdma.h @@ -111,10 +111,9 @@ struct ioat_desc_sw { struct ioat_dma_descriptor *hw; struct list_head node; int tx_cnt; + DECLARE_PCI_UNMAP_LEN(len) DECLARE_PCI_UNMAP_ADDR(src) - DECLARE_PCI_UNMAP_LEN(src_len) DECLARE_PCI_UNMAP_ADDR(dst) - DECLARE_PCI_UNMAP_LEN(dst_len) struct dma_async_tx_descriptor async_tx; }; -- cgit v1.2.3 From 6a286a6d85bb0da687011b15f268c0e52e8eaba4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 3 Aug 2007 11:25:50 -0400 Subject: [libata] pata_isapnp: replace missing module device table Signed-off-by: Jeff Garzik --- drivers/ata/pata_isapnp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 5525518204e6..91a396fa5b20 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c @@ -139,6 +139,8 @@ static struct pnp_device_id isapnp_devices[] = { {.id = ""} }; +MODULE_DEVICE_TABLE(pnp, isapnp_devices); + static struct pnp_driver isapnp_driver = { .name = DRV_NAME, .id_table = isapnp_devices, -- cgit v1.2.3 From cfbf723eb7928879292ee71fa0d118fc4e37b8c9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 9 Jul 2007 14:38:41 +0100 Subject: sata_mv: PCI IDs for Hightpoint RocketRaid 1740/1742 Underneath all the HPT packaging, PCI identifiers, binary driver modules and stuff you find that ... Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 8ec520885b95..3acf65e75eb2 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -621,6 +621,9 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1740/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1740), chip_508x }, + { PCI_VDEVICE(TTI, 0x1742), chip_508x }, { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, -- cgit v1.2.3 From ac2b04371fffd964b0d1c3369a9972bed7a5c5d9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 7 Aug 2007 02:43:27 +0900 Subject: ata_piix: update map 10b for ich8m Fix map entry 10b for ich8. It's [P0 P2 IDE IDE] like ich6 / ich6m. Signed-off-by: Tejun Heo Cc: kristen.c.accardi@intel.com Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index a78832ea81fa..c5b4509c93f4 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -436,7 +436,7 @@ static const struct piix_map_db ich8_map_db = { /* PM PS SM SS MAP */ { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ { RV, RV, RV, RV }, - { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ + { P0, P2, IDE, IDE }, /* 10b (IDE mode) */ { RV, RV, RV, RV }, }, }; -- cgit v1.2.3 From be456b77ffbd3983b5da8eff49a70a701333f68b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 9 Aug 2007 23:19:34 +0200 Subject: pata_artop: fix UDMA5 for AEC6280[R] and UDMA6 for AEC6880[R] Maximum supported UDMA mode for AEC6280[R] is UDMA5 (not UDMA4) and for AEC6880[R] it is UDMA6 (not UDMA5): * Fix the problem by adding missing struct ata_port_info to artop_init_one(). * Use the right naming (s/626/628/). * Bump driver version. Fixes IDE->libata regression, problem was never present in IDE aec62xx driver. Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_artop.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index ce589d96ca42..b5352ebecef9 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -2,6 +2,7 @@ * pata_artop.c - ARTOP ATA controller driver * * (C) 2006 Red Hat + * (C) 2007 Bartlomiej Zolnierkiewicz * * Based in part on drivers/ide/pci/aec62xx.c * Copyright (C) 1999-2002 Andre Hedrick @@ -28,7 +29,7 @@ #include #define DRV_NAME "pata_artop" -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.4" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -430,7 +431,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA4, .port_ops = &artop6260_ops, }; - static const struct ata_port_info info_626x_fast = { + static const struct ata_port_info info_628x = { .sht = &artop_sht, .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ @@ -438,6 +439,14 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA5, .port_ops = &artop6260_ops, }; + static const struct ata_port_info info_628x_fast = { + .sht = &artop_sht, + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = ATA_UDMA6, + .port_ops = &artop6260_ops, + }; const struct ata_port_info *ppi[] = { NULL, NULL }; if (!printed_version++) @@ -455,13 +464,13 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) } else if (id->driver_data == 1) /* 6260 */ ppi[0] = &info_626x; - else if (id->driver_data == 2) { /* 6260 or 6260 + fast */ + else if (id->driver_data == 2) { /* 6280 or 6280 + fast */ unsigned long io = pci_resource_start(pdev, 4); u8 reg; - ppi[0] = &info_626x; + ppi[0] = &info_628x; if (inb(io) & 0x10) - ppi[0] = &info_626x_fast; + ppi[0] = &info_628x_fast; /* Mac systems come up with some registers not set as we will need them */ -- cgit v1.2.3 From d44a65f7bb0dae0bcc78de336b55a75b30ec2d2a Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 10 Aug 2007 20:58:46 +0400 Subject: pata_hpt37x: actually clock HPT374 with 50 MHz DPLL (take 2) The DPLL tuning code always set up it for 66 MHz due to wrong UltraDMA mask including mode 5 used to check for the necessity of 66 MHz clocking -- this caused 66 MHz clock to be used for HPT374 chip that does not tolerate it. While fixing this, also remove PLL mode from the TODO list -- I don't think it's still a relevant item. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 84d9c5568567..96bbe7c39bee 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -8,12 +8,10 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * TODO - * PLL mode - * Look into engine reset on timeout errors. Should not be - * required. + * Look into engine reset on timeout errors. Should not be required. */ #include @@ -26,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.7" +#define DRV_VERSION "0.6.8" struct hpt_clock { u8 xfer_speed; @@ -1092,9 +1090,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) int dpll, adjust; /* Compute DPLL */ - dpll = 2; - if (port->udma_mask & 0xE0) - dpll = 3; + dpll = (port->udma_mask & 0xC0) ? 3 : 2; f_low = (MHz[clock_slot] * 48) / MHz[dpll]; f_high = f_low + 2; -- cgit v1.2.3 From 80b8987c8feaf07a070f7cdcd55db024e9e200ec Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 10 Aug 2007 21:02:15 +0400 Subject: pata_hpt{37x|3x2n}: fix clock reporting (take 2) Fix several inconsistencies in these drivers WRT reporting the clocks: - when using DPLL mode, 'pata_hpt37x' driver reported the DPLL frequency as the PCI clock -- make it properly report both clocks and add the same ability to the 'pata_hpt3x2n' driver; - both drivers sometimes use "pata_hpt3*:" and sometimes "hpt3*:" in the messages -- make them use only the former one; - the message about failed DPLL stablizatios deserves KERN_ERR and a bang. :-) Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 10 ++++++---- drivers/ata/pata_hpt3x2n.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 96bbe7c39bee..c5ddd937dbf2 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.8" +#define DRV_VERSION "0.6.9" struct hpt_clock { u8 xfer_speed; @@ -1112,7 +1112,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); } if (adjust == 8) { - printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); + printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n"); return -ENODEV; } if (dpll == 3) @@ -1120,7 +1120,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) else private_data = (void *)hpt37x_timings_50; - printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]); + printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n", + MHz[clock_slot], MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; /* @@ -1133,7 +1134,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) port = &info_hpt370_33; if (clock_slot < 2 && port == &info_hpt370a) port = &info_hpt370a_33; - printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); + printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n", + chip_table->name, MHz[clock_slot]); } /* Now kick off ATA set up */ diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index aa29cde09f8b..f8f234bfc8ce 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -8,7 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * * TODO @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.3" +#define DRV_VERSION "0.3.4" enum { HPT_PCI_FAST = (1 << 31), @@ -579,10 +579,12 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } if (adjust == 8) { - printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n"); + printk(KERN_ERR "pata_hpt3x2n: DPLL did not stabilize!\n"); return -ENODEV; } + printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", + pci_mhz); /* Set our private data up. We only need a few flags so we use it directly */ port.private_data = NULL; -- cgit v1.2.3 From 5c08ea019198230a62c601ddf97d0319ae246ad8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Aug 2007 19:56:04 +0900 Subject: ata_piix: add TECRA M7 to broken suspend list Add TECRA M7 to broken suspend list. Reported by Marie Koreen. Signed-off-by: Tejun Heo Cc: Marie Koreen Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index c5b4509c93f4..071d274afaab 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -900,6 +900,13 @@ static int piix_broken_suspend(void) DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"), }, }, + { + .ident = "TECRA M7", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M7"), + }, + }, { .ident = "Satellite U205", .matches = { -- cgit v1.2.3 From fb0582f91fdd62b67bf54a440d7c79b19ed84da8 Mon Sep 17 00:00:00 2001 From: Ryan Power Date: Fri, 10 Aug 2007 13:59:35 -0700 Subject: libata: adjust libata to ignore errors after spinup Adjust libata to ignore errors after spinup This patch is to ignore errors from the spinup attempt if the drive is in the "standby id" state. Signed-off-by: Ryan Power Acked-by: Mark Lord Cc: Jeff Garzik Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 60e78bef469f..99d4fbffb0df 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1723,7 +1723,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, tf.protocol = ATA_PROT_NODATA; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); - if (err_mask) { + if (err_mask && id[2] != 0x738c) { rc = -EIO; reason = "SPINUP failed"; goto err_out; -- cgit v1.2.3 From fe11cb6ba40afff15efb053fd0bcba45274636e0 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Thu, 16 Aug 2007 01:02:07 +0300 Subject: IB/mlx4: Incorrect semicolon after if statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A stray semicolon makes us inadvertently ignore the value of err. Signed-off-by: Ilpo Järvinen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx4/mad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 333091787c5f..0ed02b7834da 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -109,7 +109,7 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, in_modifier, op_modifier, MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); - if (!err); + if (!err) memcpy(response_mad, outmailbox->buf, 256); mlx4_free_cmd_mailbox(dev->dev, inmailbox); -- cgit v1.2.3 From 0f112a86a36b91afe30e1cc8d4bc000402dde127 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Thu, 9 Aug 2007 19:38:00 +0000 Subject: [WATCHDOG] Eurotechwdt.c - clean-up comments Clean-up history and add a comment about the fact that the watchdog is actually part of the SMSC FDC 37B782 super I/O chipset. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/eurotechwdt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index b070324e27a6..b14e9d1f164d 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c @@ -1,5 +1,5 @@ /* - * Eurotech CPU-1220/1410 on board WDT driver + * Eurotech CPU-1220/1410/1420 on board WDT driver * * (c) Copyright 2001 Ascensit * (c) Copyright 2001 Rodolfo Giometti @@ -24,6 +24,9 @@ */ /* Changelog: + * + * 2001 - Rodolfo Giometti + * Initial release * * 2002/04/25 - Rob Radez * clean up #includes @@ -33,13 +36,15 @@ * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls * add expect_close support * - * 2001 - Rodolfo Giometti - * Initial release - * * 2002.05.30 - Joel Becker * Added Matt Domsch's nowayout module option. */ +/* + * The eurotech CPU-1220/1410/1420's watchdog is a part + * of the on-board SUPER I/O device SMSC FDC 37B782. + */ + #include #include #include -- cgit v1.2.3 From 6e420b7e26dd539f1f78fe920d295b022a2d99c8 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 16 Aug 2007 19:32:19 +0000 Subject: [WATCHDOG] Add support for 1533 bridge to alim1535_wdt From: Andrey Borzenkov They are apparently pretty close (even lspci combines them). The patch adds support for 0x1533 bridge in addition to 0x1535. Tested on Toshiba Portege 4000 with 00:07.0 ISA bridge [0601]: ALi Corporation M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] [10b9:1533] 00:08.0 Bridge [0680]: ALi Corporation M7101 Power Management Controller [PMU] [10b9:7101] with result [ 2090.906736] PCI: Enabling device 0000:00:08.0 (0000 -> 0001) [ 2090.914034] ALi_M1535: initialized. timeout=3D60 sec (nowayout=3D0) Signed-off-by: Andrey Borzenkov Signed-off-by: Wim Van Sebroeck Signed-off-by: Andrew Morton --- drivers/char/watchdog/alim1535_wdt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index e3f6a7d0c83d..c404fc69e7e6 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c @@ -312,6 +312,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void */ static struct pci_device_id ali_pci_tbl[] = { + { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,}, { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, { 0, }, }; @@ -329,9 +330,11 @@ static int __init ali_find_watchdog(void) struct pci_dev *pdev; u32 wdog; - /* Check for a 1535 series bridge */ + /* Check for a 1533/1535 series bridge */ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); - if(pdev == NULL) + if (pdev == NULL) + pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL); + if (pdev == NULL) return -ENODEV; pci_dev_put(pdev); -- cgit v1.2.3 From 9ef7ad22965fcd817b20c1332286f02362266534 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 17 Aug 2007 14:05:27 +1000 Subject: Enable partitions for lguest block device The lguest block device only requests one minor, which means partitions don't work (eg "root=/dev/lgba1"). Let's follow the crowd and ask for 16. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/block/lguest_blk.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/lguest_blk.c b/drivers/block/lguest_blk.c index 93e3c4001bf5..160cf14431ac 100644 --- a/drivers/block/lguest_blk.c +++ b/drivers/block/lguest_blk.c @@ -308,9 +308,12 @@ static int lguestblk_probe(struct lguest_device *lgdev) } /* This allocates a "struct gendisk" where we pack all the information - * about the disk which the rest of Linux sees. We ask for one minor - * number; I do wonder if we should be asking for more. */ - bd->disk = alloc_disk(1); + * about the disk which the rest of Linux sees. The argument is the + * number of minor devices desired: we need one minor for the main + * disk, and one for each partition. Of course, we can't possibly know + * how many partitions are on the disk (add_disk does that). + */ + bd->disk = alloc_disk(16); if (!bd->disk) { err = -ENOMEM; goto out_unregister_blkdev; -- cgit v1.2.3 From 06bfb7eb1535822a3338ffea9918e22215abed90 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 18 Aug 2007 12:56:21 +0200 Subject: Add some help texts to recently-introduced kconfig items Signed-off-by: Jan Engelhardt Signed-off-by: Stefan Richter (edited MACINTOSH_DRIVERS per Geert Uytterhoeven's remark) Signed-off-by: Linus Torvalds --- arch/i386/Kconfig | 5 +++++ drivers/atm/Kconfig | 5 +++++ drivers/auxdisplay/Kconfig | 5 +++++ drivers/block/Kconfig | 6 ++++++ drivers/crypto/Kconfig | 5 +++++ drivers/hid/Kconfig | 5 +++++ drivers/kvm/Kconfig | 5 +++++ drivers/macintosh/Kconfig | 5 +++++ drivers/misc/Kconfig | 5 +++++ drivers/net/Kconfig | 15 +++++++++++++++ drivers/usb/Kconfig | 3 +++ 11 files changed, 64 insertions(+) (limited to 'drivers') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f9524933258a..f16a46e8849c 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1228,6 +1228,11 @@ menuconfig INSTRUMENTATION bool "Instrumentation Support" depends on EXPERIMENTAL default y + ---help--- + Say Y here to get to see options related to performance measurement, + debugging, and testing. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if INSTRUMENTATION diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index bed9f58c2d5a..b554edac1ced 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig @@ -6,6 +6,11 @@ menuconfig ATM_DRIVERS bool "ATM drivers" depends on NETDEVICES && ATM default y + ---help--- + Say Y here to get to see options for Asynchronous Transfer Mode + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if ATM_DRIVERS && NETDEVICES && ATM diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index de2fcce10ba5..043353bd0600 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -8,6 +8,11 @@ menuconfig AUXDISPLAY depends on PARPORT bool "Auxiliary Display support" + ---help--- + Say Y here to get to see options for auxiliary display drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if AUXDISPLAY && PARPORT diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index a4a311992408..ef32e977d307 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -6,6 +6,12 @@ menuconfig BLK_DEV bool "Block devices" depends on BLOCK default y + ---help--- + Say Y here to get to see options for various different block device + drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled; + only do this if you know what you are doing. if BLK_DEV diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 84ebfcc1ffb4..c0fc4aeb8596 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -2,6 +2,11 @@ menuconfig CRYPTO_HW bool "Hardware crypto devices" default y + ---help--- + Say Y here to get to see options for hardware crypto devices and + processors. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if CRYPTO_HW diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3b63b0b78122..19667fcc722a 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -5,6 +5,11 @@ menuconfig HID_SUPPORT bool "HID Devices" depends on INPUT default y + ---help--- + Say Y here to get to see options for various computer-human interface + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if HID_SUPPORT diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig index 6cecc396e040..7b64fd4aa2f3 100644 --- a/drivers/kvm/Kconfig +++ b/drivers/kvm/Kconfig @@ -5,6 +5,11 @@ menuconfig VIRTUALIZATION bool "Virtualization" depends on X86 default y + ---help--- + Say Y here to get to see options for virtualization guest drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if VIRTUALIZATION diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index dbe96268866e..56cd8998fe4b 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -3,6 +3,11 @@ menuconfig MACINTOSH_DRIVERS bool "Macintosh device drivers" depends on PPC || MAC || X86 default y if (PPC_PMAC || MAC) + ---help--- + Say Y here to get to see options for devices used with Macintosh + computers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if MACINTOSH_DRIVERS diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 518d5d335464..a26655881e6a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -5,6 +5,11 @@ menuconfig MISC_DEVICES bool "Misc devices" default y + ---help--- + Say Y here to get to see options for device drivers from various + different categories. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if MISC_DEVICES diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 81ef81c9a584..5b9e17bf1749 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1968,6 +1968,16 @@ menuconfig NETDEV_1000 bool "Ethernet (1000 Mbit)" depends on !UML default y + ---help--- + Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common + type of Local Area Network (LAN) in universities and companies. + + Say Y here to get to see options for Gigabit Ethernet drivers. + This option alone does not add any kernel code. + Note that drivers supporting both 100 and 1000 MBit may be listed + under "Ethernet (10 or 100MBit)" instead. + + If you say N, all options in this submenu will be skipped and disabled. if NETDEV_1000 @@ -2339,6 +2349,11 @@ menuconfig NETDEV_10000 bool "Ethernet (10000 Mbit)" depends on !UML default y + ---help--- + Say Y here to get to see options for 10 Gigabit Ethernet drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if NETDEV_10000 diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7dd73546bf43..63436892688c 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -6,6 +6,9 @@ menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y + ---help--- + This option adds core support for Universal Serial Bus (USB). + You will also need drivers from the following menu to make use of it. if USB_SUPPORT -- cgit v1.2.3 From 1a2b73302aacddf2543f9d7a25936e4323fa1486 Mon Sep 17 00:00:00 2001 From: Timo Jantunen Date: Tue, 14 Aug 2007 21:56:57 +0300 Subject: fix random hang in forcedeth driver when using netconsole If the forcedeth driver receives too much work in an interrupt, it assumes it has a broken hardware with stuck IRQ. It works around the problem by disabling interrupts on the nic but makes a printk while holding device spinlog - which isn't smart thing to do if you have netconsole on the same nic. This patch moves the printk's out of the spinlock protected area. Without this patch the machine hangs hard. With this patch everything still works even when there is significant increase on CPU usage while using the nic. Signed-off-by: Timo Jantunen Signed-off-by: Linus Torvalds --- drivers/net/forcedeth.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 69f5f365239a..10f4e3b55168 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3068,8 +3068,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3186,8 +3186,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3233,8 +3233,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_TX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); break; } @@ -3348,8 +3348,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_RX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); break; } } @@ -3421,8 +3421,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_OTHER; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); break; } -- cgit v1.2.3 From 6ec8a856e4097d42ece9b0b9459bbca1586f13d7 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 19 Aug 2007 15:57:26 +0300 Subject: KVM: Avoid calling smp_call_function_single() with interrupts disabled When taking a cpu down, we need to hardware_disable() it. Unfortunately, the CPU_DYING notifier is called with interrupts disabled, which means we can't use smp_call_function_single(). Fortunately, the CPU_DYING notifier is always called on the dying cpu, so we don't need to use the function at all and can simply call hardware_disable() directly. Tested-by: Paolo Ornati Signed-off-by: Avi Kivity Signed-off-by: Linus Torvalds --- drivers/kvm/kvm_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 96856097d15b..cd0557954e50 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -2974,6 +2974,10 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, switch (val) { case CPU_DYING: case CPU_DYING_FROZEN: + printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + cpu); + hardware_disable(NULL); + break; case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", -- cgit v1.2.3 From c3624f99a8c06cfe75e0b06f23a7f7cea9d2d5ff Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 31 Jul 2007 07:15:56 -0300 Subject: V4L/DVB (5967): ivtv: fix VIDIOC_S_FBUF:new OSD values where never set ivtv: fix VIDIOC_S_FBUF support: new OSD values where never actually set. The values set with VIDIOC_S_FBUF were not actually used until the next VIDIOC_S_FMT. Fixed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 047624b9e271..f2310b775fad 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1190,6 +1190,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; + ivtv_set_osd_alpha(itv); break; } -- cgit v1.2.3 From de23084a85f6f5030e6760f6e494a9f2a19013d4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 3 Aug 2007 09:33:38 -0300 Subject: V4L/DVB (5969): ivtv: report ivtv version in status log Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f2310b775fad..5977a79619c2 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1235,7 +1235,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void IVTV_INFO("Tuner: %s\n", test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&itv->params, itv->name); - IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); + IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags); for (i = 0; i < IVTV_MAX_STREAMS; i++) { struct ivtv_stream *s = &itv->streams[i]; -- cgit v1.2.3 From 0d84a62b38bab2e15ddc44ea6dcd8ce49199b299 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Fri, 17 Aug 2007 18:36:44 -0300 Subject: V4L/DVB (5991): dvb-pll: Set minimum and maximum frequency properly The tuner maximum frequency wasn't being set, while the minimum frequency was set to what the maximum should have been. If a future patch were to enforce these limits, dvb-pll would be effectively broken. Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dvb-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index ca99e439c97c..11f7d5939bd9 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -784,7 +784,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, strncpy(fe->ops.tuner_ops.info.name, desc->name, sizeof(fe->ops.tuner_ops.info.name)); fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_min = desc->max; + fe->ops.tuner_ops.info.frequency_max = desc->max; if (!desc->initdata) fe->ops.tuner_ops.init = NULL; if (!desc->sleepdata) -- cgit v1.2.3 From 01659f2a0067d855089811529fa596cbc40f1e75 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 17 Aug 2007 01:01:33 -0300 Subject: V4L/DVB (6026): Avoid powering up the camera on resume Signed-off-by: Chris Ball Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index c08f650df423..88090107cd44 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2233,12 +2233,21 @@ static int cafe_pci_resume(struct pci_dev *pdev) if (ret) return ret; ret = pci_enable_device(pdev); + if (ret) { cam_warn(cam, "Unable to re-enable device on resume!\n"); return ret; } cafe_ctlr_init(cam); - cafe_ctlr_power_up(cam); + cafe_ctlr_power_down(cam); + + mutex_lock(&cam->s_mutex); + if (cam->users > 0) { + cafe_ctlr_power_up(cam); + __cafe_cam_reset(cam); + } + mutex_unlock(&cam->s_mutex); + set_bit(CF_CONFIG_NEEDED, &cam->flags); if (cam->state == S_SPECREAD) cam->state = S_IDLE; /* Don't bother restarting */ -- cgit v1.2.3 From 6d77444aca298b43a88086be446f943cd0442ef7 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 17 Aug 2007 01:02:33 -0300 Subject: V4L/DVB (6027): Get rid of an ill-behaved msleep in i2c write Configuring the OLPC camera requires something over 150 register writes. Unfortunately, querying the CAFE i2c controller too soon after a write causes the hardware to flake. The problem had been "solved" with an msleep() call, but, between the number of registers and how msleep() behaves, that resulted in a 3-second delay on camera initialization. Instead, we hand-code a wait for the completion interrupt which avoids reading the status registers. Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 22 +++++++++++++++++++++- drivers/media/video/ov7670.c | 5 ++++- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 88090107cd44..acf64b19730e 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -356,6 +356,7 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, { unsigned int rval; unsigned long flags; + DEFINE_WAIT(the_wait); spin_lock_irqsave(&cam->dev_lock, flags); rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); @@ -369,10 +370,29 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); cafe_reg_write(cam, REG_TWSIC1, rval); spin_unlock_irqrestore(&cam->dev_lock, flags); - msleep(2); /* Required or things flake */ + /* + * Time to wait for the write to complete. THIS IS A RACY + * WAY TO DO IT, but the sad fact is that reading the TWSIC1 + * register too quickly after starting the operation sends + * the device into a place that may be kinder and better, but + * which is absolutely useless for controlling the sensor. In + * practice we have plenty of time to get into our sleep state + * before the interrupt hits, and the worst case is that we + * time out and then see that things completed, so this seems + * the best way for now. + */ + do { + prepare_to_wait(&cam->smbus_wait, &the_wait, + TASK_UNINTERRUPTIBLE); + schedule_timeout(1); /* even 1 jiffy is too long */ + finish_wait(&cam->smbus_wait, &the_wait); + } while (!cafe_smbus_write_done(cam)); + +#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam), CAFE_SMBUS_TIMEOUT); +#endif spin_lock_irqsave(&cam->dev_lock, flags); rval = cafe_reg_read(cam, REG_TWSIC1); spin_unlock_irqrestore(&cam->dev_lock, flags); diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index f8f21ddd9843..c4c5bd67f795 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -416,7 +416,10 @@ static int ov7670_read(struct i2c_client *c, unsigned char reg, static int ov7670_write(struct i2c_client *c, unsigned char reg, unsigned char value) { - return i2c_smbus_write_byte_data(c, reg, value); + int ret = i2c_smbus_write_byte_data(c, reg, value); + if (reg == REG_COM7 && (value & COM7_RESET)) + msleep(2); /* Wait for reset to run */ + return ret; } -- cgit v1.2.3 From 70cd685d4b161c9137020ba7ec551cb343cd6fbf Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 17 Aug 2007 01:03:22 -0300 Subject: V4L/DVB (6028): Turn an unnecessary mdelay() into msleep(). Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index acf64b19730e..ef5361824f87 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -730,7 +730,7 @@ static void cafe_ctlr_init(struct cafe_camera *cam) * Here we must wait a bit for the controller to come around. */ spin_unlock_irqrestore(&cam->dev_lock, flags); - mdelay(5); /* FIXME revisit this */ + msleep(5); spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); -- cgit v1.2.3 From 82a0e70e795ee605e1a34a874dd3a3a43b745fb9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 20 Aug 2007 22:42:53 +0200 Subject: ide: make CONFIG_IDE_GENERIC default to N These days, CONFIG_IDE_GENERIC causes more confusion and misconfiguration than it helps. Especially so because libata is linked after the generic driver. Default to N. Signed-off-by: Tejun Heo Acked-by: Jeff Garzik Cc: "P.C.Chan" Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e049f65bc3a2..e7fcdd2580fb 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,9 +304,8 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" - default y help - If unsure, say Y. + If unsure, say N. config BLK_DEV_CMD640 bool "CMD640 chipset bugfix/support" -- cgit v1.2.3 From 2195dadf853bb32262bd2e5a64f517ae45698c55 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:54 +0200 Subject: ide: fix hidden dependencies on CONFIG_IDE_GENERIC Some host drivers depend on CONFIG_IDE_GENERIC to do the probing but their config options lack explicit dependencies on IDE_GENERIC. In the long-term these host drivers should be fixed to do the probing themselves but for now fix them by making their config options select CONFIG_IDE_GENERIC. Signed-off-by: Bartlomiej Zolnierkiewicz --- arch/cris/arch-v10/drivers/Kconfig | 1 + arch/cris/arch-v32/drivers/Kconfig | 1 + drivers/ide/Kconfig | 9 +++++++++ 3 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index e7e724bc0ba6..03e2e68f947d 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -548,6 +548,7 @@ config ETRAX_IDE select BLK_DEV_IDEDISK select BLK_DEV_IDECD select BLK_DEV_IDEDMA + select IDE_GENERIC help Enable this to get support for ATA/IDE. You can't use parallel ports or SCSI ports diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index 1d859c16931e..cc6ba5423754 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -592,6 +592,7 @@ config ETRAX_IDE select BLK_DEV_IDEDISK select BLK_DEV_IDECD select BLK_DEV_IDEDMA + select IDE_GENERIC help Enables the ETRAX IDE driver. diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e7fcdd2580fb..7adb61bad6ad 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,6 +304,7 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" + default H8300 help If unsure, say N. @@ -344,6 +345,7 @@ config BLK_DEV_CMD640_ENHANCED config BLK_DEV_IDEPNP bool "PNP EIDE support" depends on PNP + select IDE_GENERIC help If you have a PnP (Plug and Play) compatible EIDE card and would like the kernel to automatically detect and activate @@ -833,6 +835,7 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ config IDE_ARM def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) + select IDE_GENERIC config BLK_DEV_IDE_ICSIDE tristate "ICS IDE interface support" @@ -866,6 +869,7 @@ config BLK_DEV_IDE_BAST config BLK_DEV_GAYLE bool "Amiga Gayle IDE interface support" depends on AMIGA + select IDE_GENERIC help This is the IDE driver for the Amiga Gayle IDE interface. It supports both the `A1200 style' and `A4000 style' of the Gayle IDE interface, @@ -897,6 +901,7 @@ config BLK_DEV_IDEDOUBLER config BLK_DEV_BUDDHA bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" depends on ZORRO && EXPERIMENTAL + select IDE_GENERIC help This is the IDE driver for the IDE interfaces on the Buddha, Catweasel and X-Surf expansion boards. It supports up to two interfaces @@ -909,6 +914,7 @@ config BLK_DEV_BUDDHA config BLK_DEV_FALCON_IDE bool "Falcon IDE interface support" depends on ATARI + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on the Atari Falcon. Say Y if you have a Falcon and want to use IDE devices (hard @@ -918,6 +924,7 @@ config BLK_DEV_FALCON_IDE config BLK_DEV_MAC_IDE bool "Macintosh Quadra/Powerbook IDE interface support" depends on MAC + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on some m68k Macintosh models. It supports both the `Quadra style' (used in @@ -931,6 +938,7 @@ config BLK_DEV_MAC_IDE config BLK_DEV_Q40IDE bool "Q40/Q60 IDE interface support" depends on Q40 + select IDE_GENERIC help Enable the on-board IDE controller in the Q40/Q60. This should normally be on; disable it only if you are running a custom hard @@ -939,6 +947,7 @@ config BLK_DEV_Q40IDE config BLK_DEV_MPC8xx_IDE bool "MPC8xx IDE support" depends on 8xx && IDE=y && BLK_DEV_IDE=y + select IDE_GENERIC help This option provides support for IDE on Motorola MPC8xx Systems. Please see 'Type of MPC8xx IDE interface' for details. -- cgit v1.2.3 From 8292e8c7e4c2b99f22120f677858487de43c484b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:54 +0200 Subject: ide-cris: fix ->set_pio_mode method to set transfer mode on the device Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cris/ide-cris.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index fbfea46a34f2..04636f7eaae7 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -718,6 +718,8 @@ static void tune_cris_ide(ide_drive_t *drive, u8 pio) } cris_ide_set_speed(TYPE_PIO, setup, strobe, hold); + + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } static int speed_cris_ide(ide_drive_t *drive, u8 speed) -- cgit v1.2.3 From 1116fae5fdfa80c6744a9b5d75fb3ef687a69b19 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:55 +0200 Subject: ide: config_drive_for_dma() fixes * Add DMA blacklist checking (->ide_dma_on check probably can go now). * Add ->atapi_dma flag checking and remove no longer needed ns87415_ide_dma_check() from ns87415 host driver. * Remove now needless __ide_dma_check() wrapper and symbol export. * Check drive->autodma instead of hwif->autodma (there should be no changes in behavior as all users of config_drive_for_dma() set both ->autodma flags). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 26 ++++++++++---------------- drivers/ide/pci/ns87415.c | 9 --------- include/linux/ide.h | 1 - 3 files changed, 10 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 5fe1d72ab451..865a2740a6e3 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -349,9 +349,17 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable); static int config_drive_for_dma (ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; - if ((id->capability & 1) && drive->hwif->autodma) { + /* consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + return -1; + + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return -1; + + if ((id->capability & 1) && drive->autodma) { /* * Enable DMA on any drive that has * UltraDMA (mode 0/1/2/3/4/5/6) enabled @@ -513,20 +521,6 @@ int __ide_dma_on (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_on); -/** - * __ide_dma_check - check DMA setup - * @drive: drive to check - * - * Don't use - due for extermination - */ - -int __ide_dma_check (ide_drive_t *drive) -{ - return config_drive_for_dma(drive); -} - -EXPORT_SYMBOL(__ide_dma_check); - /** * ide_dma_setup - begin a DMA phase * @drive: target device @@ -1021,7 +1015,7 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p if (!hwif->dma_host_on) hwif->dma_host_on = &ide_dma_host_on; if (!hwif->ide_dma_check) - hwif->ide_dma_check = &__ide_dma_check; + hwif->ide_dma_check = &config_drive_for_dma; if (!hwif->dma_setup) hwif->dma_setup = &ide_dma_setup; if (!hwif->dma_exec_cmd) diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 09941f37d635..465c935fdf25 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -187,14 +187,6 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive) return 1; } -static int ns87415_ide_dma_check (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return -1; - - return __ide_dma_check(drive); -} - static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -266,7 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) outb(0x60, hwif->dma_status); hwif->dma_setup = &ns87415_ide_dma_setup; - hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_end = &ns87415_ide_dma_end; if (!noautodma) diff --git a/include/linux/ide.h b/include/linux/ide.h index d71d0121b7f9..7e15e0870290 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1312,7 +1312,6 @@ void ide_dma_host_off(ide_drive_t *); void ide_dma_off_quietly(ide_drive_t *); void ide_dma_host_on(ide_drive_t *); extern int __ide_dma_on(ide_drive_t *); -extern int __ide_dma_check(ide_drive_t *); extern int ide_dma_setup(ide_drive_t *); extern void ide_dma_start(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *); -- cgit v1.2.3 From 59785c8fe23ca2f432bc41ef473a8933ab435812 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:55 +0200 Subject: ide-pmac: fix drive->init_speed reporting pmac_ide_tune_chipset() don't set drive->init_speed. Fix it by setting drive->{current,init}_speed in pmac_ide_do_setfeature() and clean up pmac_ide_{tune_chipset,mdma_enable,udma_enable}(). Acked-by: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 33630ad3e794..4b13cd9a027d 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -604,6 +604,9 @@ out: drive->id->dma_1word |= 0x0101; break; default: break; } + if (!drive->init_speed) + drive->init_speed = command; + drive->current_speed = command; } enable_irq(hwif->irq); return result; @@ -986,7 +989,6 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) return ret; pmac_ide_do_update_timings(drive); - drive->current_speed = speed; return 0; } @@ -1737,11 +1739,6 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) /* Apply timings to controller */ *timings = timing_local[0]; *timings2 = timing_local[1]; - - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; return 1; } @@ -1793,11 +1790,6 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) *timings = timing_local[0]; *timings2 = timing_local[1]; - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; - return 1; } -- cgit v1.2.3 From a5b7e70d787f528386eda025d3e38f545017f241 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: ide: add cable detection for early UDMA66 devices (take 3) * Move ide_in_drive_list() from ide-dma.c to ide-iops.c. * Add ivb_list[] table for listening early UDMA66 devices which don't conform to ATA4 standard wrt cable detection (bit14 is zero, only bit13 is valid) and use only device side cable detection for them since host side cable detection may be unreliable. * Add model "QUANTUM FIREBALLlct10 05" with firwmare "A03.0900" to the list (from Craig's bugreport). v2: * Improve kernel message basing on suggestion from Sergei. v3: * Don't print kernel message when no device side cable detection is done, plus some minor fixes. (Noticed by Sergei) Thanks to Craig for testing this patch. Cc: Craig Block Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 19 ------------------- drivers/ide/ide-iops.c | 39 ++++++++++++++++++++++++++++++++++++--- include/linux/ide.h | 3 ++- 3 files changed, 38 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 865a2740a6e3..ff644a5e12cd 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -134,25 +134,6 @@ static const struct drive_list_entry drive_blacklist [] = { }; -/** - * ide_in_drive_list - look for drive in black/white list - * @id: drive identifier - * @drive_table: list to inspect - * - * Look for a drive in the blacklist and the whitelist tables - * Returns 1 if the drive is found in the table. - */ - -int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) -{ - for ( ; drive_table->id_model ; drive_table++) - if ((!strcmp(drive_table->id_model, id->model)) && - (!drive_table->id_firmware || - strstr(id->fw_rev, drive_table->id_firmware))) - return 1; - return 0; -} - /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 92578b6832e9..fe2a69fed72b 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -565,6 +565,34 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b EXPORT_SYMBOL(ide_wait_stat); +/** + * ide_in_drive_list - look for drive in black/white list + * @id: drive identifier + * @drive_table: list to inspect + * + * Look for a drive in the blacklist and the whitelist tables + * Returns 1 if the drive is found in the table. + */ + +int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) +{ + for ( ; drive_table->id_model; drive_table++) + if ((!strcmp(drive_table->id_model, id->model)) && + (!drive_table->id_firmware || + strstr(id->fw_rev, drive_table->id_firmware))) + return 1; + return 0; +} + +/* + * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. + * We list them here and depend on the device side cable detection for them. + */ +static const struct drive_list_entry ivb_list[] = { + { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, + { NULL , NULL } +}; + /* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. @@ -573,11 +601,16 @@ u8 eighty_ninty_three (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; + int ivb = ide_in_drive_list(id, ivb_list); if (hwif->cbl == ATA_CBL_PATA40_SHORT) return 1; - if (hwif->cbl != ATA_CBL_PATA80) + if (ivb) + printk(KERN_DEBUG "%s: skipping word 93 validity check\n", + drive->name); + + if (hwif->cbl != ATA_CBL_PATA80 && !ivb) goto no_80w; /* Check for SATA but only if we are ATA5 or higher */ @@ -587,11 +620,11 @@ u8 eighty_ninty_three (ide_drive_t *drive) /* * FIXME: * - change master/slave IDENTIFY order - * - force bit13 (80c cable present) check + * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ #ifndef CONFIG_IDEDMA_IVB - if (id->hw_config & 0x4000) + if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) #else if (id->hw_config & 0x6000) #endif diff --git a/include/linux/ide.h b/include/linux/ide.h index 7e15e0870290..c792b4fd1588 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1285,13 +1285,14 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *); #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 -#ifdef CONFIG_BLK_DEV_IDEDMA struct drive_list_entry { const char *id_model; const char *id_firmware; }; int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); + +#ifdef CONFIG_BLK_DEV_IDEDMA int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); u8 ide_max_dma_mode(ide_drive_t *); -- cgit v1.2.3 From adcd33d41bfea8fb6870cf1f7e7ed2e5f7323fc1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: ide: ide_config_drive_speed() bugfixes * Use ->OUTBSYNC instead of ->OUTB when writing command register (needed for scc_pata and pmac host drivers). * Don't check DRDY bit of the status register on ATAPI devices (ATAPI devices are free to ignore DRDY bit). Cc: Benjamin Herrenschmidt Cc: Kou Ishizaki Cc: Akira Iguchi Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fe2a69fed72b..18cf3a66a1a3 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -828,7 +828,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); udelay(1); @@ -855,7 +855,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) */ for (i = 0; i < 10; i++) { udelay(1); - if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { + if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) { error = 0; break; } -- cgit v1.2.3 From f7b0d2df2f6fd9abdf47b4a1965dcaa2870e35df Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: cs5530: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Also this host driver requires valid PCI BAR4 for normal operation so check it in ->init_chipset and fail initialization if not set. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5530.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index acaf71fd4c09..e5949b1d3fb0 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 + * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007 * * Copyright (C) 2000 Andre Hedrick * Copyright (C) 2000 Mark Lord @@ -207,6 +207,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; + if (pci_resource_start(dev, 4) == 0) + return -EFAULT; + dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { @@ -325,6 +328,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) /* needs autotuning later */ } + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; -- cgit v1.2.3 From 01cc643ae3c7de35b63989b7b65e3ef3132e48e4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: pdc202xx_new: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Also this host driver requires valid PCI BAR4 for normal operation so check it in ->init_chipset and fail initialization if not set. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_new.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 8a66a2871b3a..f6db2f37efad 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -378,6 +378,9 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha int f, r; u8 pll_ctl0, pll_ctl1; + if (dma_base == 0) + return -EFAULT; + #ifdef CONFIG_PPC_PMAC apple_kiwi_init(dev); #endif @@ -494,15 +497,18 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->speedproc = &pdcnew_tune_chipset; hwif->resetproc = &pdcnew_reset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; if (hwif->cbl != ATA_CBL_PATA40_SHORT) -- cgit v1.2.3 From e98d6e50be87c1ad2df81f73c7442cf631d6f931 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: pdc202xx_old: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_old.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index fbcb0bb9c956..e19a891171cb 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007 * * Copyright (C) 1998-2002 Andre Hedrick * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -337,15 +337,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->speedproc = &pdc202xx_tune_chipset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; hwif->atapi_dma = 1; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->dma_timeout = &pdc202xx_dma_timeout; -- cgit v1.2.3 From 88b47040f8365ad56ecfd4103e964ba9b695987e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: triflex: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/triflex.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 024bbfae0429..098692a6d615 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -115,6 +115,9 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif) hwif->tuneproc = &triflex_tune_drive; hwif->speedproc = &triflex_tune_chipset; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; -- cgit v1.2.3 From 76e1faa7cfd464fa06a9c2cafd633d643daafeae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:57 +0200 Subject: hpt34x: fix CONFIG_HPT34X_AUTODMA=n handling Programming DMA mode may destroy current PIO mode setting so if CONFIG_HPT34X_AUTODMA=n (the default case) make ide_tune_dma() fail early by disabling all host DMA masks and re-tune PIO mode. This fix doesn't help with the driver being broken but is needed for some other changes. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt34x.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 19778c5fe711..cb8fe5643d3b 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -89,11 +89,7 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; if (ide_tune_dma(drive)) -#ifndef CONFIG_HPT34X_AUTODMA return -1; -#else - return 0; -#endif if (ide_use_fast_pio(drive)) hpt34x_tune_drive(drive, 255); @@ -160,9 +156,11 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) if (!hwif->dma_base) return; +#ifdef CONFIG_HPT34X_AUTODMA hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; +#endif hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate; if (!noautodma) -- cgit v1.2.3 From b0244a00451c1ad64bf0a51f50679f7146786780 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:57 +0200 Subject: ide-disk: workaround for buggy HPA support on ST340823A (take 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This disk reports total number of sectors instead of maximum sector address in response to READ_NATIVE_MAX_ADDRESS command and also happily accepts SET_MAX_ADDRESS command with the bogus value. This results in +1 sector capacity being used and errors on attempts to use the last sector. ... hdd: Host Protected Area detected.         current capacity is 78165360 sectors (40020 MB)         native  capacity is 78165361 sectors (40020 MB) hdd: Host Protected Area disabled. ... hdd: reading: block=78165360, sectors=1, buffer=0xc1e63000 hdd: dma_intr: status=0x51 { DriveReady SeekComplete Error } hdd: dma_intr: error=0x10 { SectorIdNotFound }, LBAsect=78165360, sector=78165360 ... Add hpa_list[] table and workaround the issue in idedisk_check_hpa(). v2: * Add missing export and improve patch description a bit. v3: * Add list termination. (From Mikko) Fixes kernel bugzilla bug #8816. Thanks to Mikko for investigating the issue and helping with this patch. Cc: Mikko Rapeli Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-disk.c | 18 ++++++++++++++++++ drivers/ide/ide-iops.c | 2 ++ 2 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5ce4216f72a2..eba1adbc1b6a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -481,6 +481,15 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) && id->lba_capacity_2; } +/* + * Some disks report total number of sectors instead of + * maximum sector address. We list them here. + */ +static const struct drive_list_entry hpa_list[] = { + { "ST340823A", NULL }, + { NULL, NULL } +}; + static void idedisk_check_hpa(ide_drive_t *drive) { unsigned long long capacity, set_max; @@ -492,6 +501,15 @@ static void idedisk_check_hpa(ide_drive_t *drive) else set_max = idedisk_read_native_max_address(drive); + if (ide_in_drive_list(drive->id, hpa_list)) { + /* + * Since we are inclusive wrt to firmware revisions do this + * extra check and apply the workaround only when needed. + */ + if (set_max == capacity + 1) + set_max--; + } + if (set_max <= capacity) return; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 18cf3a66a1a3..f4cd2700cae5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -584,6 +584,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv return 0; } +EXPORT_SYMBOL_GPL(ide_in_drive_list); + /* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. * We list them here and depend on the device side cable detection for them. -- cgit v1.2.3 From 8eb891fc809b2300137bcd247025628c06c95a63 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 20 Aug 2007 23:38:44 -0700 Subject: Revert "USB: EHCI cpufreq fix" This reverts commit 196705c9bbc03540429b0f7cf9ee35c2f928a534. It was reported to cause a regression by Daniel Exner, and Arjan van de Ven points out that we actually already have infrastructure in place for setting limits on acceptable DMA latency that would be the much more correct fix for the problem with some Broadcom EHCI controllers. Fixed up trivial conflicts due to the changes to support big-endian host controller descriptors in drivers/usb/host/{ehci-sched.c,ehci.h}. Signed-off-by: Linus Torvalds --- drivers/usb/host/ehci-hcd.c | 67 ---------------------- drivers/usb/host/ehci-mem.c | 3 - drivers/usb/host/ehci-q.c | 4 -- drivers/usb/host/ehci-sched.c | 127 ------------------------------------------ drivers/usb/host/ehci.h | 14 ----- 5 files changed, 215 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c4e15ed1405a..35cdba10411b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -275,58 +275,6 @@ static void ehci_work(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_CPU_FREQ - -#include - -static void ehci_cpufreq_pause (struct ehci_hcd *ehci) -{ - unsigned long flags; - - spin_lock_irqsave(&ehci->lock, flags); - if (!ehci->cpufreq_changing++) - qh_inactivate_split_intr_qhs(ehci); - spin_unlock_irqrestore(&ehci->lock, flags); -} - -static void ehci_cpufreq_unpause (struct ehci_hcd *ehci) -{ - unsigned long flags; - - spin_lock_irqsave(&ehci->lock, flags); - if (!--ehci->cpufreq_changing) - qh_reactivate_split_intr_qhs(ehci); - spin_unlock_irqrestore(&ehci->lock, flags); -} - -/* - * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when - * EHCI controllers that don't cache many uframes get delayed trying to - * read main memory during CPU frequency transitions. This can cause - * split interrupt transactions to not be completed in the required uframe. - * This has been observed on the Broadcom/ServerWorks HT1000 controller. - */ -static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd, - cpufreq_transition); - - switch (val) { - case CPUFREQ_PRECHANGE: - ehci_cpufreq_pause(ehci); - break; - case CPUFREQ_POSTCHANGE: - ehci_cpufreq_unpause(ehci); - break; - } - return 0; -} - -#endif - -/*-------------------------------------------------------------------------*/ - static void ehci_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; @@ -460,10 +408,6 @@ static void ehci_stop (struct usb_hcd *hcd) ehci_writel(ehci, 0, &ehci->regs->intr_enable); spin_unlock_irq(&ehci->lock); -#ifdef CONFIG_CPU_FREQ - cpufreq_unregister_notifier(&ehci->cpufreq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif /* let companion controllers work when we aren't */ ehci_writel(ehci, 0, &ehci->regs->configured_flag); @@ -569,17 +513,6 @@ static int ehci_init(struct usb_hcd *hcd) } ehci->command = temp; -#ifdef CONFIG_CPU_FREQ - INIT_LIST_HEAD(&ehci->split_intr_qhs); - /* - * If the EHCI controller caches enough uframes, this probably - * isn't needed unless there are so many low/full speed devices - * that the controller's can't cache it all. - */ - ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier; - cpufreq_register_notifier(&ehci->cpufreq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif return 0; } diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 8816d09903d0..0431397836f6 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -94,9 +94,6 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); -#ifdef CONFIG_CPU_FREQ - INIT_LIST_HEAD (&qh->split_intr_qhs); -#endif /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 2284028f8aa5..140bfa423e07 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -312,10 +312,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) struct urb *urb; u32 token = 0; - /* ignore QHs that are currently inactive */ - if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE)) - break; - qtd = list_entry (entry, struct ehci_qtd, qtd_list); urb = qtd->urb; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d4a8ace49676..e682f2342ef8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -479,109 +479,6 @@ static int disable_periodic (struct ehci_hcd *ehci) } /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_CPU_FREQ - -static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh) -{ - int now; /* current (frame * 8) + uframe */ - int prev_start, next_start; /* uframes from/to split start */ - int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK); - int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8); - int split_duration = end_uframe - start_uframe; - - now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3); - - next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) - % (qh->period << 3); - prev_start = (qh->period << 3) - next_start; - - /* - * Make sure there will be at least one uframe when qh is safe. - */ - if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration)) - /* never safe */ - return -EINVAL; - - /* - * Wait 1 uframe after transaction should have started, to make - * sure controller has time to write back overlay, so we can - * check QTD_STS_STS to see if transaction is in progress. - */ - if ((next_start > ehci->i_thresh) && (prev_start > 1)) - /* safe to set "i" bit if split isn't in progress */ - return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1; - else - return 0; -} - -/* Set inactivate bit for all the split interrupt QHs. */ -static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - int not_done, safe; - u32 inactivate = INACTIVATE_BIT(ehci); - u32 active = ACTIVE_BIT(ehci); - - do { - not_done = 0; - list_for_each_entry(qh, &ehci->split_intr_qhs, - split_intr_qhs) { - if (qh->hw_info1 & inactivate) - /* already off */ - continue; - /* - * To avoid setting "I" after the start split happens, - * don't set it if the QH might be cached in the - * controller. Some HCs (Broadcom/ServerWorks HT1000) - * will stop in the middle of a split transaction when - * the "I" bit is set. - */ - safe = safe_to_modify_i(ehci, qh); - if (safe == 0) { - not_done = 1; - } else if (safe > 0) { - qh->was_active = qh->hw_token & active; - qh->hw_info1 |= inactivate; - } - } - } while (not_done); - wmb(); -} - -static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - u32 token; - int not_done, safe; - u32 inactivate = INACTIVATE_BIT(ehci); - u32 active = ACTIVE_BIT(ehci); - u32 halt = HALT_BIT(ehci); - - do { - not_done = 0; - list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) { - if (!(qh->hw_info1 & inactivate)) /* already on */ - continue; - /* - * Don't reactivate if cached, or controller might - * overwrite overlay after we modify it! - */ - safe = safe_to_modify_i(ehci, qh); - if (safe == 0) { - not_done = 1; - } else if (safe > 0) { - /* See EHCI 1.0 section 4.15.2.4. */ - token = qh->hw_token; - qh->hw_token = (token | halt) & ~active; - wmb(); - qh->hw_info1 &= ~inactivate; - wmb(); - qh->hw_token = (token & ~halt) | qh->was_active; - } - } - } while (not_done); -} -#endif /* periodic schedule slots have iso tds (normal or split) first, then a * sparse tree for active interrupt transfers. @@ -599,17 +496,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs); -#ifdef CONFIG_CPU_FREQ - /* - * If low/full speed interrupt QHs are inactive (because of - * cpufreq changing processor speeds), start QH with I flag set-- - * it will automatically be cleared when cpufreq is done. - */ - if (ehci->cpufreq_changing) - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) - qh->hw_info1 |= INACTIVATE_BIT(ehci); -#endif - /* high bandwidth, or otherwise every microframe */ if (period == 0) period = 1; @@ -658,12 +544,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) ? ((qh->usecs + qh->c_usecs) / qh->period) : (qh->usecs * 8); -#ifdef CONFIG_CPU_FREQ - /* add qh to list of low/full speed interrupt QHs, if applicable */ - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { - list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs); - } -#endif /* maybe enable periodic schedule processing */ if (!ehci->periodic_sched++) return enable_periodic (ehci); @@ -683,13 +563,6 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) // THEN // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); -#ifdef CONFIG_CPU_FREQ - /* remove qh from list of low/full speed interrupt QHs */ - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { - list_del_init(&qh->split_intr_qhs); - } -#endif - /* high bandwidth, or otherwise part of every microframe */ if ((period = qh->period) == 0) period = 1; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2c68a04230c1..951d69fec513 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -71,12 +71,6 @@ struct ehci_hcd { /* one per controller */ __u32 hcs_params; /* cached register copy */ spinlock_t lock; -#ifdef CONFIG_CPU_FREQ - struct notifier_block cpufreq_transition; - int cpufreq_changing; - struct list_head split_intr_qhs; -#endif - /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; @@ -439,10 +433,6 @@ struct ehci_qh { __hc32 hw_next; /* see EHCI 3.6.1 */ __hc32 hw_info1; /* see EHCI 3.6.2 */ #define QH_HEAD 0x00008000 -#define QH_INACTIVATE 0x00000080 - -#define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE) - __hc32 hw_info2; /* see EHCI 3.6.2 */ #define QH_SMASK 0x000000ff #define QH_CMASK 0x0000ff00 @@ -492,10 +482,6 @@ struct ehci_qh { unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ struct usb_device *dev; /* access to TT */ -#ifdef CONFIG_CPU_FREQ - struct list_head split_intr_qhs; /* list of split qhs */ - __le32 was_active; /* active bit before "i" set */ -#endif } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From d6c59c13c070cb9d043edf38b4639fdacdb0c18c Mon Sep 17 00:00:00 2001 From: Martin Bachem Date: Tue, 21 Aug 2007 14:26:21 +0200 Subject: hisax: update hfc_usb driver This fixes handling of USB ISO completion error -EXDEV and includes several other changes to current CVS version at isdn4linux.de (changes in debug flags, style of code remarks, etc) Signed-off-by: Martin Bachem Acked-by: Karsten Keil Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/hfc_usb.c | 603 +++++++++++++++++-------------------------- drivers/isdn/hisax/hfc_usb.h | 130 ++++------ 2 files changed, 288 insertions(+), 445 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index b1a26e02df02..60843b3f3b6f 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1,12 +1,12 @@ /* * hfc_usb.c * - * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ + * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $ * * modular HiSax ISDN driver for Colognechip HFC-S USB chip * - * Authors : Peter Sprenger (sprenger@moving-bytes.de) - * Martin Bachem (info@colognechip.com) + * Authors : Peter Sprenger (sprenger@moving-bytes.de) + * Martin Bachem (m.bachem@gmx.de, info@colognechip.com) * * based on the first hfc_usb driver of * Werner Cornelius (werner@isdn-development.de) @@ -37,24 +37,25 @@ #include #include #include +#include +#include +#include #include "hisax.h" #include "hisax_if.h" #include "hfc_usb.h" static const char *hfcusb_revision = - "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; + "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ "; /* Hisax debug support -* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG +* debug flags defined in hfc_usb.h as HFCUSB_DBG_[*] */ -#ifdef CONFIG_HISAX_DEBUG -#include #define __debug_variable hfc_debug #include "hisax_debug.h" static u_int debug; module_param(debug, uint, 0); static int hfc_debug; -#endif + /* private vendor specific data */ typedef struct { @@ -63,9 +64,7 @@ typedef struct { char *vend_name; // device name } hfcsusb_vdata; -/****************************************/ -/* data defining the devices to be used */ -/****************************************/ +/* VID/PID device list */ static struct usb_device_id hfcusb_idtab[] = { { USB_DEVICE(0x0959, 0x2bd0), @@ -90,49 +89,47 @@ static struct usb_device_id hfcusb_idtab[] = { .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Stollmann USB TA"}), - }, + }, { USB_DEVICE(0x0742, 0x2009), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Aceex USB ISDN TA"}), - }, + }, { USB_DEVICE(0x0742, 0x200A), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "OEM USB ISDN TA"}), - }, + }, { USB_DEVICE(0x08e3, 0x0301), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {2, 0, 1, 4}, "Olitec USB RNIS"}), - }, + }, { USB_DEVICE(0x07fa, 0x0846), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Bewan Modem RNIS USB"}), - }, + }, { USB_DEVICE(0x07fa, 0x0847), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Djinn Numeris USB"}), - }, + }, { USB_DEVICE(0x07b0, 0x0006), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Twister ISDN TA"}), - }, + }, { } }; -/***************************************************************/ /* structure defining input+output fifos (interrupt/bulk mode) */ -/***************************************************************/ struct usb_fifo; /* forward definition */ typedef struct iso_urb_struct { struct urb *purb; @@ -140,8 +137,8 @@ typedef struct iso_urb_struct { struct usb_fifo *owner_fifo; /* pointer to owner fifo */ } iso_urb_struct; - struct hfcusb_data; /* forward definition */ + typedef struct usb_fifo { int fifonum; /* fifo index attached to this structure */ int active; /* fifo is currently active */ @@ -160,15 +157,12 @@ typedef struct usb_fifo { struct hisax_if *hif; /* hisax interface */ int delete_flg; /* only delete skbuff once */ int last_urblen; /* remember length of last packet */ - } usb_fifo; -/*********************************************/ /* structure holding all data for one device */ -/*********************************************/ typedef struct hfcusb_data { /* HiSax Interface for loadable Layer1 drivers */ - struct hisax_d_if d_if; /* see hisax_if.h */ + struct hisax_d_if d_if; /* see hisax_if.h */ struct hisax_b_if b_if[2]; /* see hisax_if.h */ int protocol; @@ -176,12 +170,13 @@ typedef struct hfcusb_data { int if_used; /* used interface number */ int alt_used; /* used alternate config */ int ctrl_paksize; /* control pipe packet size */ - int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ + int ctrl_in_pipe, /* handles for control pipe */ + ctrl_out_pipe; int cfg_used; /* configuration index used */ int vend_idx; /* vendor found */ int b_mode[2]; /* B-channel mode */ int l1_activated; /* layer 1 activated */ - int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */ + int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ int packet_size, iso_packet_size; /* control pipe background handling */ @@ -208,7 +203,6 @@ typedef struct hfcusb_data { static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish); - static inline const char * symbolic(struct hfcusb_symbolic_list list[], const int num) { @@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) return ""; } - -/******************************************************/ -/* start next background transfer for control channel */ -/******************************************************/ static void ctrl_start_transfer(hfcusb_data * hfc) { @@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc) } } /* ctrl_start_transfer */ -/************************************/ -/* queue a control transfer request */ -/* return 0 on success. */ -/************************************/ static int queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) { @@ -260,19 +246,8 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) if (++hfc->ctrl_cnt == 1) ctrl_start_transfer(hfc); return (0); -} /* queue_control_request */ - -static int -control_action_handler(hfcusb_data * hfc, int reg, int val, int action) -{ - if (!action) - return (1); /* no action defined */ - return (0); } -/***************************************************************/ -/* control completion routine handling background control cmds */ -/***************************************************************/ static void ctrl_complete(struct urb *urb) { @@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb) urb->dev = hfc->dev; if (hfc->ctrl_cnt) { buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; - control_action_handler(hfc, buf->hfc_reg, buf->reg_val, - buf->action); - hfc->ctrl_cnt--; /* decrement actual count */ if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_out_idx = 0; /* pointer wrap */ @@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb) } } /* ctrl_complete */ -/***************************************************/ /* write led data to auxport & invert if necessary */ -/***************************************************/ static void write_led(hfcusb_data * hfc, __u8 led_state) { @@ -305,9 +275,6 @@ write_led(hfcusb_data * hfc, __u8 led_state) } } -/**************************/ -/* handle LED bits */ -/**************************/ static void set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) { @@ -324,9 +291,7 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) } } -/**************************/ -/* handle LED requests */ -/**************************/ +/* handle LED requests */ static void handle_led(hfcusb_data * hfc, int event) { @@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event) switch (event) { case LED_POWER_ON: - set_led_bit(hfc, driver_info->led_bits[0], - 0); - set_led_bit(hfc, driver_info->led_bits[1], - 1); - set_led_bit(hfc, driver_info->led_bits[2], - 1); - set_led_bit(hfc, driver_info->led_bits[3], - 1); + set_led_bit(hfc, driver_info->led_bits[0], 0); + set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; - case LED_POWER_OFF: /* no Power off handling */ + case LED_POWER_OFF: + set_led_bit(hfc, driver_info->led_bits[0], 1); + set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; case LED_S0_ON: - set_led_bit(hfc, driver_info->led_bits[1], - 0); + set_led_bit(hfc, driver_info->led_bits[1], 0); break; case LED_S0_OFF: - set_led_bit(hfc, driver_info->led_bits[1], - 1); + set_led_bit(hfc, driver_info->led_bits[1], 1); break; case LED_B1_ON: - set_led_bit(hfc, driver_info->led_bits[2], - 0); + set_led_bit(hfc, driver_info->led_bits[2], 0); break; case LED_B1_OFF: - set_led_bit(hfc, driver_info->led_bits[2], - 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); break; case LED_B2_ON: - set_led_bit(hfc, driver_info->led_bits[3], - 0); + set_led_bit(hfc, driver_info->led_bits[3], 0); break; case LED_B2_OFF: - set_led_bit(hfc, driver_info->led_bits[3], - 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; } write_led(hfc, hfc->led_state); } -/********************************/ -/* called when timer t3 expires */ -/********************************/ +/* ISDN l1 timer T3 expires */ static void l1_timer_expire_t3(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); -#endif - hfc->l1_activated = false; + + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); /* deactivate : */ queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); queue_control_request(hfc, HFCUSB_STATES, 3, 1); } -/********************************/ -/* called when timer t4 expires */ -/********************************/ +/* ISDN l1 timer T4 expires */ static void l1_timer_expire_t4(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); -#endif - hfc->l1_activated = false; + + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); } -/*****************************/ -/* handle S0 state changes */ -/*****************************/ +/* S0 state changed */ static void -state_handler(hfcusb_data * hfc, __u8 state) +s0_state_handler(hfcusb_data * hfc, __u8 state) { __u8 old_state; @@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state) if (state == old_state || state < 1 || state > 8) return; -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, - old_state); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)", + old_state, state); + if (state < 4 || state == 7 || state == 8) { if (timer_pending(&hfc->t3_timer)) del_timer(&hfc->t3_timer); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T3 deactivated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated"); } if (state >= 7) { if (timer_pending(&hfc->t4_timer)) del_timer(&hfc->t4_timer); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T4 deactivated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated"); } if (state == 7 && !hfc->l1_activated) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_ACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); -#endif - hfc->l1_activated = true; + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); + hfc->l1_activated = 1; handle_led(hfc, LED_S0_ON); } else if (state <= 3 /* && activated */ ) { if (old_state == 7 || old_state == 8) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T4 activated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated"); if (!timer_pending(&hfc->t4_timer)) { hfc->t4_timer.expires = jiffies + (HFC_TIMER_T4 * HZ) / 1000; @@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state) hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); -#endif - hfc->l1_activated = false; + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); } } hfc->l1_state = state; } -/* prepare iso urb */ static void fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *buf, int num_packets, int packet_size, int interval, @@ -503,15 +444,16 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, } /* allocs urbs and start isoc transfer with two pending urbs to avoid - gaps in the transfer chain */ + * gaps in the transfer chain + */ static int start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, usb_complete_t complete, int packet_size) { int i, k, errcode; - printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", - fifo->fifonum); + DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n", + fifo->fifonum); /* allocate Memory for Iso out Urbs */ for (i = 0; i < 2; i++) { @@ -556,10 +498,9 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); fifo->active = (errcode >= 0) ? 1 : 0; - if (errcode < 0) { - printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", - symbolic(urb_errlist, errcode), i); - }; + if (errcode < 0) + printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n", + i, errcode, symbolic(urb_errlist, errcode)); } return (fifo->active); } @@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo) for (i = 0; i < 2; i++) { if (fifo->iso[i].purb) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, + DBG(HFCUSB_DBG_INIT, "HFC-S USB: Stopping iso chain for fifo %i.%i", fifo->fifonum, i); -#endif usb_kill_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb); fifo->iso[i].purb = NULL; } } + usb_kill_urb(fifo->urb); usb_free_urb(fifo->urb); fifo->urb = NULL; @@ -594,9 +534,6 @@ static int iso_packets[8] = ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D }; -/*****************************************************/ -/* transmit completion routine for all ISO tx fifos */ -/*****************************************************/ static void tx_iso_complete(struct urb *urb) { @@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb) errcode; int frame_complete, transp_mode, fifon, status; __u8 threshbit; - __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; fifon = fifo->fifonum; status = urb->status; tx_offset = 0; + /* ISO transfer only partially completed, + look at individual frame status for details */ + if (status == -EXDEV) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV" + ", urb->status %d, fifonum %d\n", + status, fifon); + + for (k = 0; k < iso_packets[fifon]; ++k) { + errcode = urb->iso_frame_desc[k].status; + if (errcode) + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete " + "packet %i, status: %i\n", + k, errcode); + } + + // clear status, so go on with ISO transfers + status = 0; + } + if (fifo->active && !status) { transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = true; + transp_mode = 1; /* is FifoFull-threshold set for our channel? */ - threshbit = threshtable[fifon] & hfc->threshold_mask; + threshbit = (hfc->threshold_mask & (1 << fifon)); num_isoc_packets = iso_packets[fifon]; /* predict dataflow to avoid fifo overflow */ @@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb) tx_iso_complete, urb->context); memset(context_iso_urb->buffer, 0, sizeof(context_iso_urb->buffer)); - frame_complete = false; - /* Generate next Iso Packets */ + frame_complete = 0; + + /* Generate next ISO Packets */ for (k = 0; k < num_isoc_packets; ++k) { if (fifo->skbuff) { len = fifo->skbuff->len; @@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb) /* add 2 byte flags and 16bit CRC at end of ISDN frame */ fifo->bit_line += 32; } - frame_complete = true; + frame_complete = 1; } memcpy(context_iso_urb->buffer + @@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb) } if (frame_complete) { - fifo->delete_flg = true; + fifo->delete_flg = 1; fifo->hif->l1l2(fifo->hif, PH_DATA | CONFIRM, (void *) (unsigned long) fifo->skbuff-> @@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = false; + fifo->delete_flg = 0; } - frame_complete = false; + frame_complete = 0; } } errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d \n", + "HFC-S USB: error submitting ISO URB: %d\n", errcode); } } else { if (status && !hfc->disc_flag) { printk(KERN_INFO - "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", - symbolic(urb_errlist, status), status, - fifon); + "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n", + status, symbolic(urb_errlist, status), fifon); } } -} /* tx_iso_complete */ +} -/*****************************************************/ -/* receive completion routine for all ISO tx fifos */ -/*****************************************************/ static void rx_iso_complete(struct urb *urb) { @@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb) unsigned int iso_status; __u8 *buf; static __u8 eof[8]; -#ifdef CONFIG_HISAX_DEBUG - __u8 i; -#endif fifon = fifo->fifonum; status = urb->status; if (urb->status == -EOVERFLOW) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", - fifon); -#endif + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); + status = 0; + } + + /* ISO transfer only partially completed, + look at individual frame status for details */ + if (status == -EXDEV) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " + "urb->status %d, fifonum %d\n", + status, fifon); status = 0; } + if (fifo->active && !status) { num_isoc_packets = iso_packets[fifon]; maxlen = fifo->usb_packet_maxlen; @@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb) offset = urb->iso_frame_desc[k].offset; buf = context_iso_urb->buffer + offset; iso_status = urb->iso_frame_desc[k].status; -#ifdef CONFIG_HISAX_DEBUG + if (iso_status && !hfc->disc_flag) - DBG(USB_DBG, - "HFC-S USB: ISO packet failure - status:%x", - iso_status); + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-S USB: rx_iso_complete " + "ISO packet %i, status: %i\n", + k, iso_status); - if ((fifon == 5) && (debug > 1)) { - printk(KERN_INFO + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: ISO-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d " - "EOF:0x%0x DATA: ", + "act_urblen:%2d max-urblen:%2d EOF:0x%0x", fifo->last_urblen, len, maxlen, eof[5]); - for (i = 0; i < len; i++) - printk("%.2x ", buf[i]); - printk("\n"); + + DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } -#endif + if (fifo->last_urblen != maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* care for L1 state only for D-Channel to avoid overlapped iso completions */ - if (fifon == 5) { + if (fifon == HFCUSB_D_RX) { /* the S0 state is in the upper half of the 1st status byte */ - state_handler(hfc, buf[0] >> 4); + s0_state_handler(hfc, buf[0] >> 4); } eof[fifon] = buf[0] & 1; if (len > 2) collect_rx_frame(fifo, buf + 2, len - 2, - (len < - maxlen) ? + (len < maxlen) ? eof[fifon] : 0); } else { collect_rx_frame(fifo, buf, len, @@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb) rx_iso_complete, urb->context); errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { - printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d \n", + printk(KERN_ERR + "HFC-S USB: error submitting ISO URB: %d\n", errcode); } } else { if (status && !hfc->disc_flag) { - printk(KERN_INFO + printk(KERN_ERR "HFC-S USB: rx_iso_complete : " "urb->status %d, fifonum %d\n", status, fifon); } } -} /* rx_iso_complete */ +} -/*****************************************************/ -/* collect data from interrupt or isochron in */ -/*****************************************************/ +/* collect rx data from INT- and ISO-URBs */ static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) { hfcusb_data *hfc = fifo->hfc; int transp_mode, fifon; -#ifdef CONFIG_HISAX_DEBUG - int i; -#endif + fifon = fifo->fifonum; transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = true; + transp_mode = 1; if (!fifo->skbuff) { fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); if (!fifo->skbuff) { - printk(KERN_INFO - "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", + printk(KERN_ERR + "HFC-S USB: cannot allocate buffer for fifo(%d)\n", fifon); return; } @@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (fifo->skbuff->len + len < fifo->max_size) { memcpy(skb_put(fifo->skbuff, len), data, len); } else { -#ifdef CONFIG_HISAX_DEBUG - printk(KERN_INFO "HFC-S USB: "); - for (i = 0; i < 15; i++) - printk("%.2x ", - fifo->skbuff->data[fifo->skbuff-> - len - 15 + i]); - printk("\n"); -#endif - printk(KERN_INFO - "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n", + DBG(HFCUSB_DBG_FIFO_ERR, + "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)", fifo->max_size, fifon); + DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); + skb_trim(fifo->skbuff, 0); } } if (transp_mode && fifo->skbuff->len >= 128) { @@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (finish) { if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) && (fifo->skbuff->len > 3)) { + + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_DCHANNEL, + "HFC-S USB: D-RX len(%d)", fifo->skbuff->len); + DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff); + } + /* remove CRC & status */ skb_trim(fifo->skbuff, fifo->skbuff->len - 3); if (fifon == HFCUSB_PCM_RX) { @@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) fifo->skbuff); fifo->skbuff = NULL; /* buffer was freed from upper layer */ } else { - if (fifo->skbuff->len > 3) { - printk(KERN_INFO - "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", - fifo->skbuff->len, fifon); -#ifdef CONFIG_HISAX_DEBUG - if (debug > 1) { - printk(KERN_INFO "HFC-S USB: "); - for (i = 0; i < 15; i++) - printk("%.2x ", - fifo->skbuff-> - data[fifo->skbuff-> - len - 15 + i]); - printk("\n"); - } -#endif - } -#ifdef CONFIG_HISAX_DEBUG - else { - printk(KERN_INFO - "HFC-S USB: frame to small (%d bytes)!!!\n", - fifo->skbuff->len); - } -#endif + DBG(HFCUSB_DBG_FIFO_ERR, + "HFC-S USB: ERROR frame len(%d) fifo(%d)", + fifo->skbuff->len, fifon); + DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); skb_trim(fifo->skbuff, 0); } } } -/***********************************************/ -/* receive completion routine for all rx fifos */ -/***********************************************/ static void -rx_complete(struct urb *urb) +rx_int_complete(struct urb *urb) { int len; int status; @@ -922,18 +851,14 @@ rx_complete(struct urb *urb) usb_fifo *fifo = (usb_fifo *) urb->context; hfcusb_data *hfc = fifo->hfc; static __u8 eof[8]; -#ifdef CONFIG_HISAX_DEBUG - __u8 i; -#endif urb->dev = hfc->dev; /* security init */ fifon = fifo->fifonum; if ((!fifo->active) || (urb->status)) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)", + DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)", fifon, urb->status); -#endif + fifo->urb->interval = 0; /* cancel automatic rescheduling */ if (fifo->skbuff) { dev_kfree_skb_any(fifo->skbuff); @@ -945,22 +870,20 @@ rx_complete(struct urb *urb) buf = fifo->buffer; maxlen = fifo->usb_packet_maxlen; -#ifdef CONFIG_HISAX_DEBUG - if ((fifon == 5) && (debug > 1)) { - printk(KERN_INFO - "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", - fifo->last_urblen, len, maxlen, eof[5]); - for (i = 0; i < len; i++) - printk("%.2x ", buf[i]); - printk("\n"); + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-S USB: INT-D-RX lst_urblen:%2d " + "act_urblen:%2d max-urblen:%2d EOF:0x%0x", + fifo->last_urblen, len, maxlen, + eof[5]); + DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } -#endif if (fifo->last_urblen != fifo->usb_packet_maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* the S0 state is in the upper half of the 1st status byte */ - state_handler(hfc, buf[0] >> 4); + s0_state_handler(hfc, buf[0] >> 4); eof[fifon] = buf[0] & 1; /* if we have more than the 2 status bytes -> collect data */ if (len > 2) @@ -975,20 +898,19 @@ rx_complete(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { printk(KERN_INFO - "HFC-S USB: error resubmitting URN at rx_complete...\n"); + "HFC-S USB: %s error resubmitting URB fifo(%d)\n", + __FUNCTION__, fifon); } -} /* rx_complete */ +} -/***************************************************/ -/* start the interrupt transfer for the given fifo */ -/***************************************************/ +/* start initial INT-URB for certain fifo */ static void start_int_fifo(usb_fifo * fifo) { int errcode; - printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", - fifo->fifonum); + DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n", + fifo->fifonum); if (!fifo->urb) { fifo->urb = usb_alloc_urb(0, GFP_KERNEL); @@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo) } usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, fifo->buffer, fifo->usb_packet_maxlen, - rx_complete, fifo, fifo->intervall); + rx_int_complete, fifo, fifo->intervall); fifo->active = 1; /* must be marked active */ errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); if (errcode) { - printk(KERN_INFO + printk(KERN_ERR "HFC-S USB: submit URB error(start_int_info): status:%i\n", errcode); fifo->active = 0; fifo->skbuff = NULL; } -} /* start_int_fifo */ +} -/*****************************/ -/* set the B-channel mode */ -/*****************************/ static void -set_hfcmode(hfcusb_data * hfc, int channel, int mode) +setup_bchannel(hfcusb_data * hfc, int channel, int mode) { __u8 val, idx_table[2] = { 0, 2 }; if (hfc->disc_flag) { return; } -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, - mode); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d", + channel, mode); hfc->b_mode[channel] = mode; /* setup CON_HDLC */ @@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) switch (pr) { case PH_ACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); -#endif + if (hfc->l1_state != 3 && hfc->l1_state != 7) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); -#endif } else { if (hfc->l1_state == 7) { /* l1 already active */ hfc->d_if.ifc.l1l2(&hfc-> @@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); -#endif } else { /* force sending sending INFO1 */ queue_control_request(hfc, @@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) } } } else { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, - "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); -#endif - set_hfcmode(hfc, + DBG(HFCUSB_DBG_STATES, + "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST"); + setup_bchannel(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (long) arg); @@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) break; case PH_DEACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); -#endif - printk(KERN_INFO - "HFC-S USB: ISDN TE device should not deativate...\n"); } else { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); -#endif - set_hfcmode(hfc, + setup_bchannel(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (int) L1_MODE_NULL); @@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = false; + fifo->delete_flg = 0; } fifo->skbuff = arg; /* we have a new buffer */ break; default: - printk(KERN_INFO - "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", - pr); + DBG(HFCUSB_DBG_STATES, + "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); break; } } -/***************************************************************************/ -/* usb_init is called once when a new matching device is detected to setup */ -/* main parameters. It registers the driver at the main hisax module. */ -/* on success 0 is returned. */ -/***************************************************************************/ +/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */ static int -usb_init(hfcusb_data * hfc) +hfc_usb_init(hfcusb_data * hfc) { usb_fifo *fifo; int i, err; @@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc) /* aux = output, reset off */ write_usb(hfc, HFCUSB_CIRM, 0x10); - /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ + /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */ write_usb(hfc, HFCUSB_USB_SIZE, (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); - /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */ + /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */ write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); /* enable PCM/GCI master mode */ @@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc) hfc->b_mode[0] = L1_MODE_NULL; hfc->b_mode[1] = L1_MODE_NULL; - hfc->l1_activated = false; - hfc->disc_flag = false; + hfc->l1_activated = 0; + hfc->disc_flag = 0; hfc->led_state = 0; hfc->led_new_data = 0; hfc->old_led_state = 0; @@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc) handle_led(hfc, LED_POWER_ON); return (0); -} /* usb_init */ +} -/*************************************************/ -/* function called to probe a new plugged device */ -/*************************************************/ +/* initial callback for each plugged USB device */ static int hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1378,11 +1275,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) } } -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, - iface->desc.bAlternateSetting, intf->minor); -#endif printk(KERN_INFO "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, iface->desc.bAlternateSetting, intf->minor); @@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* check for config EOL element */ while (validconf[cfg_used][0]) { - cfg_found = true; + cfg_found = 1; vcf = validconf[cfg_used]; /* first endpoint descriptor */ ep = iface->endpoint; -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n", - ifnum, probe_alt_setting, cfg_used); -#endif + memcpy(cmptbl, vcf, 16 * sizeof(int)); /* check for all endpoints in this alternate setting */ @@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) idx++; attr = ep->desc.bmAttributes; if (cmptbl[idx] == EP_NUL) { - cfg_found = false; + cfg_found = 0; } if (attr == USB_ENDPOINT_XFER_INT && cmptbl[idx] == EP_INT) @@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) cmptbl[idx] = EP_NUL; /* check if all INT endpoints match minimum interval */ - if (attr == USB_ENDPOINT_XFER_INT - && ep->desc.bInterval < - vcf[17]) { -#ifdef CONFIG_HISAX_DEBUG - if (cfg_found) - DBG(USB_DBG, - "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config", - vcf[17]); -#endif - cfg_found = false; + if ((attr == USB_ENDPOINT_XFER_INT) + && (ep->desc.bInterval < vcf[17])) { + cfg_found = 0; } ep++; } @@ -1455,7 +1336,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* all entries must be EP_NOP or EP_NUL for a valid config */ if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL) - cfg_found = false; + cfg_found = 0; } if (cfg_found) { if (cfg_used < small_match) { @@ -1464,23 +1345,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) probe_alt_setting; iface_used = iface; } -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: small_match=%x %x\n", - small_match, alt_used); -#endif } cfg_used++; } alt_idx++; - } /* (alt_idx < intf->num_altsetting) */ + } /* (alt_idx < intf->num_altsetting) */ /* found a valid USB Ta Endpint config */ if (small_match != 0xffff) { iface = iface_used; - if (! - (context = - kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) + if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) return (-ENOMEM); /* got no mem */ ep = iface->endpoint; @@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) driver_info; printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", driver_info->vend_name); -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", + + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)", conf_str[small_match], context->if_used, - context->alt_used); - printk(KERN_INFO - "HFC-S USB: E-channel (\"ECHO:\") logging "); - if (validconf[small_match][18]) - printk(" possible\n"); - else - printk("NOT possible\n"); -#endif + context->alt_used, + validconf[small_match][18]); + /* init the chip and register the driver */ - if (usb_init(context)) { + if (hfc_usb_init(context)) { usb_kill_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb); context->ctrl_urb = NULL; @@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) return (-EIO); } -/****************************************************/ -/* function called when an active device is removed */ -/****************************************************/ +/* callback for unplugged USB device */ static void hfc_usb_disconnect(struct usb_interface *intf) { hfcusb_data *context = usb_get_intfdata(intf); int i; + + handle_led(context, LED_POWER_OFF); + schedule_timeout((10 * HZ) / 1000); + printk(KERN_INFO "HFC-S USB: device disconnect\n"); - context->disc_flag = true; + context->disc_flag = 1; usb_set_intfdata(intf, NULL); if (!context) return; @@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface del_timer(&context->t3_timer); if (timer_pending(&context->t4_timer)) del_timer(&context->t4_timer); + /* tell all fifos to terminate */ for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { if (context->fifos[i].usb_transfer_mode == USB_ISOC) { if (context->fifos[i].active > 0) { stop_isoc_chain(&context->fifos[i]); -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", - i); -#endif + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: %s stopping ISOC chain Fifo(%i)", + __FUNCTION__, i); } } else { if (context->fifos[i].active > 0) { context->fifos[i].active = 0; -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", - i); -#endif + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: %s unlinking URB for Fifo(%i)", + __FUNCTION__, i); } usb_kill_urb(context->fifos[i].urb); usb_free_urb(context->fifos[i].urb); @@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface context->ctrl_urb = NULL; hisax_unregister(&context->d_if); kfree(context); /* free our structure again */ -} /* hfc_usb_disconnect */ +} -/************************************/ -/* our driver information structure */ -/************************************/ static struct usb_driver hfc_drv = { .name = "hfc_usb", .id_table = hfcusb_idtab, .probe = hfc_usb_probe, .disconnect = hfc_usb_disconnect, }; + static void __exit -hfc_usb_exit(void) +hfc_usb_mod_exit(void) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ..."); -#endif - usb_deregister(&hfc_drv); /* release our driver */ + usb_deregister(&hfc_drv); /* release our driver */ printk(KERN_INFO "HFC-S USB: module removed\n"); } static int __init -hfc_usb_init(void) +hfc_usb_mod_init(void) { + char revstr[30], datestr[30], dummy[30]; #ifndef CONFIG_HISAX_DEBUG - unsigned int debug = -1; + hfc_debug = debug; #endif - char revstr[30], datestr[30], dummy[30]; sscanf(hfcusb_revision, "%s %s $ %s %s %s $ ", dummy, revstr, dummy, datestr, dummy); @@ -1734,8 +1597,8 @@ hfc_usb_init(void) return (0); } -module_init(hfc_usb_init); -module_exit(hfc_usb_exit); +module_init(hfc_usb_mod_init); +module_exit(hfc_usb_mod_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h index 471f2354dfde..e79f56568d30 100644 --- a/drivers/isdn/hisax/hfc_usb.h +++ b/drivers/isdn/hisax/hfc_usb.h @@ -1,8 +1,8 @@ /* -* hfc_usb.h -* -* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $ -*/ + * hfc_usb.h + * + * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $ + */ #ifndef __HFC_USB_H__ #define __HFC_USB_H__ @@ -10,25 +10,20 @@ #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" -#define VERBOSE_USB_DEBUG +#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ +#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ +#define HFC_TIMER_T4 500 /* time for state change interval */ -/***********/ -/* defines */ -/***********/ -#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ -#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ -#define HFC_TIMER_T4 500 /* time for state change interval */ +#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ +#define HFCUSB_L1_DRX 1 /* D-frame received */ +#define HFCUSB_L1_ERX 2 /* E-frame received */ +#define HFCUSB_L1_DTX 4 /* D-frames completed */ -#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ -#define HFCUSB_L1_DRX 1 /* D-frame received */ -#define HFCUSB_L1_ERX 2 /* E-frame received */ -#define HFCUSB_L1_DTX 4 /* D-frames completed */ +#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ -#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ - -#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ -#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ +#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ +#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ #define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ #define HFCUSB_CIRM 0x00 /* cirm register index */ @@ -52,9 +47,8 @@ #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ -/******************/ + /* fifo registers */ -/******************/ #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ @@ -66,9 +60,9 @@ #define HFCUSB_PCM_RX 7 /* -* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just -* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out -*/ + * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just + * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out + */ #define USB_INT 0 #define USB_BULK 1 #define USB_ISOC 2 @@ -77,49 +71,36 @@ #define ISOC_PACKETS_B 8 #define ISO_BUFFER_SIZE 128 -// ISO send definitions +/* Fifo flow Control for TX ISO */ #define SINK_MAX 68 #define SINK_MIN 48 #define SINK_DMIN 12 #define SINK_DMAX 18 #define BITLINE_INF (-64*8) - -/**********/ -/* macros */ -/**********/ +/* HFC-S USB register access by Control-URSs */ #define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) - - -/*******************/ -/* Debugging Flags */ -/*******************/ -#define USB_DBG 1 -#define ISDN_DBG 2 - - -/* *********************/ -/* USB related defines */ -/***********************/ #define HFC_CTRL_BUFSIZE 32 - - -/*************************************************/ /* entry and size of output/input control buffer */ -/*************************************************/ typedef struct { __u8 hfc_reg; /* register number */ __u8 reg_val; /* value to be written (or read) */ int action; /* data for action handler */ } ctrl_buft; +/* Debugging Flags */ +#define HFCUSB_DBG_INIT 0x0001 +#define HFCUSB_DBG_STATES 0x0002 +#define HFCUSB_DBG_DCHANNEL 0x0080 +#define HFCUSB_DBG_FIFO_ERR 0x4000 +#define HFCUSB_DBG_VERBOSE_USB 0x8000 -/********************/ -/* URB error codes: */ -/********************/ -/* Used to represent a list of values and their respective symbolic names */ +/* + * URB error codes: + * Used to represent a list of values and their respective symbolic names + */ struct hfcusb_symbolic_list { const int num; const char *name; @@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = { {-ENXIO, "URB already queued"}, {-EFBIG, "Too much ISO frames requested"}, {-ENOSR, "Buffer error (overrun)"}, - {-EPIPE, "Specified endpoint is stalled"}, + {-EPIPE, "Specified endpoint is stalled (device not responding)"}, {-EOVERFLOW, "Babble (bad cable?)"}, {-EPROTO, "Bit-stuff error (bad cable?)"}, - {-EILSEQ, "CRC or missing token"}, - {-ETIME, "Device did not respond"}, + {-EILSEQ, "CRC/Timeout"}, + {-ETIMEDOUT, "NAK (device does not respond)"}, {-ESHUTDOWN, "Device unplugged"}, {-1, NULL} }; -/*****************************************************/ -/* device dependant information to support different */ -/* ISDN Ta's using the HFC-S USB chip */ -/*****************************************************/ +/* + * device dependant information to support different + * ISDN Ta's using the HFC-S USB chip + */ /* USB descriptor need to contain one of the following EndPoint combination: */ #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT @@ -155,16 +136,19 @@ static struct hfcusb_symbolic_list urb_errlist[] = { #define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT #define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT -#define EP_NUL 1 // Endpoint at this position not allowed -#define EP_NOP 2 // all type of endpoints allowed at this position -#define EP_ISO 3 // Isochron endpoint mandatory at this position -#define EP_BLK 4 // Bulk endpoint mandatory at this position -#define EP_INT 5 // Interrupt endpoint mandatory at this position +#define EP_NUL 1 // Endpoint at this position not allowed +#define EP_NOP 2 // all type of endpoints allowed at this position +#define EP_ISO 3 // Isochron endpoint mandatory at this position +#define EP_BLK 4 // Bulk endpoint mandatory at this position +#define EP_INT 5 // Interrupt endpoint mandatory at this position -/* this array represents all endpoints possible in the HCF-USB the last -* 3 entries are the configuration number, the minimum interval for -* Interrupt endpoints & boolean if E-channel logging possible -*/ +/* + * List of all supported endpoint configuration sets, used to find the + * best matching endpoint configuration within a devices' USB descriptor. + * We need at least 3 RX endpoints, and 3 TX endpoints, either + * INT-in and ISO-out, or ISO-in and ISO-out) + * with 4 RX endpoints even E-Channel logging is possible + */ static int validconf[][19] = { // INT in, ISO out config {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, @@ -193,7 +177,6 @@ static char *conf_str[] = { }; #endif - typedef struct { int vendor; // vendor id int prod_id; // product id @@ -202,9 +185,9 @@ typedef struct { signed short led_bits[8]; // array of 8 possible LED bitmask settings } vendor_data; -#define LED_OFF 0 // no LED support -#define LED_SCHEME1 1 // LED standard scheme -#define LED_SCHEME2 2 // not used yet... +#define LED_OFF 0 // no LED support +#define LED_SCHEME1 1 // LED standard scheme +#define LED_SCHEME2 2 // not used yet... #define LED_POWER_ON 1 #define LED_POWER_OFF 2 @@ -217,11 +200,8 @@ typedef struct { #define LED_B2_OFF 9 #define LED_B2_DATA 10 -#define LED_NORMAL 0 // LEDs are normal -#define LED_INVERTED 1 // LEDs are inverted - -/* time in ms to perform a Flashing LED when B-Channel has traffic */ -#define LED_TIME 250 +#define LED_NORMAL 0 // LEDs are normal +#define LED_INVERTED 1 // LEDs are inverted -#endif // __HFC_USB_H__ +#endif // __HFC_USB_H__ -- cgit v1.2.3 From f350339cbd0e8ed7751f98f0ef60cb3a0d410eda Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 21 Aug 2007 11:10:22 -0700 Subject: sky2: don't clear phy power bits There are special PHY settings available on Yukon EC-U chip that should not get cleared. This should solve mysterious errors on some motherboards (like Gigabyte DS-3). Signed-off-by: Stephen Hemminger Signed-off-by: Linus Torvalds --- drivers/net/sky2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e7a2eadcc3b0..757592436390 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -696,8 +696,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) int i; const u8 *addr = hw->dev[port]->dev_addr; - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); -- cgit v1.2.3 From 06c7af563d925d04961ce70cd9154fad8e2750c8 Mon Sep 17 00:00:00 2001 From: Konstantin Sharlaimov Date: Tue, 21 Aug 2007 00:12:44 -0700 Subject: [PPP]: Fix output buffer size in ppp_decompress_frame(). This patch addresses the issue with "osize too small" errors in mppe encryption. The patch fixes the issue with wrong output buffer size being passed to ppp decompression routine. -------------------- As pointed out by Suresh Mahalingam, the issue addressed by ppp-fix-osize-too-small-errors-when-decoding patch is not fully resolved yet. The size of allocated output buffer is correct, however it size passed to ppp->rcomp->decompress in ppp_generic.c if wrong. The patch fixes that. -------------------- Signed-off-by: Konstantin Sharlaimov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ef3325b69233..9293c82ef2af 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1726,7 +1726,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) } /* the decompressor still expects the A/C bytes in the hdr */ len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, - skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); + skb->len + 2, ns->data, obuff_size); if (len < 0) { /* Pass the compressed frame to pppd as an error indication. */ -- cgit v1.2.3 From 3520c92283bb7ddd59daf90cfc1eb107dc9ab76c Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 22 Aug 2007 13:51:36 +0200 Subject: [S390] cio: dont forget to set last slot to NULL in ccw_uevent(). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 297659fa0e26..e44d92eac8e9 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -117,7 +117,10 @@ static int ccw_uevent(struct device *dev, char **envp, int num_envp, snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MODALIAS=%s", modalias_buf); - return ret; + if (ret) + return ret; + envp[i] = NULL; + return 0; } struct bus_type ccw_bus_type; -- cgit v1.2.3 From 23eb68c569cdbaad1a88015be1d69c565cd3926a Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 22 Aug 2007 13:51:37 +0200 Subject: [S390] cio: change confusing message in cmf. cmf currently prints a message that more than 4096 channels are not allowed in basic mode - however, this can only be enforced if cmf was a module (which is no longer possible). It makes much more sense to not check the specified number of channels and just print a message if the block for basic mode could not be allocated (which may happen for any number of specified channels). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cmf.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 02fd00b55e1b..34a796913b06 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -594,6 +594,9 @@ alloc_cmb (struct ccw_device *cdev) free_pages((unsigned long)mem, get_order(size)); } else if (!mem) { /* no luck */ + printk(KERN_WARNING "cio: failed to allocate area " + "for measuring %d subchannels\n", + cmb_area.num_channels); ret = -ENOMEM; goto out; } else { @@ -1279,13 +1282,6 @@ init_cmf(void) case CMF_BASIC: format_string = "basic"; cmbops = &cmbops_basic; - if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) { - printk(KERN_ERR "cio: Basic channel measurement " - "facility can only use 1 to 4096 devices\n" - KERN_ERR "when the cmf driver is built" - " as a loadable module\n"); - return 1; - } break; case CMF_EXTENDED: format_string = "extended"; -- cgit v1.2.3 From f276730f8da0e8136d8491b6ef44fc719d450a1b Mon Sep 17 00:00:00 2001 From: "Klaus D. Wacker" Date: Wed, 22 Aug 2007 13:51:38 +0200 Subject: [S390] qdio: fix EQBS handling on CCQ96 QDIO returned from EQBS instruction in any case after return code CCQ=96 was issued regardless whether buffer states for at least one buffer were extracted or not. This caused FCP devices to hang when running under z/VM and having QIOASSASIST=ON and having high I/O rates. In order to fix this qdio return code processing of EQBS instruction after CCQ=96 is changed that buffers are returned and if no buffers where extracted the instruction is repeated at once. Signed-off-by: Klaus D. Wacker Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/qdio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 03347aed2b3e..badfb5b21304 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -195,6 +195,8 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, again: ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); rc = qdio_check_ccq(q, ccq); + if ((ccq == 96) && (tmp_cnt != *cnt)) + rc = 0; if (rc == 1) { QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); goto again; -- cgit v1.2.3 From 37cd0a007f88f1d6269035bdb02b50f536cca8de Mon Sep 17 00:00:00 2001 From: "Klaus D. Wacker" Date: Wed, 22 Aug 2007 13:51:39 +0200 Subject: [S390] qdio: Refresh buffer states for IQDIO Asynchronous output queue Hipersocket Multicast queue works asynchronously. When sending buffers, the buffer state change may happen delayed. The tasklet for checking changes in the outbound queue excluded IQDIO async queues from this process. This created either a hang situation when the queue ran full, or presented a hang situation a interface close time. The tasklet processing is changed to include IQDIO async queues when requesting buffer state refresh. Signed-off-by: Klaus D. Wacker Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index badfb5b21304..d8d479876ec7 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -742,7 +742,8 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q) first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), (QDIO_MAX_BUFFERS_PER_Q-1)); - if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) + if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || + (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) SYNC_MEMORY; check_next: -- cgit v1.2.3 From 0a87c5cfc0bb0c1bdcc1cc9fd82e4a1711fac512 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 22 Aug 2007 13:51:40 +0200 Subject: [S390] vmur: fix diag14 exceptions with addresses > 2GB. There are several s390 diagnose calls, which must be executed below the 2GB memory boundary. In order to enforce this, those diagnoses must be compiled into the kernel. Currently diag 14 can be called within the vmur kernel module from addresses above 2GB. This leads to specification exceptions. This patch moves diag10, diag14 and diag210 into the new diag.c file. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/diag.c | 102 +++++++++++++++++++++++++++++++++++++++++ arch/s390/kernel/s390_ksyms.c | 1 - arch/s390/mm/cmm.c | 1 + arch/s390/mm/init.c | 17 ------- drivers/s390/block/dasd_diag.c | 1 + drivers/s390/char/raw3270.c | 1 + drivers/s390/char/vmur.c | 32 ++----------- drivers/s390/cio/device_id.c | 48 +------------------ include/asm-s390/cio.h | 15 ------ include/asm-s390/diag.h | 39 ++++++++++++++++ include/asm-s390/pgalloc.h | 2 - 12 files changed, 150 insertions(+), 111 deletions(-) create mode 100644 arch/s390/kernel/diag.c create mode 100644 include/asm-s390/diag.h (limited to 'drivers') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 3195d375bd51..56cb71007cd9 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o + semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c new file mode 100644 index 000000000000..c032d11da8a1 --- /dev/null +++ b/arch/s390/kernel/diag.c @@ -0,0 +1,102 @@ +/* + * Implementation of s390 diagnose codes + * + * Copyright IBM Corp. 2007 + * Author(s): Michael Holzheu + */ + +#include +#include + +/* + * Diagnose 10: Release pages + */ +void diag10(unsigned long addr) +{ + if (addr >= 0x7ff00000) + return; + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" +#else + " diag %0,%0,0x10\n" + "0:\n" +#endif + EX_TABLE(0b, 0b) + : : "a" (addr)); +} +EXPORT_SYMBOL(diag10); + +/* + * Diagnose 14: Input spool file manipulation + */ +int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) +{ + register unsigned long _ry1 asm("2") = ry1; + register unsigned long _ry2 asm("3") = subcode; + int rc = 0; + + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %2,2,0x14\n" + " sam64\n" +#else + " diag %2,2,0x14\n" +#endif + " ipm %0\n" + " srl %0,28\n" + : "=d" (rc), "+d" (_ry2) + : "d" (rx), "d" (_ry1) + : "cc"); + + return rc; +} +EXPORT_SYMBOL(diag14); + +/* + * Diagnose 210: Get information about a virtual device + */ +int diag210(struct diag210 *addr) +{ + /* + * diag 210 needs its data below the 2GB border, so we + * use a static data area to be sure + */ + static struct diag210 diag210_tmp; + static DEFINE_SPINLOCK(diag210_lock); + unsigned long flags; + int ccode; + + spin_lock_irqsave(&diag210_lock, flags); + diag210_tmp = *addr; + +#ifdef CONFIG_64BIT + asm volatile( + " lhi %0,-1\n" + " sam31\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1: sam64\n" + EX_TABLE(0b, 1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#else + asm volatile( + " lhi %0,-1\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#endif + + *addr = diag210_tmp; + spin_unlock_irqrestore(&diag210_lock, flags); + + return ccode; +} +EXPORT_SYMBOL(diag210); diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 90b5ef529eb7..7234c737f825 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c @@ -25,7 +25,6 @@ EXPORT_SYMBOL(_oi_bitmap); EXPORT_SYMBOL(_ni_bitmap); EXPORT_SYMBOL(_zb_findmap); EXPORT_SYMBOL(_sb_findmap); -EXPORT_SYMBOL(diag10); /* * semaphore ops diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index c5b2f4f078bc..fabc50adc46a 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -20,6 +20,7 @@ #include #include +#include static char *sender = "VMRMSVM"; module_param(sender, charp, 0400); diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 9098531a2671..3a25bbf2eb0a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -42,23 +42,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); -void diag10(unsigned long addr) -{ - if (addr >= 0x7ff00000) - return; - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %0,%0,0x10\n" - "0: sam64\n" -#else - " diag %0,%0,0x10\n" - "0:\n" -#endif - EX_TABLE(0b,0b) - : : "a" (addr)); -} - void show_mem(void) { int i, total = 0, reserved = 0; diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index eccac1c3b71b..d32c60dbdd82 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "dasd_int.h" #include "dasd_diag.h" diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 4f2f81b16cfa..2edd5fb6d3dc 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "raw3270.h" diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 04b19bdc09da..2d96c958df64 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "vmur.h" @@ -379,31 +380,6 @@ static ssize_t ur_write(struct file *file, const char __user *udata, return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); } -static int do_diag_14(unsigned long rx, unsigned long ry1, - unsigned long subcode) -{ - register unsigned long _ry1 asm("2") = ry1; - register unsigned long _ry2 asm("3") = subcode; - int rc = 0; - - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %2,2,0x14\n" - " sam64\n" -#else - " diag %2,2,0x14\n" -#endif - " ipm %0\n" - " srl %0,28\n" - : "=d" (rc), "+d" (_ry2) - : "d" (rx), "d" (_ry1) - : "cc"); - - TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc); - return rc; -} - /* * diagnose code 0x14 subcode 0x0028 - position spool file to designated * record @@ -415,7 +391,7 @@ static int diag_position_to_record(int devno, int record) { int cc; - cc = do_diag_14(record, devno, 0x28); + cc = diag14(record, devno, 0x28); switch (cc) { case 0: return 0; @@ -440,7 +416,7 @@ static int diag_read_file(int devno, char *buf) { int cc; - cc = do_diag_14((unsigned long) buf, devno, 0x00); + cc = diag14((unsigned long) buf, devno, 0x00); switch (cc) { case 0: return 0; @@ -533,7 +509,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) { int cc; - cc = do_diag_14((unsigned long) buf, spid, 0xfff); + cc = diag14((unsigned long) buf, spid, 0xfff); switch (cc) { case 0: return 0; diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 60b9347f7c92..f232832f2b22 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "cio.h" #include "cio_debug.h" @@ -24,51 +25,6 @@ #include "device.h" #include "ioasm.h" -/* - * diag210 is used under VM to get information about a virtual device - */ -int -diag210(struct diag210 * addr) -{ - /* - * diag 210 needs its data below the 2GB border, so we - * use a static data area to be sure - */ - static struct diag210 diag210_tmp; - static DEFINE_SPINLOCK(diag210_lock); - unsigned long flags; - int ccode; - - spin_lock_irqsave(&diag210_lock, flags); - diag210_tmp = *addr; - -#ifdef CONFIG_64BIT - asm volatile( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#else - asm volatile( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#endif - - *addr = diag210_tmp; - spin_unlock_irqrestore(&diag210_lock, flags); - - return ccode; -} - /* * Input : * devno - device number @@ -349,5 +305,3 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) break; } } - -EXPORT_SYMBOL(diag210); diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index f738d2827582..1982fb344164 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h @@ -258,19 +258,6 @@ struct ciw { /* Sick revalidation of device. */ #define CIO_REVALIDATE 0x0008 -struct diag210 { - __u16 vrdcdvno : 16; /* device number (input) */ - __u16 vrdclen : 16; /* data block length (input) */ - __u32 vrdcvcla : 8; /* virtual device class (output) */ - __u32 vrdcvtyp : 8; /* virtual device type (output) */ - __u32 vrdcvsta : 8; /* virtual device status (output) */ - __u32 vrdcvfla : 8; /* virtual device flags (output) */ - __u32 vrdcrccl : 8; /* real device class (output) */ - __u32 vrdccrty : 8; /* real device type (output) */ - __u32 vrdccrmd : 8; /* real device model (output) */ - __u32 vrdccrft : 8; /* real device feature (output) */ -} __attribute__ ((packed,aligned(4))); - struct ccw_dev_id { u8 ssid; u16 devno; @@ -285,8 +272,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, return 0; } -extern int diag210(struct diag210 *addr); - extern void wait_cons_dev(void); extern void css_schedule_reprobe(void); diff --git a/include/asm-s390/diag.h b/include/asm-s390/diag.h new file mode 100644 index 000000000000..72b2e2f2d32d --- /dev/null +++ b/include/asm-s390/diag.h @@ -0,0 +1,39 @@ +/* + * s390 diagnose functions + * + * Copyright IBM Corp. 2007 + * Author(s): Michael Holzheu + */ + +#ifndef _ASM_S390_DIAG_H +#define _ASM_S390_DIAG_H + +/* + * Diagnose 10: Release pages + */ +extern void diag10(unsigned long addr); + +/* + * Diagnose 14: Input spool file manipulation + */ +extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); + +/* + * Diagnose 210: Get information about a virtual device + */ +struct diag210 { + u16 vrdcdvno; /* device number (input) */ + u16 vrdclen; /* data block length (input) */ + u8 vrdcvcla; /* virtual device class (output) */ + u8 vrdcvtyp; /* virtual device type (output) */ + u8 vrdcvsta; /* virtual device status (output) */ + u8 vrdcvfla; /* virtual device flags (output) */ + u8 vrdcrccl; /* real device class (output) */ + u8 vrdccrty; /* real device type (output) */ + u8 vrdccrmd; /* real device model (output) */ + u8 vrdccrft; /* real device feature (output) */ +} __attribute__((packed, aligned(4))); + +extern int diag210(struct diag210 *addr); + +#endif /* _ASM_S390_DIAG_H */ diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 56c8a6c80e2e..e45d3c9a4b7e 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h @@ -19,8 +19,6 @@ #define check_pgt_cache() do {} while (0) -extern void diag10(unsigned long addr); - /* * Page allocation orders. */ -- cgit v1.2.3 From 8127a1f80a002d02a30909ddf6187faedf89e00a Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 22 Aug 2007 13:51:41 +0200 Subject: [S390] vmur: fix reference counting for vmur device structure When a vmur device is removed due to a detach of the device, currently the ur device structure is freed. Unfortunately it can happen, that there is still a user of the device structure, when the character device is open during the detach process. To fix this, reference counting for the vmur structure is introduced. In addition to that, the online, offline, probe and remove functions are serialized now using a global mutex. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/vmur.c | 218 ++++++++++++++++++++++++++++++++++------------- drivers/s390/char/vmur.h | 1 + 2 files changed, 161 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 2d96c958df64..d70a6e65bf14 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -69,8 +69,26 @@ static struct ccw_driver ur_driver = { .set_offline = ur_set_offline, }; +static DEFINE_MUTEX(vmur_mutex); + /* * Allocation, freeing, getting and putting of urdev structures + * + * Each ur device (urd) contains a reference to its corresponding ccw device + * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the + * ur device using the cdev->dev.driver_data pointer. + * + * urd references: + * - ur_probe gets a urd reference, ur_remove drops the reference + * (cdev->dev.driver_data) + * - ur_open gets a urd reference, ur_relase drops the reference + * (urf->urd) + * + * cdev references: + * - urdev_alloc get a cdev reference (urd->cdev) + * - urdev_free drops the cdev reference (urd->cdev) + * + * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock */ static struct urdev *urdev_alloc(struct ccw_device *cdev) { @@ -79,42 +97,61 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); if (!urd) return NULL; - urd->cdev = cdev; urd->reclen = cdev->id.driver_info; ccw_device_get_id(cdev, &urd->dev_id); mutex_init(&urd->io_mutex); mutex_init(&urd->open_mutex); + atomic_set(&urd->ref_count, 1); + urd->cdev = cdev; + get_device(&cdev->dev); return urd; } static void urdev_free(struct urdev *urd) { + TRACE("urdev_free: %p\n", urd); + if (urd->cdev) + put_device(&urd->cdev->dev); kfree(urd); } -/* - * This is how the character device driver gets a reference to a - * ur device. When this call returns successfully, a reference has - * been taken (by get_device) on the underlying kobject. The recipient - * of this urdev pointer must eventually drop it with urdev_put(urd) - * which does the corresponding put_device(). - */ +static void urdev_get(struct urdev *urd) +{ + atomic_inc(&urd->ref_count); +} + +static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) +{ + struct urdev *urd; + unsigned long flags; + + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + urd = cdev->dev.driver_data; + if (urd) + urdev_get(urd); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + return urd; +} + static struct urdev *urdev_get_from_devno(u16 devno) { char bus_id[16]; struct ccw_device *cdev; + struct urdev *urd; sprintf(bus_id, "0.0.%04x", devno); cdev = get_ccwdev_by_busid(&ur_driver, bus_id); if (!cdev) return NULL; - - return cdev->dev.driver_data; + urd = urdev_get_from_cdev(cdev); + put_device(&cdev->dev); + return urd; } static void urdev_put(struct urdev *urd) { - put_device(&urd->cdev->dev); + if (atomic_dec_and_test(&urd->ref_count)) + urdev_free(urd); } /* @@ -246,6 +283,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, return; } urd = cdev->dev.driver_data; + BUG_ON(!urd); /* On special conditions irb is an error pointer */ if (IS_ERR(irb)) urd->io_request_rc = PTR_ERR(irb); @@ -263,9 +301,15 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, static ssize_t ur_attr_reclen_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct urdev *urd = dev->driver_data; + struct urdev *urd; + int rc; - return sprintf(buf, "%zu\n", urd->reclen); + urd = urdev_get_from_cdev(to_ccwdev(dev)); + if (!urd) + return -ENODEV; + rc = sprintf(buf, "%zu\n", urd->reclen); + urdev_put(urd); + return rc; } static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); @@ -726,64 +770,63 @@ static struct file_operations ur_fops = { /* * ccw_device infrastructure: - * ur_probe gets its own ref to the device (i.e. get_device), - * creates the struct urdev, the device attributes, sets up - * the interrupt handler and validates the virtual unit record device. - * ur_remove removes the device attributes, frees the struct urdev - * and drops (put_device) the ref to the device we got in ur_probe. + * ur_probe creates the struct urdev (with refcount = 1), the device + * attributes, sets up the interrupt handler and validates the virtual + * unit record device. + * ur_remove removes the device attributes and drops the reference to + * struct urdev. + * + * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized + * by the vmur_mutex lock. + * + * urd->char_device is used as indication that the online function has + * been completed successfully. */ static int ur_probe(struct ccw_device *cdev) { struct urdev *urd; int rc; - TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private); - - if (!get_device(&cdev->dev)) - return -ENODEV; + TRACE("ur_probe: cdev=%p\n", cdev); + mutex_lock(&vmur_mutex); urd = urdev_alloc(cdev); if (!urd) { rc = -ENOMEM; - goto fail; + goto fail_unlock; } + rc = ur_create_attributes(&cdev->dev); if (rc) { rc = -ENOMEM; - goto fail; + goto fail_urdev_put; } - cdev->dev.driver_data = urd; cdev->handler = ur_int_handler; /* validate virtual unit record device */ urd->class = get_urd_class(urd); if (urd->class < 0) { rc = urd->class; - goto fail; + goto fail_remove_attr; } if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { rc = -ENOTSUPP; - goto fail; + goto fail_remove_attr; } + spin_lock_irq(get_ccwdev_lock(cdev)); + cdev->dev.driver_data = urd; + spin_unlock_irq(get_ccwdev_lock(cdev)); + mutex_unlock(&vmur_mutex); return 0; -fail: - urdev_free(urd); - put_device(&cdev->dev); - return rc; -} - -static void ur_remove(struct ccw_device *cdev) -{ - struct urdev *urd = cdev->dev.driver_data; - - TRACE("ur_remove\n"); - if (cdev->online) - ur_set_offline(cdev); +fail_remove_attr: ur_remove_attributes(&cdev->dev); - urdev_free(urd); - put_device(&cdev->dev); +fail_urdev_put: + urdev_put(urd); +fail_unlock: + mutex_unlock(&vmur_mutex); + return rc; } static int ur_set_online(struct ccw_device *cdev) @@ -792,20 +835,29 @@ static int ur_set_online(struct ccw_device *cdev) int minor, major, rc; char node_id[16]; - TRACE("ur_set_online: cdev=%p state=%d\n", cdev, - *(int *) cdev->private); + TRACE("ur_set_online: cdev=%p\n", cdev); - if (!try_module_get(ur_driver.owner)) - return -EINVAL; + mutex_lock(&vmur_mutex); + urd = urdev_get_from_cdev(cdev); + if (!urd) { + /* ur_remove already deleted our urd */ + rc = -ENODEV; + goto fail_unlock; + } + + if (urd->char_device) { + /* Another ur_set_online was faster */ + rc = -EBUSY; + goto fail_urdev_put; + } - urd = (struct urdev *) cdev->dev.driver_data; minor = urd->dev_id.devno; major = MAJOR(ur_first_dev_maj_min); urd->char_device = cdev_alloc(); if (!urd->char_device) { rc = -ENOMEM; - goto fail_module_put; + goto fail_urdev_put; } cdev_init(urd->char_device, &ur_fops); @@ -834,29 +886,79 @@ static int ur_set_online(struct ccw_device *cdev) TRACE("ur_set_online: device_create rc=%d\n", rc); goto fail_free_cdev; } - + urdev_put(urd); + mutex_unlock(&vmur_mutex); return 0; fail_free_cdev: cdev_del(urd->char_device); -fail_module_put: - module_put(ur_driver.owner); - + urd->char_device = NULL; +fail_urdev_put: + urdev_put(urd); +fail_unlock: + mutex_unlock(&vmur_mutex); return rc; } -static int ur_set_offline(struct ccw_device *cdev) +static int ur_set_offline_force(struct ccw_device *cdev, int force) { struct urdev *urd; + int rc; - TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n", - cdev, cdev->private, *(int *) cdev->private); - urd = (struct urdev *) cdev->dev.driver_data; + TRACE("ur_set_offline: cdev=%p\n", cdev); + urd = urdev_get_from_cdev(cdev); + if (!urd) + /* ur_remove already deleted our urd */ + return -ENODEV; + if (!urd->char_device) { + /* Another ur_set_offline was faster */ + rc = -EBUSY; + goto fail_urdev_put; + } + if (!force && (atomic_read(&urd->ref_count) > 2)) { + /* There is still a user of urd (e.g. ur_open) */ + TRACE("ur_set_offline: BUSY\n"); + rc = -EBUSY; + goto fail_urdev_put; + } device_destroy(vmur_class, urd->char_device->dev); cdev_del(urd->char_device); - module_put(ur_driver.owner); + urd->char_device = NULL; + rc = 0; - return 0; +fail_urdev_put: + urdev_put(urd); + return rc; +} + +static int ur_set_offline(struct ccw_device *cdev) +{ + int rc; + + mutex_lock(&vmur_mutex); + rc = ur_set_offline_force(cdev, 0); + mutex_unlock(&vmur_mutex); + return rc; +} + +static void ur_remove(struct ccw_device *cdev) +{ + unsigned long flags; + + TRACE("ur_remove\n"); + + mutex_lock(&vmur_mutex); + + if (cdev->online) + ur_set_offline_force(cdev, 1); + ur_remove_attributes(&cdev->dev); + + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + urdev_put(cdev->dev.driver_data); + cdev->dev.driver_data = NULL; + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + + mutex_unlock(&vmur_mutex); } /* diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h index 2b3c564e0472..fa959644735a 100644 --- a/drivers/s390/char/vmur.h +++ b/drivers/s390/char/vmur.h @@ -70,6 +70,7 @@ struct urdev { size_t reclen; /* Record length for *write* CCWs */ int class; /* VM device class */ int io_request_rc; /* return code from I/O request */ + atomic_t ref_count; /* reference counter */ }; /* -- cgit v1.2.3 From 8e81cc13a88ce486a6b0a6ca56aba6985824917a Mon Sep 17 00:00:00 2001 From: Kent Yoder Date: Wed, 22 Aug 2007 14:01:04 -0700 Subject: tpmdd maintainers Fix up the maintainers info in the tpm drivers. Kylene will be out for some time, so copying the sourceforge list is the best way to get some attention. Cc: Marcel Selhorst Cc: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 +- drivers/char/tpm/tpm.c | 2 +- drivers/char/tpm/tpm.h | 2 +- drivers/char/tpm/tpm_atmel.c | 2 +- drivers/char/tpm/tpm_atmel.h | 2 +- drivers/char/tpm/tpm_bios.c | 2 ++ drivers/char/tpm/tpm_nsc.c | 2 +- drivers/char/tpm/tpm_tis.c | 2 ++ 8 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 371fe67a4eef..abe5fa7f9c33 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3452,7 +3452,7 @@ S: Maintained TPM DEVICE DRIVER P: Kylene Hall -M: kjhall@us.ibm.com +M: tpmdd-devel@lists.sourceforge.net W: http://tpmdd.sourceforge.net P: Marcel Selhorst M: tpm@selhorst.net diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 9bb542913b86..39564b76d4a3 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index b2e2b002a1bb..d15ccddc92eb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 1ab0896070be..d0e7926eb486 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h index 9363bcf0a402..6c831f9466b7 100644 --- a/drivers/char/tpm/tpm_atmel.h +++ b/drivers/char/tpm/tpm_atmel.h @@ -4,7 +4,7 @@ * Authors: * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 8677fc6a545e..60a2d2630e36 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -7,6 +7,8 @@ * Reiner Sailer * Kylene Hall * + * Maintained by: + * * Access to the eventlog extended by the TCG BIOS of PC platform * * This program is free software; you can redistribute it and/or diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 608f73071bef..6313326bc41f 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 483f3f60013c..23fa18a6654c 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -5,6 +5,8 @@ * Leendert van Doorn * Kylene Hall * + * Maintained by: + * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org * -- cgit v1.2.3 From 20620d688ac6ff8ea01a873e46febf5a6a7909f1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 22 Aug 2007 14:01:11 -0700 Subject: serial: don't optimise away baud rate changes when BOTHER is used The uart_set_termios() function will bail out early without bothering to touch the hardware, if it decides that nothing "relevant" has changed. Unfortunately, its idea of "relevant" doesn't include c_[io]speed. So if the baud rate bits are BOTHER and you just change the speed, the change gets optimised away. This patch makes it ignore the old Bfoo bits in c_cflag and just check whether c_ispeed and c_ospeed have changed. Those integers are always set appropriately for us by set_termios(). Signed-off-by: David Woodhouse Acked-by: Alan Cox Cc: Russell King Cc: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/serial_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 030a6063541d..a055f58f342f 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1146,11 +1146,14 @@ static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termio /* * These are the bits that are used to setup various - * flags in the low level driver. + * flags in the low level driver. We can ignore the Bfoo + * bits in c_cflag; c_[io]speed will always be set + * appropriately by set_termios() in tty_ioctl.c */ #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - if ((cflag ^ old_termios->c_cflag) == 0 && + tty->termios->c_ospeed == old_termios->c_ospeed && + tty->termios->c_ispeed == old_termios->c_ispeed && RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) return; -- cgit v1.2.3 From 84f8c6fc0e3b6e48fd22c28fc3bb666a130b3994 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 22 Aug 2007 14:01:14 -0700 Subject: serial: add support for ITE 887x chips Add support for the it887x-chips (PCI) manufactured by ITE. Signed-off-by: Niels de Vos Cc: Russell King Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 5e485876f54c..fd76542c5977 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -580,6 +580,138 @@ static int pci_netmos_init(struct pci_dev *dev) return num_serial; } +/* + * ITE support by Niels de Vos + * + * These chips are available with optionally one parallel port and up to + * two serial ports. Unfortunately they all have the same product id. + * + * Basic configuration is done over a region of 32 I/O ports. The base + * ioport is called INTA or INTC, depending on docs/other drivers. + * + * The region of the 32 I/O ports is configured in POSIO0R... + */ + +/* registers */ +#define ITE_887x_MISCR 0x9c +#define ITE_887x_INTCBAR 0x78 +#define ITE_887x_UARTBAR 0x7c +#define ITE_887x_PS0BAR 0x10 +#define ITE_887x_POSIO0 0x60 + +/* I/O space size */ +#define ITE_887x_IOSIZE 32 +/* I/O space size (bits 26-24; 8 bytes = 011b) */ +#define ITE_887x_POSIO_IOSIZE_8 (3 << 24) +/* I/O space size (bits 26-24; 32 bytes = 101b) */ +#define ITE_887x_POSIO_IOSIZE_32 (5 << 24) +/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */ +#define ITE_887x_POSIO_SPEED (3 << 29) +/* enable IO_Space bit */ +#define ITE_887x_POSIO_ENABLE (1 << 31) + +static int __devinit pci_ite887x_init(struct pci_dev *dev) +{ + /* inta_addr are the configuration addresses of the ITE */ + static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0, + 0x200, 0x280, 0 }; + int ret, i, type; + struct resource *iobase = NULL; + u32 miscr, uartbar, ioport; + + /* search for the base-ioport */ + i = 0; + while (inta_addr[i] && iobase == NULL) { + iobase = request_region(inta_addr[i], ITE_887x_IOSIZE, + "ite887x"); + if (iobase != NULL) { + /* write POSIO0R - speed | size | ioport */ + pci_write_config_dword(dev, ITE_887x_POSIO0, + ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | + ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]); + /* write INTCBAR - ioport */ + pci_write_config_dword(dev, ITE_887x_INTCBAR, inta_addr[i]); + ret = inb(inta_addr[i]); + if (ret != 0xff) { + /* ioport connected */ + break; + } + release_region(iobase->start, ITE_887x_IOSIZE); + iobase = NULL; + } + i++; + } + + if (!inta_addr[i]) { + printk(KERN_ERR "ite887x: could not find iobase\n"); + return -ENODEV; + } + + /* start of undocumented type checking (see parport_pc.c) */ + type = inb(iobase->start + 0x18) & 0x0f; + + switch (type) { + case 0x2: /* ITE8871 (1P) */ + case 0xa: /* ITE8875 (1P) */ + ret = 0; + break; + case 0xe: /* ITE8872 (2S1P) */ + ret = 2; + break; + case 0x6: /* ITE8873 (1S) */ + ret = 1; + break; + case 0x8: /* ITE8874 (2S) */ + ret = 2; + break; + default: + moan_device("Unknown ITE887x", dev); + ret = -ENODEV; + } + + /* configure all serial ports */ + for (i = 0; i < ret; i++) { + /* read the I/O port from the device */ + pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)), + &ioport); + ioport &= 0x0000FF00; /* the actual base address */ + pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)), + ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | + ITE_887x_POSIO_IOSIZE_8 | ioport); + + /* write the ioport to the UARTBAR */ + pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar); + uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */ + uartbar |= (ioport << (16 * i)); /* set the ioport */ + pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar); + + /* get current config */ + pci_read_config_dword(dev, ITE_887x_MISCR, &miscr); + /* disable interrupts (UARTx_Routing[3:0]) */ + miscr &= ~(0xf << (12 - 4 * i)); + /* activate the UART (UARTx_En) */ + miscr |= 1 << (23 - i); + /* write new config with activated UART */ + pci_write_config_dword(dev, ITE_887x_MISCR, miscr); + } + + if (ret <= 0) { + /* the device has no UARTs if we get here */ + release_region(iobase->start, ITE_887x_IOSIZE); + } + + return ret; +} + +static void __devexit pci_ite887x_exit(struct pci_dev *dev) +{ + u32 ioport; + /* the ioport is bit 0-15 in POSIO0R */ + pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport); + ioport &= 0xffff; + release_region(ioport, ITE_887x_IOSIZE); +} + static int pci_default_setup(struct serial_private *priv, struct pciserial_board *board, struct uart_port *port, int idx) @@ -652,6 +784,18 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .init = pci_inteli960ni_init, .setup = pci_default_setup, }, + /* + * ITE + */ + { + .vendor = PCI_VENDOR_ID_ITE, + .device = PCI_DEVICE_ID_ITE_8872, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_ite887x_init, + .setup = pci_default_setup, + .exit = __devexit_p(pci_ite887x_exit), + }, /* * Panacom */ @@ -933,6 +1077,7 @@ enum pci_board_num_t { pbn_b1_2_1250000, + pbn_b1_bt_1_115200, pbn_b1_bt_2_921600, pbn_b1_1_1382400, @@ -1211,6 +1356,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { .uart_offset = 8, }, + [pbn_b1_bt_1_115200] = { + .flags = FL_BASE1|FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [pbn_b1_bt_2_921600] = { .flags = FL_BASE1|FL_BASE_BARS, .num_ports = 2, @@ -2364,6 +2516,13 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_1_115200 }, + /* + * ITE + */ + { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b1_bt_1_115200 }, /* * IntaShield IS-200 -- cgit v1.2.3 From 999999616e45c603da45ee2667741fb7348629a5 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 22 Aug 2007 14:01:15 -0700 Subject: serial_txx9: Fix modem control line handling This chip does not have modem control lines. Return TIOCM_CAR and TIOCM_DSR always on get_mctrl() and ajust some bits in termios cflag. Signed-off-by: Atsushi Nemoto Cc: Ralf Baechle Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/serial_txx9.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index b8f91e018b21..0930e2a85514 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -37,7 +37,7 @@ #include -static char *serial_version = "1.09"; +static char *serial_version = "1.10"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -436,8 +436,10 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) struct uart_txx9_port *up = (struct uart_txx9_port *)port; unsigned int ret; - ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) - | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); + /* no modem control lines */ + ret = TIOCM_CAR | TIOCM_DSR; + ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS; + ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS; return ret; } @@ -557,6 +559,12 @@ serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long flags; unsigned int baud, quot; + /* + * We don't support modem control lines. + */ + termios->c_cflag &= ~(HUPCL | CMSPAR); + termios->c_cflag |= CLOCAL; + cval = sio_in(up, TXX9_SILCR); /* byte size and parity */ cval &= ~TXX9_SILCR_UMODE_MASK; -- cgit v1.2.3 From ad4c2aa6354fad5316565b1cff57f80db0e04db8 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 22 Aug 2007 14:01:18 -0700 Subject: Serial 8250: handle saving the clear-on-read bits from the LSR and MSR Reading the LSR clears the break, parity, frame error, and overrun bits in the 8250 chip, but these are not being saved in all places that read the LSR. Same goes for the MSR delta bits. Save the LSR bits off whenever the lsr is read so they can be handled later in the receive routine. Save the MSR bits to be handled in the modem status routine. Also, clear the stored bits and clear the interrupt registers before enabling interrupts, to avoid handling old values of the stored bits in the interrupt routines. [akpm@linux-foundation.org: clean up pre-existing code] Signed-off-by: Corey Minyard Cc: Russell King Cc: Yinghai Lu Cc: Bjorn Helgaas Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250.c | 85 ++++++++++++++++++++++++++++++---------------- include/linux/serial_reg.h | 1 + 2 files changed, 57 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 301313002f6b..f94109cbb46e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -129,7 +129,16 @@ struct uart_8250_port { unsigned char mcr; unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ - unsigned char lsr_break_flag; + + /* + * Some bits in registers are cleared on a read, so they must + * be saved whenever the register is read but the bits will not + * be immediately processed. + */ +#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS + unsigned char lsr_saved_flags; +#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + unsigned char msr_saved_flags; /* * We provide a per-port pm hook. @@ -1238,6 +1247,7 @@ static void serial8250_start_tx(struct uart_port *port) if (up->bugs & UART_BUG_TXEN) { unsigned char lsr, iir; lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; iir = serial_in(up, UART_IIR) & 0x0f; if ((up->port.type == PORT_RM9000) ? (lsr & UART_LSR_THRE && @@ -1290,18 +1300,10 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) flag = TTY_NORMAL; up->port.icount.rx++; -#ifdef CONFIG_SERIAL_8250_CONSOLE - /* - * Recover the break flag from console xmit - */ - if (up->port.line == up->port.cons->index) { - lsr |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif + lsr |= up->lsr_saved_flags; + up->lsr_saved_flags = 0; - if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { + if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { /* * For statistics only */ @@ -1392,6 +1394,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) { unsigned int status = serial_in(up, UART_MSR); + status |= up->msr_saved_flags; + up->msr_saved_flags = 0; if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && up->port.info != NULL) { if (status & UART_MSR_TERI) @@ -1591,7 +1595,8 @@ static void serial8250_timeout(unsigned long data) static void serial8250_backup_timeout(unsigned long data) { struct uart_8250_port *up = (struct uart_8250_port *)data; - unsigned int iir, ier = 0; + unsigned int iir, ier = 0, lsr; + unsigned long flags; /* * Must disable interrupts or else we risk racing with the interrupt @@ -1610,9 +1615,13 @@ static void serial8250_backup_timeout(unsigned long data) * the "Diva" UART used on the management processor on many HP * ia64 and parisc boxes. */ + spin_lock_irqsave(&up->port.lock, flags); + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + spin_unlock_irqrestore(&up->port.lock, flags); if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && - (serial_in(up, UART_LSR) & UART_LSR_THRE)) { + (lsr & UART_LSR_THRE)) { iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); iir |= UART_IIR_THRI; } @@ -1631,13 +1640,14 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned long flags; - unsigned int ret; + unsigned int lsr; spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; spin_unlock_irqrestore(&up->port.lock, flags); - return ret; + return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; } static unsigned int serial8250_get_mctrl(struct uart_port *port) @@ -1708,8 +1718,7 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) do { status = serial_in(up, UART_LSR); - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; + up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; if (--tmout == 0) break; @@ -1718,8 +1727,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) /* Wait up to 1s for flow control if necessary */ if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { + unsigned int tmout; + for (tmout = 1000000; tmout; tmout--) { + unsigned int msr = serial_in(up, UART_MSR); + up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; + if (msr & UART_MSR_CTS) + break; udelay(1); touch_nmi_watchdog(); } @@ -1888,6 +1901,18 @@ static int serial8250_startup(struct uart_port *port) spin_unlock_irqrestore(&up->port.lock, flags); + /* + * Clear the interrupt registers again for luck, and clear the + * saved flags to avoid getting false values from polling + * routines or the previous session. + */ + serial_inp(up, UART_LSR); + serial_inp(up, UART_RX); + serial_inp(up, UART_IIR); + serial_inp(up, UART_MSR); + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently @@ -1906,14 +1931,6 @@ static int serial8250_startup(struct uart_port *port) (void) inb_p(icp); } - /* - * And clear the interrupt registers again for luck. - */ - (void) serial_inp(up, UART_LSR); - (void) serial_inp(up, UART_RX); - (void) serial_inp(up, UART_IIR); - (void) serial_inp(up, UART_MSR); - return 0; } @@ -2484,6 +2501,16 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) wait_for_xmitr(up, BOTH_EMPTY); serial_out(up, UART_IER, ier); + /* + * The receive handling will happen properly because the + * receive ready bit will still be set; it is not cleared + * on read. However, modem control will not, we must + * call it if we have saved something in the saved flags + * while processing with interrupts off. + */ + if (up->msr_saved_flags) + check_modem_status(up); + if (locked) spin_unlock(&up->port.lock); local_irq_restore(flags); diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 1c5ed7d92b0f..96c0d93fc2ca 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -118,6 +118,7 @@ #define UART_LSR_PE 0x04 /* Parity error indicator */ #define UART_LSR_OE 0x02 /* Overrun error indicator */ #define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ #define UART_MSR 6 /* In: Modem Status Register */ #define UART_MSR_DCD 0x80 /* Data Carrier Detect */ -- cgit v1.2.3 From 436bbd431d41e0fd3bfedb0312ab764b291ddf82 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Wed, 22 Aug 2007 14:01:19 -0700 Subject: Add blacklisting capability to serial_pci to avoid misdetection of serial ports The serial_pci driver tries to guess serial ports on unknown devices based on the PCI class (modem or serial). On certain softmodems (AC'97 modems) this can lead to the recognition of non-existing serial ports. This patch adds a blacklist of PCI IDs that are to be ignored by the driver. [akpm@linux-foundation.org: cleanups] Signed-off-by: Christian Schmidt Cc: Bjorn Helgaas Cc: Russell King Cc: Yinghai Lu Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index fd76542c5977..e3140e5b16cc 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1652,6 +1652,10 @@ static struct pciserial_board pci_boards[] __devinitdata = { }, }; +static const struct pci_device_id softmodem_blacklist[] = { + { PCI_VDEVICE ( AL, 0x5457 ), }, /* ALi Corporation M5457 AC'97 Modem */ +}; + /* * Given a complete unknown PCI device, try to use some heuristics to * guess what the configuration might be, based on the pitiful PCI @@ -1660,6 +1664,7 @@ static struct pciserial_board pci_boards[] __devinitdata = { static int __devinit serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) { + const struct pci_device_id *blacklist; int num_iomem, num_port, first_port = -1, i; /* @@ -1674,6 +1679,18 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) (dev->class & 0xff) > 6) return -ENODEV; + /* + * Do not access blacklisted devices that are known not to + * feature serial ports. + */ + for (blacklist = softmodem_blacklist; + blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist); + blacklist++) { + if (dev->vendor == blacklist->vendor && + dev->device == blacklist->device) + return -ENODEV; + } + num_iomem = num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) { -- cgit v1.2.3 From afe1ab4d577892822de2c8e803fbfaed6ec44ba3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 22 Aug 2007 14:01:27 -0700 Subject: correct name for rtc-m41t80 The new rtc-m41t80 driver name doesn't match its module name, which prevents it from properly hotplugging. Since it's new, no platforms yet depend on that name ... so this patch fixes the driver name to match its module name, rather than going the other way around with a MODULE_ALIAS(). NOTE: This sort of bug is a new thing to watch out for with new-style I2C drivers; previously I2C couldn't hotplug. Signed-off-by: David Brownell Acked-by: Atsushi Nemoto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-m41t80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 80c4a8463065..1cb33cac1237 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -892,7 +892,7 @@ static int m41t80_remove(struct i2c_client *client) static struct i2c_driver m41t80_driver = { .driver = { - .name = "m41t80", + .name = "rtc-m41t80", }, .probe = m41t80_probe, .remove = m41t80_remove, -- cgit v1.2.3 From 0d5e74fc7f44b1cdcd793496877c67a2a7a32a1e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Aug 2007 14:01:31 -0700 Subject: remove dead code in via-pmu68k When suspend is ever implemented for pmu68k it really should follow the generic pm_ops concept and not mirror the platform-specific /dev/pmu device with ioctls on it. Hence, this patch removes the unused code there; should the implementers need it they can look at via-pmu.c and/or the history of the file. Signed-off-by: Johannes Berg Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/via-pmu68k.c | 240 ----------------------------------------- 1 file changed, 240 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index dfdf11c1eec4..e2f84da09e7c 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -818,243 +818,3 @@ pmu_present(void) { return (pmu_kind != PMU_UNKNOWN); } - -#if 0 /* needs some work for 68K */ - -/* - * This struct is used to store config register values for - * PCI devices which may get powered off when we sleep. - */ -static struct pci_save { - u16 command; - u16 cache_lat; - u16 intr; -} *pbook_pci_saves; -static int n_pbook_pci_saves; - -static inline void -pbook_pci_save(void) -{ - int npci; - struct pci_dev *pd = NULL; - struct pci_save *ps; - - npci = 0; - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) - ++npci; - n_pbook_pci_saves = npci; - if (npci == 0) - return; - ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL); - pbook_pci_saves = ps; - if (ps == NULL) - return; - - pd = NULL; - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - pci_read_config_word(pd, PCI_COMMAND, &ps->command); - pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); - pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); - ++ps; - --npci; - } -} - -static inline void -pbook_pci_restore(void) -{ - u16 cmd; - struct pci_save *ps = pbook_pci_saves; - struct pci_dev *pd = NULL; - int j; - - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - if (ps->command == 0) - continue; - pci_read_config_word(pd, PCI_COMMAND, &cmd); - if ((ps->command & ~cmd) == 0) - continue; - switch (pd->hdr_type) { - case PCI_HEADER_TYPE_NORMAL: - for (j = 0; j < 6; ++j) - pci_write_config_dword(pd, - PCI_BASE_ADDRESS_0 + j*4, - pd->resource[j].start); - pci_write_config_dword(pd, PCI_ROM_ADDRESS, - pd->resource[PCI_ROM_RESOURCE].start); - pci_write_config_word(pd, PCI_CACHE_LINE_SIZE, - ps->cache_lat); - pci_write_config_word(pd, PCI_INTERRUPT_LINE, - ps->intr); - pci_write_config_word(pd, PCI_COMMAND, ps->command); - break; - /* other header types not restored at present */ - } - } -} - -/* - * Put the powerbook to sleep. - */ -#define IRQ_ENABLE ((unsigned int *)0xf3000024) -#define MEM_CTRL ((unsigned int *)0xf8000070) - -int powerbook_sleep(void) -{ - int ret, i, x; - static int save_backlight; - static unsigned int save_irqen; - unsigned long msr; - unsigned int hid0; - unsigned long p, wait; - struct adb_request sleep_req; - - /* Notify device drivers */ - ret = blocking_notifier_call_chain(&sleep_notifier_list, - PBOOK_SLEEP, NULL); - if (ret & NOTIFY_STOP_MASK) - return -EBUSY; - - /* Sync the disks. */ - /* XXX It would be nice to have some way to ensure that - * nobody is dirtying any new buffers while we wait. */ - sys_sync(); - - /* Turn off the display backlight */ - save_backlight = backlight_enabled; - if (save_backlight) - pmu_enable_backlight(0); - - /* Give the disks a little time to actually finish writing */ - for (wait = jiffies + (HZ/4); time_before(jiffies, wait); ) - mb(); - - /* Disable all interrupts except pmu */ - save_irqen = in_le32(IRQ_ENABLE); - for (i = 0; i < 32; ++i) - if (i != vias->intrs[0].line && (save_irqen & (1 << i))) - disable_irq(i); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - - /* Save the state of PCI config space for some slots */ - pbook_pci_save(); - - /* Set the memory controller to keep the memory refreshed - while we're asleep */ - for (i = 0x403f; i >= 0x4000; --i) { - out_be32(MEM_CTRL, i); - do { - x = (in_be32(MEM_CTRL) >> 16) & 0x3ff; - } while (x == 0); - if (x >= 0x100) - break; - } - - /* Ask the PMU to put us to sleep */ - pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); - while (!sleep_req.complete) - mb(); - /* displacement-flush the L2 cache - necessary? */ - for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000) - i = *(volatile int *)p; - asleep = 1; - - /* Put the CPU into sleep mode */ - asm volatile("mfspr %0,1008" : "=r" (hid0) :); - hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; - asm volatile("mtspr 1008,%0" : : "r" (hid0)); - local_save_flags(msr); - msr |= MSR_POW | MSR_EE; - local_irq_restore(msr); - udelay(10); - - /* OK, we're awake again, start restoring things */ - out_be32(MEM_CTRL, 0x3f); - pbook_pci_restore(); - - /* wait for the PMU interrupt sequence to complete */ - while (asleep) - mb(); - - /* reenable interrupts */ - for (i = 0; i < 32; ++i) - if (i != vias->intrs[0].line && (save_irqen & (1 << i))) - enable_irq(i); - - /* Notify drivers */ - blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); - - /* reenable ADB autopoll */ - pmu_adb_autopoll(adb_dev_map); - - /* Turn on the screen backlight, if it was on before */ - if (save_backlight) - pmu_enable_backlight(1); - - /* Wait for the hard disk to spin up */ - - return 0; -} - -/* - * Support for /dev/pmu device - */ -static int pmu_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t pmu_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static ssize_t pmu_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static int pmu_ioctl(struct inode * inode, struct file *filp, - u_int cmd, u_long arg) -{ - int error; - __u32 value; - - switch (cmd) { - case PMU_IOC_SLEEP: - return -ENOSYS; - case PMU_IOC_GET_BACKLIGHT: - return put_user(backlight_level, (__u32 *)arg); - case PMU_IOC_SET_BACKLIGHT: - error = get_user(value, (__u32 *)arg); - if (!error) - pmu_set_brightness(value); - return error; - case PMU_IOC_GET_MODEL: - return put_user(pmu_kind, (__u32 *)arg); - } - return -EINVAL; -} - -static const struct file_operations pmu_device_fops = { - .read = pmu_read, - .write = pmu_write, - .ioctl = pmu_ioctl, - .open = pmu_open, -}; - -static struct miscdevice pmu_device = { - PMU_MINOR, "pmu", &pmu_device_fops -}; - -void pmu_device_init(void) -{ - if (!via) - return; - if (misc_register(&pmu_device) < 0) - printk(KERN_ERR "via-pmu68k: cannot register misc device.\n"); -} -#endif /* CONFIG_PMAC_PBOOK */ - -- cgit v1.2.3 From 90638f9975e34aef82e97146012ad9d16ac9e4c2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:34 -0700 Subject: m68k: Fix a few hickups in drivers/scsi/Kconfig m68k: Fix a few hickups in drivers/scsi/Kconfig Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d2b3898b750a..a50b9553d5b1 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1561,7 +1561,7 @@ config A3000_SCSI built-in SCSI controller, say Y. Otherwise, say N. To compile this driver as a module, choose M here: the - module will be called wd33c93. + module will be called a3000. config A2091_SCSI tristate "A2091/A590 WD33C93A support" @@ -1571,7 +1571,7 @@ config A2091_SCSI say N. To compile this driver as a module, choose M here: the - module will be called wd33c93. + module will be called a2091. config GVP11_SCSI tristate "GVP Series II WD33C93A support" -- cgit v1.2.3 From a01086687c5f795a9c2b85d757e3af3cb7bb4f2d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:34 -0700 Subject: zorro: Make sysfs config attribute read-only zorro: Make the sysfs `config' attribute read-only, as you cannot write to it (there's no .write function neither). Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/zorro/zorro-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c index 9130f1c12c26..808b4f8675c5 100644 --- a/drivers/zorro/zorro-sysfs.c +++ b/drivers/zorro/zorro-sysfs.c @@ -78,7 +78,7 @@ static ssize_t zorro_read_config(struct kobject *kobj, static struct bin_attribute zorro_config_attr = { .attr = { .name = "config", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO, }, .size = sizeof(struct ConfigDev), .read = zorro_read_config, -- cgit v1.2.3 From 2301060e2b19aa4830060524ef66abdf32b26a26 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:35 -0700 Subject: m68k/mac: Make mac_hid_mouse_emulate_buttons() declaration visible m68k/mac: Make mac_hid_mouse_emulate_buttons() declaration visible drivers/char/keyboard.c: In function 'kbd_keycode': drivers/char/keyboard.c:1142: error: implicit declaration of function 'mac_hid_mouse_emulate_buttons' The forward declaration of mac_hid_mouse_emulate_buttons() is not visible on m68k because it's hidden in the middle of a big #ifdef block. Move it to , correct the type of the second parameter, and include where needed. Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/keyboard.c | 4 ---- drivers/macintosh/mac_hid.c | 1 + include/linux/kbd_kern.h | 3 +++ 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 2ce0af1bd588..d95f316afb5a 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1022,10 +1022,6 @@ static const unsigned short x86_keycodes[256] = 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; -#ifdef CONFIG_MAC_EMUMOUSEBTN -extern int mac_hid_mouse_emulate_buttons(int, int, int); -#endif /* CONFIG_MAC_EMUMOUSEBTN */ - #ifdef CONFIG_SPARC static int sparc_l1_a_state = 0; extern void sun_do_break(void); diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 76c1e8e4a487..33dee3a773ed 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct input_dev *emumousebtn; diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 506ad20c18f8..8bdb16bfe5fb 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -161,4 +161,7 @@ static inline void con_schedule_flip(struct tty_struct *t) schedule_delayed_work(&t->buf.work, 0); } +/* mac_hid.c */ +extern int mac_hid_mouse_emulate_buttons(int, unsigned int, int); + #endif -- cgit v1.2.3 From 928923c76b393e38e5ba1d47e843e208ceef6cf9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:36 -0700 Subject: Introduce CONFIG_CHECK_SIGNATURE Introduce CONFIG_CHECK_SIGNATURE to control inclusion of check_signature() and avoid problems on platforms that don't have readb(). Let the few legacy (ISA || PCI || X86) drivers that need check_signature() select CONFIG_CHECK_SIGNATURE. Signed-off-by: Geert Uytterhoeven Cc: Jeff Dike Cc: Heiko Carstens Cc: Roman Zippel Cc: Alan Cox Cc: Martin Schwidefsky Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/Kconfig | 1 + drivers/input/misc/Kconfig | 1 + drivers/scsi/Kconfig | 6 ++++++ lib/Kconfig | 3 +++ lib/Makefile | 3 ++- 5 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ef32e977d307..4245b7f80a49 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -68,6 +68,7 @@ config AMIGA_Z2RAM config BLK_DEV_XD tristate "XT hard disk support" depends on ISA && ISA_DMA_API + select CHECK_SIGNATURE help Very old 8 bit hard disk controllers used in the IBM XT computer will be supported if you say Y here. diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 9b26574f1466..d602b8fa7d46 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -68,6 +68,7 @@ config INPUT_WISTRON_BTNS select INPUT_POLLDEV select NEW_LEDS select LEDS_CLASS + select CHECK_SIGNATURE help Say Y here for support of Winstron laptop button interface, used on laptops of various brands, including Acer and Fujitsu-Siemens. If diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a50b9553d5b1..6f2c71ef47ee 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -367,6 +367,7 @@ config SCSI_3W_9XXX config SCSI_7000FASST tristate "7000FASST SCSI support" depends on ISA && SCSI && ISA_DMA_API + select CHECK_SIGNATURE help This driver supports the Western Digital 7000 SCSI host adapter family. Some information is in the source: @@ -388,6 +389,7 @@ config SCSI_AHA152X tristate "Adaptec AHA152X/2825 support" depends on ISA && SCSI && !64BIT select SCSI_SPI_ATTRS + select CHECK_SIGNATURE ---help--- This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. @@ -583,6 +585,7 @@ config SCSI_DTC3280 tristate "DTC3180/3280 SCSI support" depends on ISA && SCSI select SCSI_SPI_ATTRS + select CHECK_SIGNATURE help This is support for DTC 3180/3280 SCSI Host Adapters. Please read the SCSI-HOWTO, available from @@ -657,6 +660,7 @@ config SCSI_EATA_PIO config SCSI_FUTURE_DOMAIN tristate "Future Domain 16xx SCSI/AHA-2920A support" depends on (ISA || PCI) && SCSI + select CHECK_SIGNATURE ---help--- This is support for Future Domain's 16-bit SCSI host adapters (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and @@ -1324,6 +1328,7 @@ config SCSI_LPFC config SCSI_SEAGATE tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" depends on X86 && ISA && SCSI + select CHECK_SIGNATURE ---help--- These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, @@ -1397,6 +1402,7 @@ config SCSI_T128 tristate "Trantor T128/T128F/T228 SCSI support" depends on ISA && SCSI select SCSI_SPI_ATTRS + select CHECK_SIGNATURE ---help--- This is support for a SCSI host adapter. It is explained in section 3.11 of the SCSI-HOWTO, available from diff --git a/lib/Kconfig b/lib/Kconfig index e5c2c514174a..ba3d104994d9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -138,4 +138,7 @@ config HAS_DMA depends on !NO_DMA default y +config CHECK_SIGNATURE + bool + endmenu diff --git a/lib/Makefile b/lib/Makefile index d9e5f1cd0bfb..6b0ba8cf4e5f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,7 +21,8 @@ CFLAGS_kobject_uevent.o += -DDEBUG endif obj-$(CONFIG_GENERIC_IOMAP) += iomap.o -obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o check_signature.o +obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o +obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o -- cgit v1.2.3 From 32d219854d31daba3407389ada1d454a4cd86fda Mon Sep 17 00:00:00 2001 From: Mijo Safradin Date: Wed, 22 Aug 2007 14:01:48 -0700 Subject: IPMI: fix warning in ipmi_si_intf.c trivial change: fix warning Signed-off-by: Mijo Safradin Acked-by: Christian Krafft Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 96d2f9ee42d6..9b07f7851061 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2292,7 +2292,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->irq = irq_of_parse_and_map(dev->node, 0); info->dev = &dev->dev; - dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", + dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq); -- cgit v1.2.3 From d4c63b7c74507c424afcc9c80ba77a55bfb0d07e Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Wed, 22 Aug 2007 14:01:50 -0700 Subject: synclink_gt fix module reference Get module reference on open() by generic HDLC to prevent module from unloading while interface is active. Signed-off-by: Paul Fulghum Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/synclink_gt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index bbb7f1292665..2f97d2f8f916 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -1565,6 +1565,9 @@ static int hdlcdev_open(struct net_device *dev) int rc; unsigned long flags; + if (!try_module_get(THIS_MODULE)) + return -EBUSY; + DBGINFO(("%s hdlcdev_open\n", dev->name)); /* generic HDLC layer open processing */ @@ -1634,6 +1637,7 @@ static int hdlcdev_close(struct net_device *dev) info->netcount=0; spin_unlock_irqrestore(&info->netlock, flags); + module_put(THIS_MODULE); return 0; } -- cgit v1.2.3 From 59d9445e851976d973a5a4009f80a3d55959d231 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Wed, 22 Aug 2007 14:01:51 -0700 Subject: w1: fix w1_remove_master_device() searching In case bus master driver provided bogus value as its private data, search can be incorrect. Problem found by Adrian Bunk. Signed-off-by: Evgeniy Polyakov Cc: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/w1_int.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 2fbd8dd16df5..6840dfebe4d4 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -170,22 +170,24 @@ void __w1_remove_master_device(struct w1_master *dev) void w1_remove_master_device(struct w1_bus_master *bm) { - struct w1_master *dev = NULL; + struct w1_master *dev, *found = NULL; list_for_each_entry(dev, &w1_masters, w1_master_entry) { if (!dev->initialized) continue; - if (dev->bus_master->data == bm->data) + if (dev->bus_master->data == bm->data) { + found = dev; break; + } } - if (!dev) { + if (!found) { printk(KERN_ERR "Device doesn't exist.\n"); return; } - __w1_remove_master_device(dev); + __w1_remove_master_device(found); } EXPORT_SYMBOL(w1_add_master_device); -- cgit v1.2.3 From 918f02383fb9ff5dba29709f3199189eeac55021 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 22 Aug 2007 14:01:52 -0700 Subject: md: make sure a re-add after a restart honours bitmap when resyncing Commit 1757128438d41670ded8bc3bc735325cc07dc8f9 was slightly bad. If an array has a write-intent bitmap, and you remove a drive, then readd it, only the changed parts should be resynced. However after the above commit, this only works if the array has not been shut down and restarted. This is because it sets 'fullsync' at little more often than it should. This patch is more careful. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 650991bddd8e..ea2a58d28871 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1972,7 +1972,8 @@ static int run(mddev_t *mddev) !test_bit(In_sync, &disk->rdev->flags)) { disk->head_position = 0; mddev->degraded++; - conf->fullsync = 1; + if (disk->rdev) + conf->fullsync = 1; } } if (mddev->degraded == conf->raid_disks) { -- cgit v1.2.3 From a88aa7865bc1d1d451af2d585ac0119164ce8e00 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 22 Aug 2007 14:01:53 -0700 Subject: md: correctly update sysfs when a raid1 is reshaped When a raid1 array is reshaped (number of drives changed), the list of devices is compacted, so that slots for missing devices are filled with working devices from later slots. This requires the "rd%d" symlinks in sysfs to be updated. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ea2a58d28871..f33a729960ca 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2154,11 +2154,25 @@ static int raid1_reshape(mddev_t *mddev) oldpool = conf->r1bio_pool; conf->r1bio_pool = newpool; - for (d=d2=0; d < conf->raid_disks; d++) - if (conf->mirrors[d].rdev) { - conf->mirrors[d].rdev->raid_disk = d2; - newmirrors[d2++].rdev = conf->mirrors[d].rdev; + for (d = d2 = 0; d < conf->raid_disks; d++) { + mdk_rdev_t *rdev = conf->mirrors[d].rdev; + if (rdev && rdev->raid_disk != d2) { + char nm[20]; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + rdev->raid_disk = d2; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + if (sysfs_create_link(&mddev->kobj, + &rdev->kobj, nm)) + printk(KERN_WARNING + "md/raid1: cannot register " + "%s for %s\n", + nm, mdname(mddev)); } + if (rdev) + newmirrors[d2++].rdev = rdev; + } kfree(conf->mirrors); conf->mirrors = newmirrors; kfree(conf->poolinfo); -- cgit v1.2.3 From aa7985056286f5f912af7bb03f883230cc527701 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 22 Aug 2007 14:01:55 -0700 Subject: serial: add pci ids for PA Semi PWRficient onchip uarts Add PCI IDs for the onchip UARTs on PA Semi PWRficient. Signed-off-by: Olof Johansson Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index e3140e5b16cc..bd66339f7a3f 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1128,6 +1128,7 @@ enum pci_board_num_t { pbn_exar_XR17C152, pbn_exar_XR17C154, pbn_exar_XR17C158, + pbn_pasemi_1682M, }; /* @@ -1650,6 +1651,14 @@ static struct pciserial_board pci_boards[] __devinitdata = { .base_baud = 921600, .uart_offset = 0x200, }, + /* + * PA Semi PWRficient PA6T-1682M on-chip UART + */ + [pbn_pasemi_1682M] = { + .flags = FL_BASE0, + .num_ports = 1, + .base_baud = 8333333, + }, }; static const struct pci_device_id softmodem_blacklist[] = { @@ -2557,6 +2566,13 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, 0, 0, pbn_b2_8_921600 }, + /* + * PA Semi PA6T-1682M on-chip UART + */ + { PCI_VENDOR_ID_PASEMI, 0xa004, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_pasemi_1682M }, + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL -- cgit v1.2.3 From fe58103a56f05613cb1f0ef228354d4d5f6c2b08 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 22 Aug 2007 14:01:56 -0700 Subject: cfag12864b fix This one-liner patch fixes a bug in drivers/auxdisplay/cfag12864b.c At cfag12864b_init(), the driver tries to kalloc some memory in the variable cfag12864b_cache. Then, as usual, it checks if the call failed. However, it checks cfag12864b_buffer instead. This patch changes the "cfag12864b_buffer" to "cfag12864b_cache" so the correct variable is checked. Signed-off-by: Miguel Ojeda Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/auxdisplay/cfag12864b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index cb44cb4f6a47..80bb06105387 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -355,7 +355,7 @@ static int __init cfag12864b_init(void) cfag12864b_cache = kmalloc(sizeof(unsigned char) * CFAG12864B_SIZE, GFP_KERNEL); - if (cfag12864b_buffer == NULL) { + if (cfag12864b_cache == NULL) { printk(KERN_ERR CFAG12864B_NAME ": ERROR: " "can't alloc cache buffer (%i bytes)\n", CFAG12864B_SIZE); -- cgit v1.2.3 From 5c076fce2e217240b44bc753a5ec8ecd379c6eb9 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 22 Aug 2007 14:01:57 -0700 Subject: rtc-max6902 minor fixes Minor tweaks to rtc-max6902: make it hotplug correctly, and fix a few space-before-tab whitespace botches. This driver has no current in-tree users, so the hotplug fix changes the driver name. Signed-off-by: David Brownell Cc: Atsushi Nemoto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-max6902.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index d94170728075..3e183cfee10f 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -13,7 +13,7 @@ * * 24-May-2006: Raphael Assenat * - Major rework - * Converted to rtc_device and uses the SPI layer. + * Converted to rtc_device and uses the SPI layer. * * ??-???-2005: Someone at Compulab * - Initial driver creation. @@ -259,11 +259,11 @@ static int __devexit max6902_remove(struct spi_device *spi) static struct spi_driver max6902_driver = { .driver = { - .name = "max6902", + .name = "rtc-max6902", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = max6902_probe, + .probe = max6902_probe, .remove = __devexit_p(max6902_remove), }; -- cgit v1.2.3 From de5986dd3a102b8ae34bf08fe6f45b62b57ab2eb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 22 Aug 2007 14:02:00 -0700 Subject: Check for PPC32 in imsttfb This is the correct fix according to Paul Mackerras and allows an allyesconfig on PPC64 to build. Signed-off-by: Stephen Rothwell Cc: Paul Mackerras Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/imsttfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 5715b8ad0ddc..94f4511023d8 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -1391,7 +1391,7 @@ init_imstt(struct fb_info *info) } } -#if USE_NV_MODES && defined(CONFIG_PPC) +#if USE_NV_MODES && defined(CONFIG_PPC32) { int vmode = init_vmode, cmode = init_cmode; -- cgit v1.2.3 From 4ae8aeae47e0f014ec453c4b75c9de00bd29e9e6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 22 Aug 2007 14:02:01 -0700 Subject: newport_con warning fix drivers/video/console/newport_con.c: In function `newport_console_init': drivers/video/console/newport_con.c:743: warning: return makes integer from pointer without a cast Although one wonders whether that should have been -ENODEV... Cc: "Antonino A. Daplas" Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/newport_con.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 7fa1afeae8dc..dda0586ab3f3 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -738,9 +738,8 @@ const struct consw newport_con = { #ifdef MODULE static int __init newport_console_init(void) { - if (!sgi_gfxaddr) - return NULL; + return 0; if (!npregs) npregs = (struct newport_regs *)/* ioremap cannot fail */ -- cgit v1.2.3 From 8e92f21ba3ea3f54e4be062b87ef9fc4af2d33e2 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 22 Aug 2007 14:02:03 -0700 Subject: au1100fb: move au1100fb_fb_blank() beforce au1100fb_setmode() au1100fb_fb_blank() should come before au1100fb_setmode(). drivers/video/au1100fb.c: In function 'au1100fb_setmode': drivers/video/au1100fb.c:211: error: implicit declaration of function 'au1100fb_fb_blank' Signed-off-by: Yoichi Yuasa Cc: "Antonino A. Daplas" Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/au1100fb.c | 92 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 80a81eccad36..832e4613673a 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -115,6 +115,52 @@ static int nocursor = 0; module_param(nocursor, int, 0644); MODULE_PARM_DESC(nocursor, "cursor enable/disable"); +/* fb_blank + * Blank the screen. Depending on the mode, the screen will be + * activated with the backlight color, or desactivated + */ +static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) +{ + struct au1100fb_device *fbdev = to_au1100fb_device(fbi); + + print_dbg("fb_blank %d %p", blank_mode, fbi); + + switch (blank_mode) { + + case VESA_NO_BLANKING: + /* Turn on panel */ + fbdev->regs->lcd_control |= LCD_CONTROL_GO; +#ifdef CONFIG_MIPS_PB1100 + if (drv_info.panel_idx == 1) { + au_writew(au_readw(PB1100_G_CONTROL) + | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), + PB1100_G_CONTROL); + } +#endif + au_sync(); + break; + + case VESA_VSYNC_SUSPEND: + case VESA_HSYNC_SUSPEND: + case VESA_POWERDOWN: + /* Turn off panel */ + fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; +#ifdef CONFIG_MIPS_PB1100 + if (drv_info.panel_idx == 1) { + au_writew(au_readw(PB1100_G_CONTROL) + & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), + PB1100_G_CONTROL); + } +#endif + au_sync(); + break; + default: + break; + + } + return 0; +} + /* * Set hardware with var settings. This will enable the controller with a specific * mode, normally validated with the fb_check_var method @@ -272,52 +318,6 @@ int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned return 0; } -/* fb_blank - * Blank the screen. Depending on the mode, the screen will be - * activated with the backlight color, or desactivated - */ -int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) -{ - struct au1100fb_device *fbdev = to_au1100fb_device(fbi); - - print_dbg("fb_blank %d %p", blank_mode, fbi); - - switch (blank_mode) { - - case VESA_NO_BLANKING: - /* Turn on panel */ - fbdev->regs->lcd_control |= LCD_CONTROL_GO; -#ifdef CONFIG_MIPS_PB1100 - if (drv_info.panel_idx == 1) { - au_writew(au_readw(PB1100_G_CONTROL) - | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), - PB1100_G_CONTROL); - } -#endif - au_sync(); - break; - - case VESA_VSYNC_SUSPEND: - case VESA_HSYNC_SUSPEND: - case VESA_POWERDOWN: - /* Turn off panel */ - fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; -#ifdef CONFIG_MIPS_PB1100 - if (drv_info.panel_idx == 1) { - au_writew(au_readw(PB1100_G_CONTROL) - & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), - PB1100_G_CONTROL); - } -#endif - au_sync(); - break; - default: - break; - - } - return 0; -} - /* fb_pan_display * Pan display in x and/or y as specified */ -- cgit v1.2.3