diff -uarN linux-2.6.3-ref/drivers/message/fusion/Kconfig linux-2.6.3/drivers/message/fusion/Kconfig --- linux-2.6.3-ref/drivers/message/fusion/Kconfig 2004-02-17 20:59:59.000000000 -0700 +++ linux-2.6.3/drivers/message/fusion/Kconfig 2004-02-24 17:19:50.000000000 -0700 @@ -3,7 +3,6 @@ config FUSION tristate "Fusion MPT (base + ScsiHost) drivers" - depends on BLK_DEV_SD ---help--- LSI Logic Fusion(TM) Message Passing Technology (MPT) device support provides high performance SCSI host initiator, and LAN [1] interface @@ -14,41 +13,6 @@ [1] LAN is not supported on parallel SCSI medium. - These drivers require a Fusion MPT compatible PCI adapter installed - in the host system. MPT adapters contain specialized I/O processors - to handle I/O workload, and more importantly to offload this work - from the host CPU(s). - - If you have Fusion MPT hardware and want to use it, you can say - Y or M here to add MPT (base + ScsiHost) drivers. - = build lib (fusion), and link [static] into the kernel [2] - proper - = compiled as [dynamic] modules [3] named: (mptbase, - mptscsih) - - [2] In order enable capability to boot the linux kernel - natively from a Fusion MPT target device, you MUST - answer Y here! (currently requires CONFIG_BLK_DEV_SD) - [3] To compile this support as modules, choose M here. - - If unsure, say N. - - If you say Y or M here you will get a choice of these - additional protocol and support module options: Module Name: - Enhanced SCSI error reporting (isense) - Fusion MPT misc device (ioctl) driver (mptctl) - Fusion MPT LAN driver (mptlan) - - --- - Fusion MPT is trademark of LSI Logic Corporation, and its - architecture is based on LSI Logic's Message Passing Interface (MPI) - specification. - -config FUSION_BOOT - bool - depends on FUSION=y - default y - config FUSION_MAX_SGE int "Maximum number of scatter gather entries" depends on FUSION @@ -62,7 +26,6 @@ necessary (or recommended) unless the user will be running large I/O's via the raw interface. -# How can we force these options to module or nothing? config FUSION_ISENSE tristate "Enhanced SCSI error reporting" depends on MODULES && FUSION && m @@ -132,17 +95,4 @@ If unsure whether you really want or need this, say N. - NOTES: This feature is NOT available nor supported for linux-2.2.x - kernels. You must be building a linux-2.3.x or linux-2.4.x kernel - in order to configure this option. - Support for building this feature into the linux kernel is not - yet available. - -# if [ "$CONFIG_FUSION_LAN" != "n" ]; then -# define_bool CONFIG_NET_FC y -# fi -# These be define_tristate, but we leave them define_bool -# for backward compatibility with pre-linux-2.2.15 kernels. -# (Bugzilla:fibrebugs, #384) endmenu - diff -uarN linux-2.6.3-ref/drivers/message/fusion/mptbase.c linux-2.6.3/drivers/message/fusion/mptbase.c --- linux-2.6.3-ref/drivers/message/fusion/mptbase.c 2004-02-17 20:57:20.000000000 -0700 +++ linux-2.6.3/drivers/message/fusion/mptbase.c 2004-02-24 17:17:53.000000000 -0700 @@ -714,6 +714,7 @@ MptCallbacks[i] = cbfunc; MptDriverClass[i] = dclass; MptEvHandlers[i] = NULL; + MptDeviceDriverHandlers[i] = NULL; last_drv_idx = i; if (cbfunc != mpt_base_reply) { mpt_inc_use_count(); @@ -838,11 +839,28 @@ int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) { - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) - return -1; + MPT_ADAPTER *ioc; + int error=0; + + if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) { + error= -EINVAL; + return error; + } MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; - return 0; + + /* call per pci device probe entry point */ + for(ioc = mpt_adapter_find_first(); ioc != NULL; + ioc = mpt_adapter_find_next(ioc)) { + if(dd_cbfunc->probe) { + error = dd_cbfunc->probe(ioc->pcidev, + ioc->pcidev->driver->id_table); + if(error != 0) + return error; + } + } + + return error; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1497,14 +1515,20 @@ || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X)) mpt_detect_bound_ports(ioc, pdev); - if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { - printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n", - ioc->name, r); - } - - if(r != 0 ) + if ((r = mpt_do_ioc_recovery(ioc, + MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { + printk(KERN_WARNING MYNAM + ": WARNING - %s did not initialize properly! (%d)\n", + ioc->name, r); + + Q_DEL_ITEM(ioc); + mpt_adapters[ioc->id] = NULL; + free_irq(ioc->pci_irq, ioc); + iounmap(mem); + kfree(ioc); + pci_set_drvdata(pdev, NULL); return r; - + } /* call per device driver probe entry point */ for(ii=0; iifacts.NumberOfPorts; portnum++) { @@ -1542,8 +1543,10 @@ */ sz = hd->ioc->req_depth * sizeof(void *); mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) + if (mem == NULL) { + error = -ENOMEM; goto mptscsih_probe_failed; + } memset(mem, 0, sz); hd->ScsiLookup = (struct scsi_cmnd **) mem; @@ -1551,15 +1554,19 @@ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", ioc->name, hd->ScsiLookup, sz)); - if (mptscsih_initChainBuffers(hd, 1) < 0) + if (mptscsih_initChainBuffers(hd, 1) < 0) { + error = -EINVAL; goto mptscsih_probe_failed; + } /* Allocate memory for free and doneQ's */ sz = sh->can_queue * sizeof(MPT_DONE_Q); mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) + if (mem == NULL) { + error = -ENOMEM; goto mptscsih_probe_failed; + } memset(mem, 0xFF, sz); hd->memQ = mem; @@ -1591,8 +1598,10 @@ */ sz = sh->max_id * sizeof(void *); mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) + if (mem == NULL) { + error = -ENOMEM; goto mptscsih_probe_failed; + } memset(mem, 0, sz); hd->Targets = (VirtDevice **) mem; @@ -1683,7 +1692,8 @@ mpt_scsi_hosts++; - if(scsi_add_host (sh, &ioc->pcidev->dev)) { + error = scsi_add_host (sh, &ioc->pcidev->dev); + if(error) { dprintk((KERN_ERR MYNAM, "scsi_add_host failed\n")); goto mptscsih_probe_failed; @@ -1691,7 +1701,6 @@ scsi_scan_host(sh); return 0; - } /* scsi_host_alloc */ } /* for each adapter port */ @@ -1699,8 +1708,7 @@ mptscsih_probe_failed: mptscsih_remove(pdev); - return -ENODEV; - + return error; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1710,7 +1718,7 @@ * * */ -static void __devexit +static void mptscsih_remove(struct pci_dev *pdev) { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); @@ -1828,6 +1836,7 @@ } scsi_host_put(host); + mpt_scsi_hosts--; } @@ -1911,7 +1920,7 @@ static struct mpt_pci_driver mptscsih_driver = { .probe = mptscsih_probe, - .remove = __devexit_p(mptscsih_remove), + .remove = mptscsih_remove, .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, @@ -1928,10 +1937,9 @@ * * Returns 0 for success, non-zero for failure. */ -static int -__init mptscsih_init(void) +static int __init +mptscsih_init(void) { - MPT_ADAPTER *ioc; show_mptmod_ver(my_NAME, my_VERSION); @@ -1939,12 +1947,6 @@ ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER); ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER); - if(mpt_device_driver_register(&mptscsih_driver, - MPTSCSIH_DRIVER) != 0 ) { - dprintk((KERN_INFO MYNAM - ": failed to register dd callbacks\n")); - } - if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) { dprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); @@ -1961,20 +1963,13 @@ mptscsih_setup(mptscsih); #endif - /* probing for devices */ - for(ioc = mpt_adapter_find_first(); ioc != NULL; - ioc = mpt_adapter_find_next(ioc)) { - if(mptscsih_probe(ioc->pcidev, ioc->pcidev->driver->id_table)) { - dprintk((KERN_INFO MYNAM ": probe failed\n")); - return -ENODEV; - } + if(mpt_device_driver_register(&mptscsih_driver, + MPTSCSIH_DRIVER) != 0 ) { + dprintk((KERN_INFO MYNAM + ": failed to register dd callbacks\n")); } - if (mpt_scsi_hosts > 0) - return 0; - - mptscsih_exit(); - return -ENODEV; + return 0; } @@ -1984,7 +1979,7 @@ * mptscsih_exit - Unregisters MPT adapter(s) * */ -static void +static void __exit mptscsih_exit(void) { MPT_ADAPTER *ioc;