diff options
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/lsi/mpi.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/lsi/mpi_cnfg.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/lsi/mpi_history.txt | 6 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.c | 121 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 19 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 14 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptdebug.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 14 | ||||
-rw-r--r-- | drivers/message/fusion/mptlan.c | 28 | ||||
-rw-r--r-- | drivers/message/fusion/mptlan.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 56 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 6 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 12 | ||||
-rw-r--r-- | drivers/message/i2o/device.c | 54 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_config.c | 12 |
18 files changed, 249 insertions, 107 deletions
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 1acbdd61b670..10b6ef758725 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi.h diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index 2bd8adae0f00..b2db3330c591 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_cnfg.h diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 241592ab13ad..3f15fcfe4a2e 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt @@ -127,7 +127,7 @@ mpi_ioc.h * 08-08-01 01.02.01 Original release for v1.2 work. * New format for FWVersion and ProductId in * MSG_IOC_FACTS_REPLY and MPI_FW_HEADER. - * 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and + * 08-31-01 01.02.02 Added event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and * related structure and defines. * Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED. * Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE. @@ -187,7 +187,7 @@ mpi_ioc.h * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED. * Added MaxInitiators field to PortFacts reply. * Added SAS Device Status Change ReasonCode for - * asynchronous notificaiton. + * asynchronous notification. * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event * data structure. * Added new ImageType values for FWDownload and FWUpload @@ -213,7 +213,7 @@ mpi_cnfg.h * Added _RESPONSE_ID_MASK definition to SCSI_PORT_1 * page and updated the page version. * Added Information field and _INFO_PARAMS_NEGOTIATED - * definitionto SCSI_DEVICE_0 page. + * definition to SCSI_DEVICE_0 page. * 06-22-00 01.00.03 Removed batch controls from LAN_0 page and updated the * page version. * Added BucketsRemaining to LAN_1 page, redefined the diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index db3c892f87fb..d6a0074b9dc3 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -5,7 +5,7 @@ * For use with LSI PCI chip/adapter(s) * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -103,7 +103,7 @@ static int mfcounter = 0; * Public data... */ -struct proc_dir_entry *mpt_proc_root_dir; +static struct proc_dir_entry *mpt_proc_root_dir; #define WHOINIT_UNKNOWN 0xAA @@ -253,6 +253,55 @@ mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) return 0; } +/** + * mpt_fault_reset_work - work performed on workq after ioc fault + * @work: input argument, used to derive ioc + * +**/ +static void +mpt_fault_reset_work(struct work_struct *work) +{ + MPT_ADAPTER *ioc = + container_of(work, MPT_ADAPTER, fault_reset_work.work); + u32 ioc_raw_state; + int rc; + unsigned long flags; + + if (ioc->diagPending || !ioc->active) + goto out; + + ioc_raw_state = mpt_GetIocState(ioc, 0); + if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { + printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", + ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); + printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", + ioc->name, __func__); + rc = mpt_HardResetHandler(ioc, CAN_SLEEP); + printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, + __func__, (rc == 0) ? "success" : "failed"); + ioc_raw_state = mpt_GetIocState(ioc, 0); + if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) + printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " + "reset (%04xh)\n", ioc->name, ioc_raw_state & + MPI_DOORBELL_DATA_MASK); + } + + out: + /* + * Take turns polling alternate controller + */ + if (ioc->alt_ioc) + ioc = ioc->alt_ioc; + + /* rearm the timer */ + spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); + if (ioc->reset_work_q) + queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, + msecs_to_jiffies(MPT_POLLING_INTERVAL)); + spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); +} + + /* * Process turbo (context) reply... */ @@ -307,7 +356,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", - __FUNCTION__, ioc->name, cb_idx); + __func__, ioc->name, cb_idx); goto out; } @@ -371,7 +420,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", - __FUNCTION__, ioc->name, cb_idx); + __func__, ioc->name, cb_idx); freeme = 0; goto out; } @@ -1616,6 +1665,23 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) /* Find lookup slot. */ INIT_LIST_HEAD(&ioc->list); + + /* Initialize workqueue */ + INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); + spin_lock_init(&ioc->fault_reset_work_lock); + + snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name), + "mpt_poll_%d", ioc->id); + ioc->reset_work_q = + create_singlethread_workqueue(ioc->reset_work_q_name); + if (!ioc->reset_work_q) { + printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", + ioc->name); + pci_release_selected_regions(pdev, ioc->bars); + kfree(ioc); + return -ENOMEM; + } + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", ioc->name, &ioc->facts, &ioc->pfacts[0])); @@ -1686,9 +1752,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->bus_type = SAS; } - if (ioc->bus_type == SAS && mpt_msi_enable == -1) - ioc->msi_enable = 1; - else + if (mpt_msi_enable == -1) { + /* Enable on SAS, disable on FC and SPI */ + if (ioc->bus_type == SAS) + ioc->msi_enable = 1; + else + ioc->msi_enable = 0; + } else + /* follow flag: 0 - disable; 1 - enable */ ioc->msi_enable = mpt_msi_enable; if (ioc->errata_flag_1064) @@ -1722,6 +1793,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) iounmap(ioc->memmap); if (r != -5) pci_release_selected_regions(pdev, ioc->bars); + + destroy_workqueue(ioc->reset_work_q); + ioc->reset_work_q = NULL; + kfree(ioc); pci_set_drvdata(pdev, NULL); return r; @@ -1754,6 +1829,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) } #endif + if (!ioc->alt_ioc) + queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, + msecs_to_jiffies(MPT_POLLING_INTERVAL)); + return 0; } @@ -1769,6 +1848,19 @@ mpt_detach(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); char pname[32]; u8 cb_idx; + unsigned long flags; + struct workqueue_struct *wq; + + /* + * Stop polling ioc for fault condition + */ + spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); + wq = ioc->reset_work_q; + ioc->reset_work_q = NULL; + spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); + cancel_delayed_work(&ioc->fault_reset_work); + destroy_workqueue(wq); + sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); remove_proc_entry(pname, NULL); @@ -2342,7 +2434,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) if (ioc->cached_fw != NULL) { ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " - "adapter\n", __FUNCTION__, ioc->name)); + "adapter\n", __func__, ioc->name)); if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) ioc->cached_fw, CAN_SLEEP)) < 0) { printk(MYIOC_s_WARN_FMT @@ -3601,7 +3693,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " - "address=%p\n", ioc->name, __FUNCTION__, + "address=%p\n", ioc->name, __func__, &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); if (sleepFlag == CAN_SLEEP) @@ -4650,12 +4742,12 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) break; } - printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode); + printk("%s: persist_opcode=%x\n",__func__, persist_opcode); /* Get a MF for this command. */ if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { - printk("%s: no msg frames!\n",__FUNCTION__); + printk("%s: no msg frames!\n",__func__); return -1; } @@ -4679,13 +4771,13 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) (SasIoUnitControlReply_t *)ioc->persist_reply_frame; if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", - __FUNCTION__, + __func__, sasIoUnitCntrReply->IOCStatus, sasIoUnitCntrReply->IOCLogInfo); return -1; } - printk("%s: success\n",__FUNCTION__); + printk("%s: success\n",__func__); return 0; } @@ -5692,7 +5784,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", - ioc->name,__FUNCTION__)); + ioc->name,__func__)); return -1; } @@ -7451,7 +7543,6 @@ EXPORT_SYMBOL(mpt_resume); EXPORT_SYMBOL(mpt_suspend); #endif EXPORT_SYMBOL(ioc_list); -EXPORT_SYMBOL(mpt_proc_root_dir); EXPORT_SYMBOL(mpt_register); EXPORT_SYMBOL(mpt_deregister); EXPORT_SYMBOL(mpt_event_register); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index a8f617447d22..dff048cfa101 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -73,11 +73,11 @@ #endif #ifndef COPYRIGHT -#define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR +#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.06" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.06" +#define MPT_LINUX_VERSION_COMMON "3.04.07" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.07" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -176,6 +176,8 @@ /* debug print string length used for events and iocstatus */ # define EVENT_DESCR_STR_SZ 100 +#define MPT_POLLING_INTERVAL 1000 /* in milliseconds */ + #ifdef __KERNEL__ /* { */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -705,10 +707,16 @@ typedef struct _MPT_ADAPTER u8 fc_link_speed[2]; spinlock_t fc_rescan_work_lock; struct work_struct fc_rescan_work; - char fc_rescan_work_q_name[KOBJ_NAME_LEN]; + char fc_rescan_work_q_name[20]; struct workqueue_struct *fc_rescan_work_q; struct scsi_cmnd **ScsiLookup; spinlock_t scsi_lookup_lock; + + char reset_work_q_name[20]; + struct workqueue_struct *reset_work_q; + struct delayed_work fault_reset_work; + spinlock_t fault_reset_work_lock; + } MPT_ADAPTER; /* @@ -919,7 +927,6 @@ extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhys * Public data decl's... */ extern struct list_head ioc_list; -extern struct proc_dir_entry *mpt_proc_root_dir; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index e630b50966ec..f5233f3d9eff 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -4,7 +4,7 @@ * For use with LSI PCI chip/adapters * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -66,7 +66,7 @@ #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> -#define COPYRIGHT "Copyright (c) 1999-2007 LSI Corporation" +#define COPYRIGHT "Copyright (c) 1999-2008 LSI Corporation" #define MODULEAUTHOR "LSI Corporation" #include "mptbase.h" #include "mptctl.h" @@ -505,7 +505,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) event = le32_to_cpu(pEvReply->Event) & 0xFF; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n", - ioc->name, __FUNCTION__)); + ioc->name, __func__)); if(async_queue == NULL) return 1; @@ -548,11 +548,15 @@ static int mptctl_fasync(int fd, struct file *filep, int mode) { MPT_ADAPTER *ioc; + int ret; + lock_kernel(); list_for_each_entry(ioc, &ioc_list, list) ioc->aen_event_read_flag=0; - return fasync_helper(fd, filep, mode, &async_queue); + ret = fasync_helper(fd, filep, mode, &async_queue); + unlock_kernel(); + return ret; } static int @@ -2478,7 +2482,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) */ if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", - ioc->name,__FUNCTION__)); + ioc->name,__func__)); goto out; } diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 2c1890127e15..d564cc9ada6a 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptdebug.h b/drivers/message/fusion/mptdebug.h index ffdb0a6191b4..510b9f492093 100644 --- a/drivers/message/fusion/mptdebug.h +++ b/drivers/message/fusion/mptdebug.h @@ -3,7 +3,7 @@ * For use with LSI PCI chip/adapter(s) * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 1e24ab4ac38c..c3c24fdf9fb6 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -3,7 +3,7 @@ * For use with LSI PCI chip/adapter(s) * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -231,28 +231,28 @@ static int mptfc_abort(struct scsi_cmnd *SCpnt) { return - mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__); + mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__); } static int mptfc_dev_reset(struct scsi_cmnd *SCpnt) { return - mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__); + mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__); } static int mptfc_bus_reset(struct scsi_cmnd *SCpnt) { return - mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__); + mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__); } static int mptfc_host_reset(struct scsi_cmnd *SCpnt) { return - mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__); + mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __func__); } static void @@ -1326,8 +1326,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* initialize workqueue */ - snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d", - sh->host_no); + snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name), + "mptfc_wq_%d", sh->host_no); ioc->fc_rescan_work_q = create_singlethread_workqueue(ioc->fc_rescan_work_q_name); if (!ioc->fc_rescan_work_q) diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 7950fc678ed1..a1abf95cf751 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -4,7 +4,7 @@ * For use with LSI Fibre Channel PCI chip/adapters * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2007 LSI Corporation + * Copyright (c) 2000-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -610,7 +610,7 @@ mpt_lan_send_turbo(struct net_device *dev, u32 tmsg) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __FUNCTION__, sent)); + __func__, sent)); priv->SendCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, @@ -676,7 +676,7 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __FUNCTION__, sent)); + __func__, sent)); priv->SendCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, @@ -715,7 +715,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) u16 cur_naa = 0x1000; dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n", - __FUNCTION__, skb)); + __func__, skb)); spin_lock_irqsave(&priv->txfidx_lock, flags); if (priv->mpt_txfidx_tail < 0) { @@ -723,7 +723,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&priv->txfidx_lock, flags); printk (KERN_ERR "%s: no tx context available: %u\n", - __FUNCTION__, priv->mpt_txfidx_tail); + __func__, priv->mpt_txfidx_tail); return 1; } @@ -733,7 +733,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&priv->txfidx_lock, flags); printk (KERN_ERR "%s: Unable to alloc request frame\n", - __FUNCTION__); + __func__); return 1; } @@ -1208,7 +1208,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __FUNCTION__, buckets, curr)); + __func__, buckets, curr)); max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); @@ -1217,9 +1217,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) mf = mpt_get_msg_frame(LanCtx, mpt_dev); if (mf == NULL) { printk (KERN_ERR "%s: Unable to alloc request frame\n", - __FUNCTION__); + __func__); dioprintk((KERN_ERR "%s: %u buckets remaining\n", - __FUNCTION__, buckets)); + __func__, buckets)); goto out; } pRecvReq = (LANReceivePostRequest_t *) mf; @@ -1244,7 +1244,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) spin_lock_irqsave(&priv->rxfidx_lock, flags); if (priv->mpt_rxfidx_tail < 0) { printk (KERN_ERR "%s: Can't alloc context\n", - __FUNCTION__); + __func__); spin_unlock_irqrestore(&priv->rxfidx_lock, flags); break; @@ -1267,7 +1267,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) if (skb == NULL) { printk (KERN_WARNING MYNAM "/%s: Can't alloc skb\n", - __FUNCTION__); + __func__); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); break; @@ -1305,7 +1305,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) if (pSimple == NULL) { /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", -/**/ __FUNCTION__); +/**/ __func__); mpt_free_msg_frame(mpt_dev, mf); goto out; } @@ -1329,9 +1329,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) out: dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n", - __FUNCTION__, buckets, atomic_read(&priv->buckets_out))); + __func__, buckets, atomic_read(&priv->buckets_out))); dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n", - __FUNCTION__, priv->total_posted, priv->total_received)); + __func__, priv->total_posted, priv->total_received)); clear_bit(0, &priv->post_buckets_active); } diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h index bafb67fc8181..33927ee7dc3b 100644 --- a/drivers/message/fusion/mptlan.h +++ b/drivers/message/fusion/mptlan.h @@ -4,7 +4,7 @@ * For use with LSI Fibre Channel PCI chip/adapters * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2007 LSI Corporation + * Copyright (c) 2000-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 4d492ba232b0..12b732512e57 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -3,7 +3,7 @@ * For use with LSI PCI chip/adapter(s) * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -300,7 +300,7 @@ mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_detai phy_info = port_info->phy_info; dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d " - "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details, + "bitmask=0x%016llX\n", ioc->name, __func__, port_details, port_details->num_phys, (unsigned long long) port_details->phy_bitmask)); @@ -411,7 +411,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) */ dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: deleting phy = %d\n", - ioc->name, __FUNCTION__, port_details, i)); + ioc->name, __func__, port_details, i)); port_details->num_phys--; port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); @@ -497,7 +497,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) continue; dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: phy_id=%02d num_phys=%02d " - "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, + "bitmask=0x%016llX\n", ioc->name, __func__, port_details, i, port_details->num_phys, (unsigned long long)port_details->phy_bitmask)); dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n", @@ -553,7 +553,7 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id) if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n", - ioc->name,__FUNCTION__, __LINE__)); + ioc->name,__func__, __LINE__)); return 0; } @@ -606,7 +606,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, GFP_ATOMIC); if (!target_reset_list) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", - ioc->name,__FUNCTION__, __LINE__)); + ioc->name,__func__, __LINE__)); return; } @@ -673,7 +673,7 @@ mptsas_dev_reset_complete(MPT_ADAPTER *ioc) ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", - ioc->name,__FUNCTION__, __LINE__)); + ioc->name,__func__, __LINE__)); return; } @@ -1183,7 +1183,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", - ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo); + ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo); error = -ENXIO; goto out_unlock; } @@ -1270,14 +1270,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, if (!rsp) { printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", - ioc->name, __FUNCTION__); + ioc->name, __func__); return -EINVAL; } /* do we need to support multiple segments? */ if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n", - ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len, + ioc->name, __func__, req->bio->bi_vcnt, req->data_len, rsp->bio->bi_vcnt, rsp->data_len); return -EINVAL; } @@ -1343,7 +1343,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); if (!timeleft) { - printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__); + printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__); /* On timeout reset the board */ mpt_HardResetHandler(ioc, CAN_SLEEP); ret = -ETIMEDOUT; @@ -1361,7 +1361,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, rsp->data_len -= smprep->ResponseDataLength; } else { printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", - ioc->name, __FUNCTION__); + ioc->name, __func__); ret = -ENXIO; } unmap: @@ -2006,7 +2006,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (error) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); goto out; } mptsas_set_port(ioc, phy_info, port); @@ -2076,7 +2076,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (!rphy) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); goto out; } @@ -2085,7 +2085,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (error) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); sas_rphy_free(rphy); goto out; } @@ -2613,7 +2613,7 @@ mptsas_hotplug_work(struct work_struct *work) (ev->channel << 8) + ev->id)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } phy_info = mptsas_find_phyinfo_by_sas_address( @@ -2633,20 +2633,20 @@ mptsas_hotplug_work(struct work_struct *work) if (!phy_info){ dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } if (!phy_info->port_details) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } rphy = mptsas_get_rphy(phy_info); if (!rphy) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } @@ -2654,7 +2654,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!port) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } @@ -2665,7 +2665,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!vtarget) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } @@ -2720,7 +2720,7 @@ mptsas_hotplug_work(struct work_struct *work) (ev->channel << 8) + ev->id)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } @@ -2732,7 +2732,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!phy_info || !phy_info->port_details) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } @@ -2744,7 +2744,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!vtarget) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } /* @@ -2767,7 +2767,7 @@ mptsas_hotplug_work(struct work_struct *work) if (mptsas_get_rphy(phy_info)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); if (ev->channel) printk("%d\n", __LINE__); break; } @@ -2776,7 +2776,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!port) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; } memcpy(&phy_info->attached, &sas_device, @@ -2801,7 +2801,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!rphy) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); break; /* non-fatal: an rphy can be added later */ } @@ -2809,7 +2809,7 @@ mptsas_hotplug_work(struct work_struct *work) if (sas_rphy_add(rphy)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + __func__, __LINE__)); sas_rphy_free(rphy); break; } diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h index 7c150f50629a..2b544e0877e6 100644 --- a/drivers/message/fusion/mptsas.h +++ b/drivers/message/fusion/mptsas.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index c68ef00c2f92..9f9354fd3516 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -3,7 +3,7 @@ * For use with LSI PCI chip/adapter(s) * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -461,7 +461,7 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n", - ioc->name,__FUNCTION__)); + ioc->name,__func__)); return; } @@ -2187,7 +2187,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m (ioc->debug_level & MPT_DEBUG_TM )) printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " - "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus, + "term_cmnds=%d\n", __func__, ioc->id, pScsiTmReply->Bus, pScsiTmReply->TargetID, pScsiTmReq->TaskType, le16_to_cpu(pScsiTmReply->IOCStatus), le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 7ea7da0e090c..319aa3033371 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 25bcfcf36f2e..61620144e49c 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -3,7 +3,7 @@ * For use with LSI PCI chip/adapter(s) * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Corporation + * Copyright (c) 1999-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -447,6 +447,7 @@ static int mptspi_target_alloc(struct scsi_target *starget) spi_max_offset(starget) = ioc->spi_data.maxSyncOffset; spi_offset(starget) = 0; + spi_period(starget) = 0xFF; mptspi_write_width(starget, 0); return 0; @@ -1266,13 +1267,18 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) static int mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); int rc; rc = mptscsih_ioc_reset(ioc, reset_phase); - if (reset_phase == MPT_IOC_POST_RESET) + /* only try to do a renegotiation if we're properly set up + * if we get an ioc fault on bringup, ioc->sh will be NULL */ + if (reset_phase == MPT_IOC_POST_RESET && + ioc->sh) { + struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); + mptspi_dv_renegotiate(hd); + } return rc; } diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index 489d7c5c4965..8774c670e668 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c @@ -243,29 +243,41 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) /* create user entries for this device */ tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); - if (tmp && (tmp != i2o_dev)) - sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, - "user"); + if (tmp && (tmp != i2o_dev)) { + rc = sysfs_create_link(&i2o_dev->device.kobj, + &tmp->device.kobj, "user"); + if (rc) + goto unreg_dev; + } /* create user entries refering to this device */ list_for_each_entry(tmp, &c->devices, list) if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) - sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "user"); + && (tmp != i2o_dev)) { + rc = sysfs_create_link(&tmp->device.kobj, + &i2o_dev->device.kobj, "user"); + if (rc) + goto rmlink1; + } /* create parent entries for this device */ tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); - if (tmp && (tmp != i2o_dev)) - sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, - "parent"); + if (tmp && (tmp != i2o_dev)) { + rc = sysfs_create_link(&i2o_dev->device.kobj, + &tmp->device.kobj, "parent"); + if (rc) + goto rmlink1; + } /* create parent entries refering to this device */ list_for_each_entry(tmp, &c->devices, list) if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) - sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "parent"); + && (tmp != i2o_dev)) { + rc = sysfs_create_link(&tmp->device.kobj, + &i2o_dev->device.kobj, "parent"); + if (rc) + goto rmlink2; + } i2o_driver_notify_device_add_all(i2o_dev); @@ -273,6 +285,24 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) return 0; +rmlink2: + /* If link creating failed halfway, we loop whole list to cleanup. + * And we don't care wrong removing of link, because sysfs_remove_link + * will take care of it. + */ + list_for_each_entry(tmp, &c->devices, list) { + if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) + sysfs_remove_link(&tmp->device.kobj, "parent"); + } + sysfs_remove_link(&i2o_dev->device.kobj, "parent"); +rmlink1: + list_for_each_entry(tmp, &c->devices, list) + if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) + sysfs_remove_link(&tmp->device.kobj, "user"); + sysfs_remove_link(&i2o_dev->device.kobj, "user"); +unreg_dev: + list_del(&i2o_dev->list); + device_unregister(&i2o_dev->device); err: kfree(i2o_dev); return rc; diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index c0fb77dc19bb..4238de98d4a6 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -1061,6 +1061,7 @@ static int cfg_open(struct inode *inode, struct file *file) if (!tmp) return -ENOMEM; + lock_kernel(); file->private_data = (void *)(i2o_cfg_info_id++); tmp->fp = file; tmp->fasync = NULL; @@ -1074,6 +1075,7 @@ static int cfg_open(struct inode *inode, struct file *file) spin_lock_irqsave(&i2o_config_lock, flags); open_files = tmp; spin_unlock_irqrestore(&i2o_config_lock, flags); + unlock_kernel(); return 0; } @@ -1082,15 +1084,17 @@ static int cfg_fasync(int fd, struct file *fp, int on) { ulong id = (ulong) fp->private_data; struct i2o_cfg_info *p; + int ret = -EBADF; + lock_kernel(); for (p = open_files; p; p = p->next) if (p->q_id == id) break; - if (!p) - return -EBADF; - - return fasync_helper(fd, fp, on, &p->fasync); + if (p) + ret = fasync_helper(fd, fp, on, &p->fasync); + unlock_kernel(); + return ret; } static int cfg_release(struct inode *inode, struct file *file) |