aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2006-06-26 01:31:38 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2006-06-26 01:31:38 -0400
commit4854c7b27f0975a2b629f35ea3996d2968eb7c4f (patch)
tree4102bdb70289764a2058aff0f907b13d7cf0e0d1 /drivers/message
parent3cbd5b32cb625f5c0f1b1476d154fac873dd49ce (diff)
parentfcc18e83e1f6fd9fa6b333735bf0fcd530655511 (diff)
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptbase.c252
-rw-r--r--drivers/message/fusion/mptbase.h16
-rw-r--r--drivers/message/fusion/mptfc.c394
-rw-r--r--drivers/message/fusion/mptscsih.c23
-rw-r--r--drivers/message/fusion/mptspi.c2
-rw-r--r--drivers/message/i2o/exec-osm.c72
-rw-r--r--drivers/message/i2o/i2o_scsi.c4
-rw-r--r--drivers/message/i2o/iop.c4
8 files changed, 510 insertions, 257 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 9080853fe283..12dd8d493ee2 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -63,9 +63,6 @@
63#ifdef CONFIG_MTRR 63#ifdef CONFIG_MTRR
64#include <asm/mtrr.h> 64#include <asm/mtrr.h>
65#endif 65#endif
66#ifdef __sparc__
67#include <asm/irq.h> /* needed for __irq_itoa() proto */
68#endif
69 66
70#include "mptbase.h" 67#include "mptbase.h"
71 68
@@ -1188,7 +1185,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1188 ioc->pcidev = pdev; 1185 ioc->pcidev = pdev;
1189 ioc->diagPending = 0; 1186 ioc->diagPending = 0;
1190 spin_lock_init(&ioc->diagLock); 1187 spin_lock_init(&ioc->diagLock);
1191 spin_lock_init(&ioc->fc_rescan_work_lock);
1192 spin_lock_init(&ioc->initializing_hba_lock); 1188 spin_lock_init(&ioc->initializing_hba_lock);
1193 1189
1194 /* Initialize the event logging. 1190 /* Initialize the event logging.
@@ -1386,39 +1382,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1386 /* Set lookup ptr. */ 1382 /* Set lookup ptr. */
1387 list_add_tail(&ioc->list, &ioc_list); 1383 list_add_tail(&ioc->list, &ioc_list);
1388 1384
1389 ioc->pci_irq = -1;
1390 if (pdev->irq) {
1391 if (mpt_msi_enable && !pci_enable_msi(pdev))
1392 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name);
1393
1394 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1395
1396 if (r < 0) {
1397#ifndef __sparc__
1398 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1399 ioc->name, pdev->irq);
1400#else
1401 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1402 ioc->name, __irq_itoa(pdev->irq));
1403#endif
1404 list_del(&ioc->list);
1405 iounmap(mem);
1406 kfree(ioc);
1407 return -EBUSY;
1408 }
1409
1410 ioc->pci_irq = pdev->irq;
1411
1412 pci_set_master(pdev); /* ?? */
1413 pci_set_drvdata(pdev, ioc);
1414
1415#ifndef __sparc__
1416 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1417#else
1418 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1419#endif
1420 }
1421
1422 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. 1385 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1423 */ 1386 */
1424 mpt_detect_bound_ports(ioc, pdev); 1387 mpt_detect_bound_ports(ioc, pdev);
@@ -1428,11 +1391,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1428 printk(KERN_WARNING MYNAM 1391 printk(KERN_WARNING MYNAM
1429 ": WARNING - %s did not initialize properly! (%d)\n", 1392 ": WARNING - %s did not initialize properly! (%d)\n",
1430 ioc->name, r); 1393 ioc->name, r);
1431
1432 list_del(&ioc->list); 1394 list_del(&ioc->list);
1433 free_irq(ioc->pci_irq, ioc);
1434 if (mpt_msi_enable)
1435 pci_disable_msi(pdev);
1436 if (ioc->alt_ioc) 1395 if (ioc->alt_ioc)
1437 ioc->alt_ioc->alt_ioc = NULL; 1396 ioc->alt_ioc->alt_ioc = NULL;
1438 iounmap(mem); 1397 iounmap(mem);
@@ -1605,6 +1564,21 @@ mpt_resume(struct pci_dev *pdev)
1605} 1564}
1606#endif 1565#endif
1607 1566
1567static int
1568mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1569{
1570 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1571 ioc->bus_type != SPI) ||
1572 (MptDriverClass[index] == MPTFC_DRIVER &&
1573 ioc->bus_type != FC) ||
1574 (MptDriverClass[index] == MPTSAS_DRIVER &&
1575 ioc->bus_type != SAS))
1576 /* make sure we only call the relevant reset handler
1577 * for the bus */
1578 return 0;
1579 return (MptResetHandlers[index])(ioc, reset_phase);
1580}
1581
1608/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1582/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1609/* 1583/*
1610 * mpt_do_ioc_recovery - Initialize or recover MPT adapter. 1584 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
@@ -1636,6 +1610,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1636 int handlers; 1610 int handlers;
1637 int ret = 0; 1611 int ret = 0;
1638 int reset_alt_ioc_active = 0; 1612 int reset_alt_ioc_active = 0;
1613 int irq_allocated = 0;
1639 1614
1640 printk(KERN_INFO MYNAM ": Initiating %s %s\n", 1615 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1641 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); 1616 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
@@ -1719,6 +1694,36 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1719 } 1694 }
1720 } 1695 }
1721 1696
1697 /*
1698 * Device is reset now. It must have de-asserted the interrupt line
1699 * (if it was asserted) and it should be safe to register for the
1700 * interrupt now.
1701 */
1702 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1703 ioc->pci_irq = -1;
1704 if (ioc->pcidev->irq) {
1705 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1706 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1707 ioc->name);
1708 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1709 SA_SHIRQ, ioc->name, ioc);
1710 if (rc < 0) {
1711 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1712 "interrupt %d!\n", ioc->name,
1713 ioc->pcidev->irq);
1714 if (mpt_msi_enable)
1715 pci_disable_msi(ioc->pcidev);
1716 return -EBUSY;
1717 }
1718 irq_allocated = 1;
1719 ioc->pci_irq = ioc->pcidev->irq;
1720 pci_set_master(ioc->pcidev); /* ?? */
1721 pci_set_drvdata(ioc->pcidev, ioc);
1722 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1723 "%d\n", ioc->name, ioc->pcidev->irq));
1724 }
1725 }
1726
1722 /* Prime reply & request queues! 1727 /* Prime reply & request queues!
1723 * (mucho alloc's) Must be done prior to 1728 * (mucho alloc's) Must be done prior to
1724 * init as upper addresses are needed for init. 1729 * init as upper addresses are needed for init.
@@ -1818,7 +1823,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1818 ret = mptbase_sas_persist_operation(ioc, 1823 ret = mptbase_sas_persist_operation(ioc,
1819 MPI_SAS_OP_CLEAR_NOT_PRESENT); 1824 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1820 if(ret != 0) 1825 if(ret != 0)
1821 return -1; 1826 goto out;
1822 } 1827 }
1823 1828
1824 /* Find IM volumes 1829 /* Find IM volumes
@@ -1826,14 +1831,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1826 mpt_findImVolumes(ioc); 1831 mpt_findImVolumes(ioc);
1827 1832
1828 } else if (ioc->bus_type == FC) { 1833 } else if (ioc->bus_type == FC) {
1829 /*
1830 * Pre-fetch FC port WWN and stuff...
1831 * (FCPortPage0_t stuff)
1832 */
1833 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1834 (void) mptbase_GetFcPortPage0(ioc, ii);
1835 }
1836
1837 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && 1834 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1838 (ioc->lan_cnfg_page0.Header.PageLength == 0)) { 1835 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1839 /* 1836 /*
@@ -1885,20 +1882,26 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1885 if ((ret == 0) && MptResetHandlers[ii]) { 1882 if ((ret == 0) && MptResetHandlers[ii]) {
1886 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n", 1883 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1887 ioc->name, ii)); 1884 ioc->name, ii));
1888 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET); 1885 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1889 handlers++; 1886 handlers++;
1890 } 1887 }
1891 1888
1892 if (alt_ioc_ready && MptResetHandlers[ii]) { 1889 if (alt_ioc_ready && MptResetHandlers[ii]) {
1893 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", 1890 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1894 ioc->name, ioc->alt_ioc->name, ii)); 1891 ioc->name, ioc->alt_ioc->name, ii));
1895 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); 1892 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1896 handlers++; 1893 handlers++;
1897 } 1894 }
1898 } 1895 }
1899 /* FIXME? Examine results here? */ 1896 /* FIXME? Examine results here? */
1900 } 1897 }
1901 1898
1899out:
1900 if ((ret != 0) && irq_allocated) {
1901 free_irq(ioc->pci_irq, ioc);
1902 if (mpt_msi_enable)
1903 pci_disable_msi(ioc->pcidev);
1904 }
1902 return ret; 1905 return ret;
1903} 1906}
1904 1907
@@ -2273,7 +2276,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2273 } 2276 }
2274 2277
2275 if (sleepFlag == CAN_SLEEP) { 2278 if (sleepFlag == CAN_SLEEP) {
2276 msleep_interruptible(1); 2279 msleep(1);
2277 } else { 2280 } else {
2278 mdelay (1); /* 1 msec delay */ 2281 mdelay (1); /* 1 msec delay */
2279 } 2282 }
@@ -2661,7 +2664,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2661 state = mpt_GetIocState(ioc, 1); 2664 state = mpt_GetIocState(ioc, 1);
2662 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { 2665 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2663 if (sleepFlag == CAN_SLEEP) { 2666 if (sleepFlag == CAN_SLEEP) {
2664 msleep_interruptible(1); 2667 msleep(1);
2665 } else { 2668 } else {
2666 mdelay(1); 2669 mdelay(1);
2667 } 2670 }
@@ -2913,7 +2916,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2913 2916
2914 /* wait 1 msec */ 2917 /* wait 1 msec */
2915 if (sleepFlag == CAN_SLEEP) { 2918 if (sleepFlag == CAN_SLEEP) {
2916 msleep_interruptible(1); 2919 msleep(1);
2917 } else { 2920 } else {
2918 mdelay (1); 2921 mdelay (1);
2919 } 2922 }
@@ -2930,7 +2933,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2930 } 2933 }
2931 /* wait .1 sec */ 2934 /* wait .1 sec */
2932 if (sleepFlag == CAN_SLEEP) { 2935 if (sleepFlag == CAN_SLEEP) {
2933 msleep_interruptible (100); 2936 msleep (100);
2934 } else { 2937 } else {
2935 mdelay (100); 2938 mdelay (100);
2936 } 2939 }
@@ -3020,7 +3023,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3020 3023
3021 /* wait 1 msec */ 3024 /* wait 1 msec */
3022 if (sleepFlag == CAN_SLEEP) { 3025 if (sleepFlag == CAN_SLEEP) {
3023 msleep_interruptible (1); 3026 msleep (1);
3024 } else { 3027 } else {
3025 mdelay (1); 3028 mdelay (1);
3026 } 3029 }
@@ -3068,7 +3071,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3068 return 0; 3071 return 0;
3069 } 3072 }
3070 if (sleepFlag == CAN_SLEEP) { 3073 if (sleepFlag == CAN_SLEEP) {
3071 msleep_interruptible (10); 3074 msleep (10);
3072 } else { 3075 } else {
3073 mdelay (10); 3076 mdelay (10);
3074 } 3077 }
@@ -3119,7 +3122,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3119 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); 3122 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3120 3123
3121 if (sleepFlag == CAN_SLEEP) { 3124 if (sleepFlag == CAN_SLEEP) {
3122 msleep_interruptible (1000); 3125 msleep (1000);
3123 } else { 3126 } else {
3124 mdelay (1000); 3127 mdelay (1000);
3125 } 3128 }
@@ -3141,7 +3144,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3141 return hard_reset_done; 3144 return hard_reset_done;
3142 } 3145 }
3143 if (sleepFlag == CAN_SLEEP) { 3146 if (sleepFlag == CAN_SLEEP) {
3144 msleep_interruptible (10); 3147 msleep (10);
3145 } else { 3148 } else {
3146 mdelay (10); 3149 mdelay (10);
3147 } 3150 }
@@ -3212,7 +3215,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3212 3215
3213 /* wait 100 msec */ 3216 /* wait 100 msec */
3214 if (sleepFlag == CAN_SLEEP) { 3217 if (sleepFlag == CAN_SLEEP) {
3215 msleep_interruptible (100); 3218 msleep (100);
3216 } else { 3219 } else {
3217 mdelay (100); 3220 mdelay (100);
3218 } 3221 }
@@ -3267,11 +3270,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3267 if (MptResetHandlers[ii]) { 3270 if (MptResetHandlers[ii]) {
3268 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n", 3271 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3269 ioc->name, ii)); 3272 ioc->name, ii));
3270 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET); 3273 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3271 if (ioc->alt_ioc) { 3274 if (ioc->alt_ioc) {
3272 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n", 3275 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3273 ioc->name, ioc->alt_ioc->name, ii)); 3276 ioc->name, ioc->alt_ioc->name, ii));
3274 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET); 3277 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3275 } 3278 }
3276 } 3279 }
3277 } 3280 }
@@ -3291,7 +3294,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3291 3294
3292 /* wait 1 sec */ 3295 /* wait 1 sec */
3293 if (sleepFlag == CAN_SLEEP) { 3296 if (sleepFlag == CAN_SLEEP) {
3294 msleep_interruptible (1000); 3297 msleep (1000);
3295 } else { 3298 } else {
3296 mdelay (1000); 3299 mdelay (1000);
3297 } 3300 }
@@ -3319,7 +3322,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3319 3322
3320 /* wait 1 sec */ 3323 /* wait 1 sec */
3321 if (sleepFlag == CAN_SLEEP) { 3324 if (sleepFlag == CAN_SLEEP) {
3322 msleep_interruptible (1000); 3325 msleep (1000);
3323 } else { 3326 } else {
3324 mdelay (1000); 3327 mdelay (1000);
3325 } 3328 }
@@ -3353,7 +3356,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3353 3356
3354 /* wait 100 msec */ 3357 /* wait 100 msec */
3355 if (sleepFlag == CAN_SLEEP) { 3358 if (sleepFlag == CAN_SLEEP) {
3356 msleep_interruptible (100); 3359 msleep (100);
3357 } else { 3360 } else {
3358 mdelay (100); 3361 mdelay (100);
3359 } 3362 }
@@ -3447,7 +3450,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3447 } 3450 }
3448 3451
3449 if (sleepFlag == CAN_SLEEP) { 3452 if (sleepFlag == CAN_SLEEP) {
3450 msleep_interruptible(1); 3453 msleep(1);
3451 } else { 3454 } else {
3452 mdelay (1); /* 1 msec delay */ 3455 mdelay (1); /* 1 msec delay */
3453 } 3456 }
@@ -3887,7 +3890,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3887 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 3890 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3888 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 3891 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3889 break; 3892 break;
3890 msleep_interruptible (1); 3893 msleep (1);
3891 count++; 3894 count++;
3892 } 3895 }
3893 } else { 3896 } else {
@@ -3936,7 +3939,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3936 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 3939 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3937 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 3940 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3938 break; 3941 break;
3939 msleep_interruptible(1); 3942 msleep(1);
3940 count++; 3943 count++;
3941 } 3944 }
3942 } else { 3945 } else {
@@ -4159,108 +4162,6 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
4159 4162
4160/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4163/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4161/* 4164/*
4162 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4163 * @ioc: Pointer to MPT_ADAPTER structure
4164 * @portnum: IOC Port number
4165 *
4166 * Return: 0 for success
4167 * -ENOMEM if no memory available
4168 * -EPERM if not allowed due to ISR context
4169 * -EAGAIN if no msg frames currently available
4170 * -EFAULT for non-successful reply or no reply (timeout)
4171 */
4172int
4173mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4174{
4175 ConfigPageHeader_t hdr;
4176 CONFIGPARMS cfg;
4177 FCPortPage0_t *ppage0_alloc;
4178 FCPortPage0_t *pp0dest;
4179 dma_addr_t page0_dma;
4180 int data_sz;
4181 int copy_sz;
4182 int rc;
4183 int count = 400;
4184
4185
4186 /* Get FCPort Page 0 header */
4187 hdr.PageVersion = 0;
4188 hdr.PageLength = 0;
4189 hdr.PageNumber = 0;
4190 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4191 cfg.cfghdr.hdr = &hdr;
4192 cfg.physAddr = -1;
4193 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4194 cfg.dir = 0;
4195 cfg.pageAddr = portnum;
4196 cfg.timeout = 0;
4197
4198 if ((rc = mpt_config(ioc, &cfg)) != 0)
4199 return rc;
4200
4201 if (hdr.PageLength == 0)
4202 return 0;
4203
4204 data_sz = hdr.PageLength * 4;
4205 rc = -ENOMEM;
4206 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4207 if (ppage0_alloc) {
4208
4209 try_again:
4210 memset((u8 *)ppage0_alloc, 0, data_sz);
4211 cfg.physAddr = page0_dma;
4212 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4213
4214 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4215 /* save the data */
4216 pp0dest = &ioc->fc_port_page0[portnum];
4217 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4218 memcpy(pp0dest, ppage0_alloc, copy_sz);
4219
4220 /*
4221 * Normalize endianness of structure data,
4222 * by byte-swapping all > 1 byte fields!
4223 */
4224 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4225 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4226 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4227 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4228 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4229 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4230 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4231 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4232 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4233 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4234 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4235 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4236 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4237 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4238 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4239 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4240
4241 /*
4242 * if still doing discovery,
4243 * hang loose a while until finished
4244 */
4245 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4246 if (count-- > 0) {
4247 msleep_interruptible(100);
4248 goto try_again;
4249 }
4250 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4251 " complete.\n",
4252 ioc->name);
4253 }
4254 }
4255
4256 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4257 }
4258
4259 return rc;
4260}
4261
4262/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4263/*
4264 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table 4165 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4265 * @ioc: Pointer to MPT_ADAPTER structure 4166 * @ioc: Pointer to MPT_ADAPTER structure
4266 * @sas_address: 64bit SAS Address for operation. 4167 * @sas_address: 64bit SAS Address for operation.
@@ -5632,11 +5533,7 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
5632 a[5], a[4], a[3], a[2], a[1], a[0]); 5533 a[5], a[4], a[3], a[2], a[1], a[0]);
5633 } 5534 }
5634 5535
5635#ifndef __sparc__
5636 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq); 5536 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5637#else
5638 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5639#endif
5640 5537
5641 if (!ioc->active) 5538 if (!ioc->active)
5642 y += sprintf(buffer+len+y, " (disabled)"); 5539 y += sprintf(buffer+len+y, " (disabled)");
@@ -5706,11 +5603,11 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5706 if (MptResetHandlers[ii]) { 5603 if (MptResetHandlers[ii]) {
5707 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", 5604 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5708 ioc->name, ii)); 5605 ioc->name, ii));
5709 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET); 5606 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5710 if (ioc->alt_ioc) { 5607 if (ioc->alt_ioc) {
5711 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", 5608 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5712 ioc->name, ioc->alt_ioc->name, ii)); 5609 ioc->name, ioc->alt_ioc->name, ii));
5713 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET); 5610 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5714 } 5611 }
5715 } 5612 }
5716 } 5613 }
@@ -6468,7 +6365,6 @@ EXPORT_SYMBOL(mpt_findImVolumes);
6468EXPORT_SYMBOL(mpt_alloc_fw_memory); 6365EXPORT_SYMBOL(mpt_alloc_fw_memory);
6469EXPORT_SYMBOL(mpt_free_fw_memory); 6366EXPORT_SYMBOL(mpt_free_fw_memory);
6470EXPORT_SYMBOL(mptbase_sas_persist_operation); 6367EXPORT_SYMBOL(mptbase_sas_persist_operation);
6471EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6472 6368
6473 6369
6474/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6370/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index f673cca507e1..4720f9ae86aa 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.09" 79#define MPT_LINUX_VERSION_COMMON "3.03.10"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.09" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -487,6 +487,15 @@ typedef struct _RaidCfgData {
487 int isRaid; /* bit field, 1 if RAID */ 487 int isRaid; /* bit field, 1 if RAID */
488}RaidCfgData; 488}RaidCfgData;
489 489
490typedef struct _FcCfgData {
491 /* will ultimately hold fc_port_page0 also */
492 struct {
493 FCPortPage1_t *data;
494 dma_addr_t dma;
495 int pg_sz;
496 } fc_port_page1[2];
497} FcCfgData;
498
490#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ 499#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
491#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ 500#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
492 501
@@ -565,6 +574,7 @@ typedef struct _MPT_ADAPTER
565 SpiCfgData spi_data; /* Scsi config. data */ 574 SpiCfgData spi_data; /* Scsi config. data */
566 RaidCfgData raid_data; /* Raid config. data */ 575 RaidCfgData raid_data; /* Raid config. data */
567 SasCfgData sas_data; /* Sas config. data */ 576 SasCfgData sas_data; /* Sas config. data */
577 FcCfgData fc_data; /* Fc config. data */
568 MPT_IOCTL *ioctl; /* ioctl data pointer */ 578 MPT_IOCTL *ioctl; /* ioctl data pointer */
569 struct proc_dir_entry *ioc_dentry; 579 struct proc_dir_entry *ioc_dentry;
570 struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ 580 struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
@@ -625,6 +635,7 @@ typedef struct _MPT_ADAPTER
625 int num_ports; 635 int num_ports;
626 struct work_struct mptscsih_persistTask; 636 struct work_struct mptscsih_persistTask;
627 637
638 struct work_struct fc_setup_reset_work;
628 struct list_head fc_rports; 639 struct list_head fc_rports;
629 spinlock_t fc_rescan_work_lock; 640 spinlock_t fc_rescan_work_lock;
630 int fc_rescan_work_count; 641 int fc_rescan_work_count;
@@ -1027,7 +1038,6 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
1027extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 1038extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1028extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1039extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1029extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1040extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1030extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
1031 1041
1032/* 1042/*
1033 * Public data decl's... 1043 * Public data decl's...
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 856487741ef4..74714e5bcf03 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -169,13 +169,6 @@ static struct fc_function_template mptfc_transport_functions = {
169 169
170}; 170};
171 171
172/* FIXME! values controlling firmware RESCAN event
173 * need to be set low to allow dev_loss_tmo to
174 * work as expected. Currently, firmware doesn't
175 * notify driver of RESCAN event until some number
176 * of seconds elapse. This value can be set via
177 * lsiutil.
178 */
179static void 172static void
180mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 173mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
181{ 174{
@@ -587,15 +580,266 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
587#ifdef DMPT_DEBUG_FC 580#ifdef DMPT_DEBUG_FC
588 if (unlikely(err)) { 581 if (unlikely(err)) {
589 dfcprintk ((MYIOC_s_INFO_FMT 582 dfcprintk ((MYIOC_s_INFO_FMT
590 "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n", 583 "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero, (%x).\n",
591 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name, 584 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
592 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no, 585 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
593 SCpnt->device->id,SCpnt->device->lun)); 586 SCpnt->device->id,SCpnt->device->lun,err));
594 } 587 }
595#endif 588#endif
596 return err; 589 return err;
597} 590}
598 591
592/*
593 * mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
594 * @ioc: Pointer to MPT_ADAPTER structure
595 * @portnum: IOC Port number
596 *
597 * Return: 0 for success
598 * -ENOMEM if no memory available
599 * -EPERM if not allowed due to ISR context
600 * -EAGAIN if no msg frames currently available
601 * -EFAULT for non-successful reply or no reply (timeout)
602 * -EINVAL portnum arg out of range (hardwired to two elements)
603 */
604static int
605mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
606{
607 ConfigPageHeader_t hdr;
608 CONFIGPARMS cfg;
609 FCPortPage0_t *ppage0_alloc;
610 FCPortPage0_t *pp0dest;
611 dma_addr_t page0_dma;
612 int data_sz;
613 int copy_sz;
614 int rc;
615 int count = 400;
616
617 if (portnum > 1)
618 return -EINVAL;
619
620 /* Get FCPort Page 0 header */
621 hdr.PageVersion = 0;
622 hdr.PageLength = 0;
623 hdr.PageNumber = 0;
624 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
625 cfg.cfghdr.hdr = &hdr;
626 cfg.physAddr = -1;
627 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
628 cfg.dir = 0;
629 cfg.pageAddr = portnum;
630 cfg.timeout = 0;
631
632 if ((rc = mpt_config(ioc, &cfg)) != 0)
633 return rc;
634
635 if (hdr.PageLength == 0)
636 return 0;
637
638 data_sz = hdr.PageLength * 4;
639 rc = -ENOMEM;
640 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
641 if (ppage0_alloc) {
642
643 try_again:
644 memset((u8 *)ppage0_alloc, 0, data_sz);
645 cfg.physAddr = page0_dma;
646 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
647
648 if ((rc = mpt_config(ioc, &cfg)) == 0) {
649 /* save the data */
650 pp0dest = &ioc->fc_port_page0[portnum];
651 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
652 memcpy(pp0dest, ppage0_alloc, copy_sz);
653
654 /*
655 * Normalize endianness of structure data,
656 * by byte-swapping all > 1 byte fields!
657 */
658 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
659 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
660 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
661 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
662 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
663 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
664 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
665 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
666 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
667 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
668 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
669 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
670 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
671 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
672 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
673 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
674
675 /*
676 * if still doing discovery,
677 * hang loose a while until finished
678 */
679 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
680 if (count-- > 0) {
681 msleep(100);
682 goto try_again;
683 }
684 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
685 " complete.\n",
686 ioc->name);
687 }
688 }
689
690 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
691 }
692
693 return rc;
694}
695
696static int
697mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
698{
699 ConfigPageHeader_t hdr;
700 CONFIGPARMS cfg;
701 int rc;
702
703 if (portnum > 1)
704 return -EINVAL;
705
706 if (!(ioc->fc_data.fc_port_page1[portnum].data))
707 return -EINVAL;
708
709 /* get fcport page 1 header */
710 hdr.PageVersion = 0;
711 hdr.PageLength = 0;
712 hdr.PageNumber = 1;
713 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
714 cfg.cfghdr.hdr = &hdr;
715 cfg.physAddr = -1;
716 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
717 cfg.dir = 0;
718 cfg.pageAddr = portnum;
719 cfg.timeout = 0;
720
721 if ((rc = mpt_config(ioc, &cfg)) != 0)
722 return rc;
723
724 if (hdr.PageLength == 0)
725 return -ENODEV;
726
727 if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
728 return -EINVAL;
729
730 cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
731 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
732 cfg.dir = 1;
733
734 rc = mpt_config(ioc, &cfg);
735
736 return rc;
737}
738
739static int
740mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
741{
742 ConfigPageHeader_t hdr;
743 CONFIGPARMS cfg;
744 FCPortPage1_t *page1_alloc;
745 dma_addr_t page1_dma;
746 int data_sz;
747 int rc;
748
749 if (portnum > 1)
750 return -EINVAL;
751
752 /* get fcport page 1 header */
753 hdr.PageVersion = 0;
754 hdr.PageLength = 0;
755 hdr.PageNumber = 1;
756 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
757 cfg.cfghdr.hdr = &hdr;
758 cfg.physAddr = -1;
759 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
760 cfg.dir = 0;
761 cfg.pageAddr = portnum;
762 cfg.timeout = 0;
763
764 if ((rc = mpt_config(ioc, &cfg)) != 0)
765 return rc;
766
767 if (hdr.PageLength == 0)
768 return -ENODEV;
769
770start_over:
771
772 if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
773 data_sz = hdr.PageLength * 4;
774 if (data_sz < sizeof(FCPortPage1_t))
775 data_sz = sizeof(FCPortPage1_t);
776
777 page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
778 data_sz,
779 &page1_dma);
780 if (!page1_alloc)
781 return -ENOMEM;
782 }
783 else {
784 page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
785 page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
786 data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
787 if (hdr.PageLength * 4 > data_sz) {
788 ioc->fc_data.fc_port_page1[portnum].data = NULL;
789 pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
790 page1_alloc, page1_dma);
791 goto start_over;
792 }
793 }
794
795 memset(page1_alloc,0,data_sz);
796
797 cfg.physAddr = page1_dma;
798 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
799
800 if ((rc = mpt_config(ioc, &cfg)) == 0) {
801 ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
802 ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
803 ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
804 }
805 else {
806 ioc->fc_data.fc_port_page1[portnum].data = NULL;
807 pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
808 page1_alloc, page1_dma);
809 }
810
811 return rc;
812}
813
814static void
815mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
816{
817 int ii;
818 FCPortPage1_t *pp1;
819
820 #define MPTFC_FW_DEVICE_TIMEOUT (1)
821 #define MPTFC_FW_IO_PEND_TIMEOUT (1)
822 #define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
823 #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
824
825 for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
826 if (mptfc_GetFcPortPage1(ioc, ii) != 0)
827 continue;
828 pp1 = ioc->fc_data.fc_port_page1[ii].data;
829 if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
830 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
831 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
832 && ((pp1->Flags & OFF_FLAGS) == 0))
833 continue;
834 pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
835 pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
836 pp1->Flags &= ~OFF_FLAGS;
837 pp1->Flags |= ON_FLAGS;
838 mptfc_WriteFcPortPage1(ioc, ii);
839 }
840}
841
842
599static void 843static void
600mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) 844mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
601{ 845{
@@ -629,6 +873,31 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
629} 873}
630 874
631static void 875static void
876mptfc_setup_reset(void *arg)
877{
878 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
879 u64 pn;
880 struct mptfc_rport_info *ri;
881
882 /* reset about to happen, delete (block) all rports */
883 list_for_each_entry(ri, &ioc->fc_rports, list) {
884 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
885 ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
886 fc_remote_port_delete(ri->rport); /* won't sleep */
887 ri->rport = NULL;
888
889 pn = (u64)ri->pg0.WWPN.High << 32 |
890 (u64)ri->pg0.WWPN.Low;
891 dfcprintk ((MYIOC_s_INFO_FMT
892 "mptfc_setup_reset.%d: %llx deleted\n",
893 ioc->name,
894 ioc->sh->host_no,
895 (unsigned long long)pn));
896 }
897 }
898}
899
900static void
632mptfc_rescan_devices(void *arg) 901mptfc_rescan_devices(void *arg)
633{ 902{
634 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 903 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
@@ -651,7 +920,7 @@ mptfc_rescan_devices(void *arg)
651 * will reregister existing rports 920 * will reregister existing rports
652 */ 921 */
653 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 922 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
654 (void) mptbase_GetFcPortPage0(ioc, ii); 923 (void) mptfc_GetFcPortPage0(ioc, ii);
655 mptfc_init_host_attr(ioc,ii); /* refresh */ 924 mptfc_init_host_attr(ioc,ii); /* refresh */
656 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); 925 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
657 } 926 }
@@ -753,7 +1022,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
753 goto out_mptfc_probe; 1022 goto out_mptfc_probe;
754 } 1023 }
755 1024
1025 spin_lock_init(&ioc->fc_rescan_work_lock);
756 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc); 1026 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
1027 INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc);
757 1028
758 spin_lock_irqsave(&ioc->FreeQlock, flags); 1029 spin_lock_irqsave(&ioc->FreeQlock, flags);
759 1030
@@ -889,6 +1160,15 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
889 goto out_mptfc_probe; 1160 goto out_mptfc_probe;
890 1161
891 /* 1162 /*
1163 * Pre-fetch FC port WWN and stuff...
1164 * (FCPortPage0_t stuff)
1165 */
1166 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1167 (void) mptfc_GetFcPortPage0(ioc, ii);
1168 }
1169 mptfc_SetFcPortPage1_defaults(ioc);
1170
1171 /*
892 * scan for rports - 1172 * scan for rports -
893 * by doing it via the workqueue, some locking is eliminated 1173 * by doing it via the workqueue, some locking is eliminated
894 */ 1174 */
@@ -917,6 +1197,81 @@ static struct pci_driver mptfc_driver = {
917#endif 1197#endif
918}; 1198};
919 1199
1200static int
1201mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1202{
1203 MPT_SCSI_HOST *hd;
1204 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1205 unsigned long flags;
1206 int rc=1;
1207
1208 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1209 ioc->name, event));
1210
1211 if (ioc->sh == NULL ||
1212 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
1213 return 1;
1214
1215 switch (event) {
1216 case MPI_EVENT_RESCAN:
1217 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1218 if (ioc->fc_rescan_work_q) {
1219 if (ioc->fc_rescan_work_count++ == 0) {
1220 queue_work(ioc->fc_rescan_work_q,
1221 &ioc->fc_rescan_work);
1222 }
1223 }
1224 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1225 break;
1226 default:
1227 rc = mptscsih_event_process(ioc,pEvReply);
1228 break;
1229 }
1230 return rc;
1231}
1232
1233static int
1234mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1235{
1236 int rc;
1237 unsigned long flags;
1238
1239 rc = mptscsih_ioc_reset(ioc,reset_phase);
1240 if (rc == 0)
1241 return rc;
1242
1243
1244 dtmprintk((KERN_WARNING MYNAM
1245 ": IOC %s_reset routed to FC host driver!\n",
1246 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1247 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1248
1249 if (reset_phase == MPT_IOC_SETUP_RESET) {
1250 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1251 if (ioc->fc_rescan_work_q) {
1252 queue_work(ioc->fc_rescan_work_q,
1253 &ioc->fc_setup_reset_work);
1254 }
1255 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1256 }
1257
1258 else if (reset_phase == MPT_IOC_PRE_RESET) {
1259 }
1260
1261 else { /* MPT_IOC_POST_RESET */
1262 mptfc_SetFcPortPage1_defaults(ioc);
1263 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1264 if (ioc->fc_rescan_work_q) {
1265 if (ioc->fc_rescan_work_count++ == 0) {
1266 queue_work(ioc->fc_rescan_work_q,
1267 &ioc->fc_rescan_work);
1268 }
1269 }
1270 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1271 }
1272 return 1;
1273}
1274
920/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1275/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
921/** 1276/**
922 * mptfc_init - Register MPT adapter(s) as SCSI host(s) with 1277 * mptfc_init - Register MPT adapter(s) as SCSI host(s) with
@@ -931,8 +1286,8 @@ mptfc_init(void)
931 1286
932 show_mptmod_ver(my_NAME, my_VERSION); 1287 show_mptmod_ver(my_NAME, my_VERSION);
933 1288
934 /* sanity check module parameter */ 1289 /* sanity check module parameters */
935 if (mptfc_dev_loss_tmo == 0) 1290 if (mptfc_dev_loss_tmo <= 0)
936 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; 1291 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
937 1292
938 mptfc_transport_template = 1293 mptfc_transport_template =
@@ -945,12 +1300,12 @@ mptfc_init(void)
945 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 1300 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
946 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 1301 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
947 1302
948 if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { 1303 if (mpt_event_register(mptfcDoneCtx, mptfc_event_process) == 0) {
949 devtverboseprintk((KERN_INFO MYNAM 1304 devtverboseprintk((KERN_INFO MYNAM
950 ": Registered for IOC event notifications\n")); 1305 ": Registered for IOC event notifications\n"));
951 } 1306 }
952 1307
953 if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) { 1308 if (mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset) == 0) {
954 dprintk((KERN_INFO MYNAM 1309 dprintk((KERN_INFO MYNAM
955 ": Registered for IOC reset notifications\n")); 1310 ": Registered for IOC reset notifications\n"));
956 } 1311 }
@@ -975,6 +1330,7 @@ mptfc_remove(struct pci_dev *pdev)
975 struct mptfc_rport_info *p, *n; 1330 struct mptfc_rport_info *p, *n;
976 struct workqueue_struct *work_q; 1331 struct workqueue_struct *work_q;
977 unsigned long flags; 1332 unsigned long flags;
1333 int ii;
978 1334
979 /* destroy workqueue */ 1335 /* destroy workqueue */
980 if ((work_q=ioc->fc_rescan_work_q)) { 1336 if ((work_q=ioc->fc_rescan_work_q)) {
@@ -991,6 +1347,16 @@ mptfc_remove(struct pci_dev *pdev)
991 kfree(p); 1347 kfree(p);
992 } 1348 }
993 1349
1350 for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1351 if (ioc->fc_data.fc_port_page1[ii].data) {
1352 pci_free_consistent(ioc->pcidev,
1353 ioc->fc_data.fc_port_page1[ii].pg_sz,
1354 (u8 *) ioc->fc_data.fc_port_page1[ii].data,
1355 ioc->fc_data.fc_port_page1[ii].dma);
1356 ioc->fc_data.fc_port_page1[ii].data = NULL;
1357 }
1358 }
1359
994 mptscsih_remove(pdev); 1360 mptscsih_remove(pdev);
995} 1361}
996 1362
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 84fa271eb8f4..8242b16e3168 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1922,7 +1922,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1922 break; 1922 break;
1923 } 1923 }
1924 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1924 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1925 msleep_interruptible(250); 1925 msleep(250);
1926 } while (--loop_count); 1926 } while (--loop_count);
1927 1927
1928 return status; 1928 return status;
@@ -2521,18 +2521,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2521 hd->cmdPtr = NULL; 2521 hd->cmdPtr = NULL;
2522 } 2522 }
2523 2523
2524 /* 7. FC: Rescan for blocked rports which might have returned.
2525 */
2526 if (ioc->bus_type == FC) {
2527 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2528 if (ioc->fc_rescan_work_q) {
2529 if (ioc->fc_rescan_work_count++ == 0) {
2530 queue_work(ioc->fc_rescan_work_q,
2531 &ioc->fc_rescan_work);
2532 }
2533 }
2534 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2535 }
2536 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); 2524 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2537 2525
2538 } 2526 }
@@ -2546,7 +2534,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2546{ 2534{
2547 MPT_SCSI_HOST *hd; 2535 MPT_SCSI_HOST *hd;
2548 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2536 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2549 unsigned long flags;
2550 2537
2551 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2538 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2552 ioc->name, event)); 2539 ioc->name, event));
@@ -2569,14 +2556,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2569 break; 2556 break;
2570 2557
2571 case MPI_EVENT_RESCAN: /* 06 */ 2558 case MPI_EVENT_RESCAN: /* 06 */
2572 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2573 if (ioc->fc_rescan_work_q) {
2574 if (ioc->fc_rescan_work_count++ == 0) {
2575 queue_work(ioc->fc_rescan_work_q,
2576 &ioc->fc_rescan_work);
2577 }
2578 }
2579 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2580 break; 2559 break;
2581 2560
2582 /* 2561 /*
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index f2a4d382ea19..3201de053943 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -831,6 +831,7 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
831 return rc; 831 return rc;
832} 832}
833 833
834#ifdef CONFIG_PM
834/* 835/*
835 * spi module resume handler 836 * spi module resume handler
836 */ 837 */
@@ -846,6 +847,7 @@ mptspi_resume(struct pci_dev *pdev)
846 847
847 return rc; 848 return rc;
848} 849}
850#endif
849 851
850/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 852/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
851/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 853/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 5ea133c59afb..7bd4d85d0b42 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -55,6 +55,7 @@ struct i2o_exec_wait {
55 u32 m; /* message id */ 55 u32 m; /* message id */
56 struct i2o_message *msg; /* pointer to the reply message */ 56 struct i2o_message *msg; /* pointer to the reply message */
57 struct list_head list; /* node in global wait list */ 57 struct list_head list; /* node in global wait list */
58 spinlock_t lock; /* lock before modifying */
58}; 59};
59 60
60/* Work struct needed to handle LCT NOTIFY replies */ 61/* Work struct needed to handle LCT NOTIFY replies */
@@ -87,6 +88,7 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void)
87 return NULL; 88 return NULL;
88 89
89 INIT_LIST_HEAD(&wait->list); 90 INIT_LIST_HEAD(&wait->list);
91 spin_lock_init(&wait->lock);
90 92
91 return wait; 93 return wait;
92}; 94};
@@ -125,6 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
125 DECLARE_WAIT_QUEUE_HEAD(wq); 127 DECLARE_WAIT_QUEUE_HEAD(wq);
126 struct i2o_exec_wait *wait; 128 struct i2o_exec_wait *wait;
127 static u32 tcntxt = 0x80000000; 129 static u32 tcntxt = 0x80000000;
130 long flags;
128 int rc = 0; 131 int rc = 0;
129 132
130 wait = i2o_exec_wait_alloc(); 133 wait = i2o_exec_wait_alloc();
@@ -146,33 +149,28 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
146 wait->tcntxt = tcntxt++; 149 wait->tcntxt = tcntxt++;
147 msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); 150 msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt);
148 151
152 wait->wq = &wq;
153 /*
154 * we add elements to the head, because if a entry in the list will
155 * never be removed, we have to iterate over it every time
156 */
157 list_add(&wait->list, &i2o_exec_wait_list);
158
149 /* 159 /*
150 * Post the message to the controller. At some point later it will 160 * Post the message to the controller. At some point later it will
151 * return. If we time out before it returns then complete will be zero. 161 * return. If we time out before it returns then complete will be zero.
152 */ 162 */
153 i2o_msg_post(c, msg); 163 i2o_msg_post(c, msg);
154 164
155 if (!wait->complete) { 165 wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ);
156 wait->wq = &wq;
157 /*
158 * we add elements add the head, because if a entry in the list
159 * will never be removed, we have to iterate over it every time
160 */
161 list_add(&wait->list, &i2o_exec_wait_list);
162
163 wait_event_interruptible_timeout(wq, wait->complete,
164 timeout * HZ);
165 166
166 wait->wq = NULL; 167 spin_lock_irqsave(&wait->lock, flags);
167 }
168 168
169 barrier(); 169 wait->wq = NULL;
170 170
171 if (wait->complete) { 171 if (wait->complete)
172 rc = le32_to_cpu(wait->msg->body[0]) >> 24; 172 rc = le32_to_cpu(wait->msg->body[0]) >> 24;
173 i2o_flush_reply(c, wait->m); 173 else {
174 i2o_exec_wait_free(wait);
175 } else {
176 /* 174 /*
177 * We cannot remove it now. This is important. When it does 175 * We cannot remove it now. This is important. When it does
178 * terminate (which it must do if the controller has not 176 * terminate (which it must do if the controller has not
@@ -186,6 +184,13 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
186 rc = -ETIMEDOUT; 184 rc = -ETIMEDOUT;
187 } 185 }
188 186
187 spin_unlock_irqrestore(&wait->lock, flags);
188
189 if (rc != -ETIMEDOUT) {
190 i2o_flush_reply(c, wait->m);
191 i2o_exec_wait_free(wait);
192 }
193
189 return rc; 194 return rc;
190}; 195};
191 196
@@ -213,7 +218,6 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
213{ 218{
214 struct i2o_exec_wait *wait, *tmp; 219 struct i2o_exec_wait *wait, *tmp;
215 unsigned long flags; 220 unsigned long flags;
216 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
217 int rc = 1; 221 int rc = 1;
218 222
219 /* 223 /*
@@ -223,23 +227,24 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
223 * already expired. Not much we can do about that except log it for 227 * already expired. Not much we can do about that except log it for
224 * debug purposes, increase timeout, and recompile. 228 * debug purposes, increase timeout, and recompile.
225 */ 229 */
226 spin_lock_irqsave(&lock, flags);
227 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { 230 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
228 if (wait->tcntxt == context) { 231 if (wait->tcntxt == context) {
229 list_del(&wait->list); 232 spin_lock_irqsave(&wait->lock, flags);
230 233
231 spin_unlock_irqrestore(&lock, flags); 234 list_del(&wait->list);
232 235
233 wait->m = m; 236 wait->m = m;
234 wait->msg = msg; 237 wait->msg = msg;
235 wait->complete = 1; 238 wait->complete = 1;
236 239
237 barrier(); 240 if (wait->wq)
238
239 if (wait->wq) {
240 wake_up_interruptible(wait->wq);
241 rc = 0; 241 rc = 0;
242 } else { 242 else
243 rc = -1;
244
245 spin_unlock_irqrestore(&wait->lock, flags);
246
247 if (rc) {
243 struct device *dev; 248 struct device *dev;
244 249
245 dev = &c->pdev->dev; 250 dev = &c->pdev->dev;
@@ -248,15 +253,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
248 c->name); 253 c->name);
249 i2o_dma_free(dev, &wait->dma); 254 i2o_dma_free(dev, &wait->dma);
250 i2o_exec_wait_free(wait); 255 i2o_exec_wait_free(wait);
251 rc = -1; 256 } else
252 } 257 wake_up_interruptible(wait->wq);
253 258
254 return rc; 259 return rc;
255 } 260 }
256 } 261 }
257 262
258 spin_unlock_irqrestore(&lock, flags);
259
260 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, 263 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
261 context); 264 context);
262 265
@@ -322,14 +325,9 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
322static int i2o_exec_probe(struct device *dev) 325static int i2o_exec_probe(struct device *dev)
323{ 326{
324 struct i2o_device *i2o_dev = to_i2o_device(dev); 327 struct i2o_device *i2o_dev = to_i2o_device(dev);
325 struct i2o_controller *c = i2o_dev->iop;
326 328
327 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); 329 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
328 330
329 c->exec = i2o_dev;
330
331 i2o_exec_lct_notify(c, c->lct->change_ind + 1);
332
333 device_create_file(dev, &dev_attr_vendor_id); 331 device_create_file(dev, &dev_attr_vendor_id);
334 device_create_file(dev, &dev_attr_product_id); 332 device_create_file(dev, &dev_attr_product_id);
335 333
@@ -523,6 +521,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
523 struct device *dev; 521 struct device *dev;
524 struct i2o_message *msg; 522 struct i2o_message *msg;
525 523
524 down(&c->lct_lock);
525
526 dev = &c->pdev->dev; 526 dev = &c->pdev->dev;
527 527
528 if (i2o_dma_realloc 528 if (i2o_dma_realloc
@@ -545,6 +545,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
545 545
546 i2o_msg_post(c, msg); 546 i2o_msg_post(c, msg);
547 547
548 up(&c->lct_lock);
549
548 return 0; 550 return 0;
549}; 551};
550 552
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index c08ddac3717d..6ebf38213f9f 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -65,9 +65,7 @@
65#include <scsi/scsi_host.h> 65#include <scsi/scsi_host.h>
66#include <scsi/scsi_device.h> 66#include <scsi/scsi_device.h>
67#include <scsi/scsi_cmnd.h> 67#include <scsi/scsi_cmnd.h>
68#include <scsi/scsi_request.h>
69#include <scsi/sg.h> 68#include <scsi/sg.h>
70#include <scsi/sg_request.h>
71 69
72#define OSM_NAME "scsi-osm" 70#define OSM_NAME "scsi-osm"
73#define OSM_VERSION "1.316" 71#define OSM_VERSION "1.316"
@@ -588,6 +586,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
588 586
589 mptr = &msg->body[0]; 587 mptr = &msg->body[0];
590 588
589#if 0 /* this code can't work */
591#ifdef CONFIG_I2O_EXT_ADAPTEC 590#ifdef CONFIG_I2O_EXT_ADAPTEC
592 if (c->adaptec) { 591 if (c->adaptec) {
593 u32 adpt_flags = 0; 592 u32 adpt_flags = 0;
@@ -625,6 +624,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
625 *mptr++ = cpu_to_le32(adpt_flags | tid); 624 *mptr++ = cpu_to_le32(adpt_flags | tid);
626 } 625 }
627#endif 626#endif
627#endif
628 628
629 msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid); 629 msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
630 msg->u.s.icntxt = cpu_to_le32(i2o_scsi_driver.context); 630 msg->u.s.icntxt = cpu_to_le32(i2o_scsi_driver.context);
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 492167446936..febbdd4e0605 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -804,8 +804,6 @@ void i2o_iop_remove(struct i2o_controller *c)
804 804
805 /* Ask the IOP to switch to RESET state */ 805 /* Ask the IOP to switch to RESET state */
806 i2o_iop_reset(c); 806 i2o_iop_reset(c);
807
808 put_device(&c->device);
809} 807}
810 808
811/** 809/**
@@ -1059,7 +1057,7 @@ struct i2o_controller *i2o_iop_alloc(void)
1059 1057
1060 snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name); 1058 snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name);
1061 if (i2o_pool_alloc 1059 if (i2o_pool_alloc
1062 (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4, 1060 (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32),
1063 I2O_MSG_INPOOL_MIN)) { 1061 I2O_MSG_INPOOL_MIN)) {
1064 kfree(c); 1062 kfree(c);
1065 return ERR_PTR(-ENOMEM); 1063 return ERR_PTR(-ENOMEM);