diff --git a/qla_isp/common/isp_tpublic.h b/qla_isp/common/isp_tpublic.h index 82102a671..08f8cd5e8 100644 --- a/qla_isp/common/isp_tpublic.h +++ b/qla_isp/common/isp_tpublic.h @@ -1,4 +1,4 @@ -/* $Id: isp_tpublic.h,v 1.41 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: isp_tpublic.h,v 1.42 2008/02/27 21:00:26 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -360,6 +360,12 @@ typedef struct tmd_xact { #ifndef QCDS #define QCDS (sizeof (uint64_t)) #endif +#ifndef TMD_PRIV_LO +#define TMD_PRIV_LO 4 +#endif +#ifndef TMD_PRIV_HI +#define TMD_PRIV_HI 4 +#endif struct tmd_cmd { void * cd_hba; /* HBA tag */ @@ -383,7 +389,7 @@ struct tmd_cmd { uint32_t longs[QCDS / sizeof (uint32_t)]; /* two longs */ uint16_t shorts[QCDS / sizeof (uint16_t)]; /* four shorts */ uint8_t bytes[QCDS]; /* eight bytes */ - } cd_lreserved[4], cd_hreserved[4]; + } cd_lreserved[TMD_PRIV_LO], cd_hreserved[TMD_PRIV_HI]; }; #define CDF_NODISC 0x0001 /* disconnects disabled */ diff --git a/qla_isp/linux/isp_linux.c b/qla_isp/linux/isp_linux.c index d2551eb66..ac6180c8a 100644 --- a/qla_isp/linux/isp_linux.c +++ b/qla_isp/linux/isp_linux.c @@ -1,4 +1,4 @@ -/* $Id: isp_linux.c,v 1.226 2008/02/12 00:40:51 mjacob Exp $ */ +/* $Id: isp_linux.c,v 1.227 2008/02/27 21:02:34 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -3114,6 +3114,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) if (lp->ini_map_idx) { tgt = lp->ini_map_idx - 1; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived at", tgt, lp->node_wwn, lp->port_wwn); + ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, 0, 0, __FUNCTION__, __LINE__); } else { isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", lp->node_wwn, lp->port_wwn); } @@ -3159,6 +3160,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) lp->state = FC_PORTDB_STATE_NIL; lp->ini_map_idx = 0; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", tgt, lp->node_wwn, lp->port_wwn); + ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, 0, 0, __FUNCTION__, __LINE__); } else if (lp->reserved == 0) { isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", lp->node_wwn, lp->port_wwn); } @@ -4333,25 +4335,9 @@ isplinux_reinit(ispsoftc_t *isp) } } isp->isp_osinfo.host->max_lun = min(maxluns, ISP_MAX_LUNS(isp)); - -#if 0 - /* - * If we're not taking a role, set some 'defaults' and turn off lasers (for FC cards). - */ - if (isp->isp_osinfo.role == ISP_ROLE_NONE) { - isp->isp_osinfo.host->can_queue = 16; - isp->isp_osinfo.host->can_queue = 1; - isp->isp_osinfo.host->cmd_per_lun = 1; - isp->isp_osinfo.host->this_id = IS_FC(isp)? MAX_FC_TARG : 7; - isp_shutdown(isp); - return (0); - } -#else - isp->isp_osinfo.host->can_queue = 16; isp->isp_osinfo.host->can_queue = 1; isp->isp_osinfo.host->cmd_per_lun = 1; isp->isp_osinfo.host->this_id = IS_FC(isp)? MAX_FC_TARG : 7; -#endif isp_init(isp); if (isp->isp_state != ISP_INITSTATE) { @@ -4513,6 +4499,9 @@ isp_task_thread(void *arg) switch (tap->thread_action) { case ISP_THREAD_NIL: break; + case ISP_THREAD_SCSI_SCAN: + scsi_scan_host(isp->isp_osinfo.host); + break; #ifdef ISP_FW_CRASH_DUMP case ISP_THREAD_FW_CRASH_DUMP: ISP_LOCKU_SOFTC(isp); diff --git a/qla_isp/linux/isp_linux.h b/qla_isp/linux/isp_linux.h index ad99c09f3..7ce671c83 100644 --- a/qla_isp/linux/isp_linux.h +++ b/qla_isp/linux/isp_linux.h @@ -276,6 +276,7 @@ typedef struct { ISP_THREAD_TERMINATE, ISP_THREAD_RESTART_AT7, ISP_THREAD_FC_PUTBACK, + ISP_THREAD_SCSI_SCAN, } thread_action; void * arg; struct semaphore * thread_waiter; diff --git a/qla_isp/linux/isp_pci.c b/qla_isp/linux/isp_pci.c index a0469b085..4ce6c8b36 100644 --- a/qla_isp/linux/isp_pci.c +++ b/qla_isp/linux/isp_pci.c @@ -1,4 +1,4 @@ -/* $Id: isp_pci.c,v 1.161 2008/02/12 00:40:51 mjacob Exp $ */ +/* $Id: isp_pci.c,v 1.162 2008/02/27 21:03:06 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -509,16 +509,16 @@ isplinux_pci_release(struct Scsi_Host *host) static void pci_intx(struct pci_dev *pdev, int enable) { - u16 pci_command, new; - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if (enable) { - new = pci_command & ~PCI_COMMAND_INTX_DISABLE; - } else { - new = pci_command | PCI_COMMAND_INTX_DISABLE; - } - if (new != pci_command) { - pci_write_config_word(pdev, PCI_COMMAND, new); - } + u16 pci_command, new; + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); + if (enable) { + new = pci_command & ~PCI_COMMAND_INTX_DISABLE; + } else { + new = pci_command | PCI_COMMAND_INTX_DISABLE; + } + if (new != pci_command) { + pci_write_config_word(pdev, PCI_COMMAND, new); + } } #endif @@ -898,6 +898,7 @@ isplinux_pci_init_one(struct Scsi_Host *host) } } +#ifdef CONFIG_FW_LOADER if (fwname) { if (request_firmware(&isp->isp_osinfo.fwp, fwname, &pdev->dev) == 0) { isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.fwp->data; @@ -924,6 +925,7 @@ isplinux_pci_init_one(struct Scsi_Host *host) isp_prt(isp, ISP_LOGCONFIG, "unable to load firmware set \"%s\"", fwname); } } +#endif if (isplinux_common_init(isp)) { isp_prt(isp, ISP_LOGERR, "isplinux_common_init failed"); @@ -940,10 +942,12 @@ bad: isp_kfree(isp->isp_osinfo.storep, isp->isp_osinfo.storep_amt); isp->isp_osinfo.storep = NULL; } +#ifdef CONFIG_FW_LOADER if (isp->isp_osinfo.fwp) { release_firmware(isp->isp_osinfo.fwp); isp->isp_osinfo.fwp = NULL; } +#endif ISP_DISABLE_INTS(isp); if (host->irq) { free_irq(host->irq, isp_pci); @@ -3453,10 +3457,12 @@ isplinux_pci_remove(struct pci_dev *pdev) isp_deinit_target(isp); #endif scsi_host_put(host); +#ifdef CONFIG_FW_LOADER if (isp->isp_osinfo.fwp) { release_firmware(isp->isp_osinfo.fwp); isp->isp_osinfo.fwp = NULL; } +#endif pci_set_drvdata(pdev, NULL); } @@ -3499,7 +3505,7 @@ isplinux_pci_init(void) } ret = pci_register_driver(&isplinux_pci_driver); if (ret < 0) { - printk(KERN_ERR "%s: unable to register driver (return value %d)", __FUNCTION__, ret); + printk(KERN_ERR "%s: unable to register driver (return value %d)", __FUNCTION__, ret); unregister_chrdev_region(isp_dev, MAX_ISP); return (ret); } diff --git a/qla_isp/linux/scsi_target.c b/qla_isp/linux/scsi_target.c index 74d79687a..8e2c58bd9 100644 --- a/qla_isp/linux/scsi_target.c +++ b/qla_isp/linux/scsi_target.c @@ -1,4 +1,4 @@ -/* $Id: scsi_target.c,v 1.81 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: scsi_target.c,v 1.82 2008/02/27 21:01:12 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -297,7 +297,7 @@ typedef struct { wce : 1, overcommit : 1, enabled : 1; - struct semaphore sema; + wait_queue_head_t whook; tmd_cmd_t * u_front; tmd_cmd_t * u_tail; uint64_t nbytes; @@ -1717,8 +1717,8 @@ out: lp->u_front = tmd; } lp->u_tail = tmd; - up(&lp->sema); spin_unlock_irqrestore(&scsi_target_lock, flags); + wake_up_all(&lp->whook); return (1); } else { xact->td_hflags |= TDFH_STSVALID; @@ -1945,7 +1945,7 @@ scsi_target_handler(qact_e action, void *arg) } lp->u_tail = tmd; spin_unlock_irqrestore(&scsi_target_lock, flags); - up(&lp->sema); + wake_up_all(&lp->whook); break; } spin_unlock_irqrestore(&scsi_target_lock, flags); @@ -2329,7 +2329,7 @@ scsi_target_start_user_io(sc_io_t *sc) lp = &bp->bchan[sc->channel].luns[sc->lun]; SDprintk2("%s: waiting for a R/W IO operation\n", __FUNCTION__); - if (down_interruptible(&lp->sema)) { + if (wait_event_interruptible(lp->whook, (lp->u_front != NULL))) { return (-EINTR); } spin_lock_irqsave(&scsi_target_lock, flags); @@ -2538,7 +2538,7 @@ scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int chan, int lun, int e scsi_free_disk(bp, chan, lun); } else { lp->u_tail = lp->u_front = NULL; - sema_init(&lp->sema, 0); + init_waitqueue_head(&lp->whook); lp->wce = 1; lp->enabled = 1; }