Commit 4195d656 authored by James Bottomley's avatar James Bottomley

Fusion update to 3.00.02

From: Moore, Eric Dean <Emoore@lsil.com>

Here is list of fix's.
* added new PCI API support
* added ACPI support
* added CONFIG_LBA, READ16, WRITE16 support
* underun fix
* chain buffer free list not being init properly
* reduce task management 
        (abort=2sec,reset bus=5sec, timeout=10sec)
* Hot plug fix's requested from Christoph Hellwig, and several
others from the linux-scsi@ list.
parent 0450c68d
...@@ -167,6 +167,7 @@ static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS]; ...@@ -167,6 +167,7 @@ static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS]; static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
/* Reset handler lookup table */ /* Reset handler lookup table */
static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
static int FusionInitCalled = 0; static int FusionInitCalled = 0;
static int mpt_base_index = -1; static int mpt_base_index = -1;
...@@ -183,7 +184,6 @@ static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r); ...@@ -183,7 +184,6 @@ static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag); static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
static int mpt_adapter_install(struct pci_dev *pdev);
static void mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev); static void mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
static void mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup); static void mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
static void mpt_adapter_dispose(MPT_ADAPTER *ioc); static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
...@@ -232,8 +232,12 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t * ...@@ -232,8 +232,12 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
int fusion_init(void); /* module entry point */
static void fusion_exit(void); static int __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
static void __devexit mptbase_remove(struct pci_dev *);
static void mptbase_shutdown(struct device * );
static int __init fusion_init (void);
static void __exit fusion_exit (void);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -260,6 +264,30 @@ struct _mpt_ioc_proc_list { ...@@ -260,6 +264,30 @@ struct _mpt_ioc_proc_list {
#endif #endif
/****************************************************************************
* Supported hardware
*/
static struct pci_device_id mptbase_pci_table[] = {
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* 20000207 -sralston /* 20000207 -sralston
* GRRRRR... IOSpace (port i/o) register access (for the 909) is back! * GRRRRR... IOSpace (port i/o) register access (for the 909) is back!
...@@ -518,7 +546,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) ...@@ -518,7 +546,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
* @mf: Pointer to original MPT request frame * @mf: Pointer to original MPT request frame
* @reply: Pointer to MPT reply frame (NULL if TurboReply) * @reply: Pointer to MPT reply frame (NULL if TurboReply)
* *
* Returns 1 indicating original alloc'd request frame ptr * Returns 1 indicating original alloc'd request frame ptr
* should be freed, or 0 if it shouldn't. * should be freed, or 0 if it shouldn't.
*/ */
static int static int
...@@ -803,6 +831,34 @@ mpt_reset_deregister(int cb_idx) ...@@ -803,6 +831,34 @@ mpt_reset_deregister(int cb_idx)
MptResetHandlers[cb_idx] = NULL; MptResetHandlers[cb_idx] = NULL;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_device_driver_register - Register device driver hooks
*/
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;
MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_device_driver_deregister - DeRegister device driver hooks
*/
void
mpt_device_driver_deregister(int cb_idx)
{
if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
return;
MptDeviceDriverHandlers[cb_idx] = NULL;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024) * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
...@@ -1142,88 +1198,6 @@ mpt_adapter_find_next(MPT_ADAPTER *prev) ...@@ -1142,88 +1198,6 @@ mpt_adapter_find_next(MPT_ADAPTER *prev)
return next; return next;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_pci_scan - Scan PCI devices for MPT adapters.
*
* Returns count of MPT adapters found, keying off of PCI vendor and
* device_id's.
*/
static int __init
mpt_pci_scan(void)
{
struct pci_dev *pdev = NULL;
struct pci_dev *pdev2;
int found = 0;
int count = 0;
int r;
dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n"));
/*
* NOTE: The 929, 929X, 1030 and 1035 will appear as 2 separate PCI devices,
* one for each channel.
*/
while ((pdev = pci_find_device(PCI_VENDOR_ID_LSI_LOGIC, PCI_ANY_ID, pdev)) != NULL) {
pdev2 = NULL;
if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_1030_53C1035) &&
1) {
dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device));
continue;
}
/* GRRRRR
* dual function devices (929, 929X, 1030, 1035) may be presented in Func 1,0 order,
* but we'd really really rather have them in Func 0,1 order.
* Do some kind of look ahead here...
*/
if (pdev->devfn & 1) {
pdev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev);
if (pdev2 && (pdev2->vendor == 0x1000) &&
(PCI_SLOT(pdev2->devfn) == PCI_SLOT(pdev->devfn)) &&
(pdev2->device == pdev->device) &&
(pdev2->bus->number == pdev->bus->number) &&
!(pdev2->devfn & 1)) {
dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",
pdev2->bus->number, pdev2->devfn, pdev2->class, pdev2->device));
found++;
if ((r = mpt_adapter_install(pdev2)) == 0)
count++;
} else {
pdev2 = NULL;
}
}
dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",
pdev->bus->number, pdev->devfn, pdev->class, pdev->device));
found++;
if ((r = mpt_adapter_install(pdev)) == 0)
count++;
if (pdev2)
pdev = pdev2;
}
printk(KERN_INFO MYNAM ": %d MPT adapter%s found, %d installed.\n",
found, (found==1) ? "" : "s", count);
if (!found || !count) {
fusion_exit();
return -ENODEV;
}
#ifdef CONFIG_PROC_FS
(void) procmpt_create();
#endif
return count;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
...@@ -1253,7 +1227,7 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) ...@@ -1253,7 +1227,7 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* mpt_adapter_install - Install a PCI intelligent MPT adapter. * mptbase_probe - Install a PCI intelligent MPT adapter.
* @pdev: Pointer to pci_dev structure * @pdev: Pointer to pci_dev structure
* *
* This routine performs all the steps necessary to bring the IOC of * This routine performs all the steps necessary to bring the IOC of
...@@ -1268,8 +1242,8 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) ...@@ -1268,8 +1242,8 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
* *
* TODO: Add support for polled controllers * TODO: Add support for polled controllers
*/ */
static int __init static int __devinit
mpt_adapter_install(struct pci_dev *pdev) mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
u8 *mem; u8 *mem;
...@@ -1292,6 +1266,13 @@ mpt_adapter_install(struct pci_dev *pdev) ...@@ -1292,6 +1266,13 @@ mpt_adapter_install(struct pci_dev *pdev)
return r; return r;
} }
if (!pci_set_consistent_dma_mask(pdev, mask))
dprintk((KERN_INFO MYNAM
": Using 64 bit consistent mask\n"));
else
dprintk((KERN_INFO MYNAM
": Not using 64 bit consistent mask\n"));
ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
if (ioc == NULL) { if (ioc == NULL) {
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
...@@ -1500,6 +1481,7 @@ mpt_adapter_install(struct pci_dev *pdev) ...@@ -1500,6 +1481,7 @@ mpt_adapter_install(struct pci_dev *pdev)
ioc->pci_irq = pdev->irq; ioc->pci_irq = pdev->irq;
pci_set_master(pdev); /* ?? */ pci_set_master(pdev); /* ?? */
pci_set_drvdata(pdev, ioc);
#ifndef __sparc__ #ifndef __sparc__
dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq)); dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
...@@ -1520,9 +1502,207 @@ mpt_adapter_install(struct pci_dev *pdev) ...@@ -1520,9 +1502,207 @@ mpt_adapter_install(struct pci_dev *pdev)
ioc->name, r); ioc->name, r);
} }
return r; if(r != 0 )
return r;
/* call per device driver probe entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] &&
MptDeviceDriverHandlers[ii]->probe) {
MptDeviceDriverHandlers[ii]->probe(pdev,id);
}
}
return 0;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptbase_remove - Remove a PCI intelligent MPT adapter.
* @pdev: Pointer to pci_dev structure
*
*/
static void __devexit
mptbase_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
int ii;
/* call per device driver remove entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] &&
MptDeviceDriverHandlers[ii]->remove) {
MptDeviceDriverHandlers[ii]->remove(pdev);
}
}
/* Disable interrupts! */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
CHIPREG_READ32(&ioc->chip->IntStatus);
Q_DEL_ITEM(ioc);
mpt_adapter_dispose(ioc);
mptscsih_sync_irq(ioc->irq);
pci_set_drvdata(pdev, NULL);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptbase_shutdown -
*
*/
static void
mptbase_shutdown(struct device * dev)
{
int ii;
/* call per device driver shutdown entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] &&
MptDeviceDriverHandlers[ii]->shutdown) {
MptDeviceDriverHandlers[ii]->shutdown(dev);
}
}
}
/**************************************************************************
* Power Management
*/
#ifdef CONFIG_PM
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptbase_suspend - Fusion MPT base driver suspend routine.
*
*
*/
static int
mptbase_suspend(struct pci_dev *pdev, u32 state)
{
u32 device_state;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
int ii;
switch(state)
{
case 1: /* S1 */
device_state=1; /* D1 */;
break;
case 3: /* S3 */
case 4: /* S4 */
device_state=3; /* D3 */;
break;
default:
return -EAGAIN /*FIXME*/;
break;
}
printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
ioc->name, pdev, pci_name(pdev), device_state);
/* call per device driver suspend entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] &&
MptDeviceDriverHandlers[ii]->suspend) {
MptDeviceDriverHandlers[ii]->suspend(pdev, state);
}
}
pci_save_state(pdev, ioc->PciState);
/* put ioc into READY_STATE */
if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
printk(MYIOC_s_ERR_FMT
"pci-suspend: IOC msg unit reset failed!\n", ioc->name);
}
/* disable interrupts */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
pci_disable_device(pdev);
pci_set_power_state(pdev, device_state);
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptbase_resume - Fusion MPT base driver resume routine.
*
*
*/
static int
mptbase_resume(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
u32 device_state = pdev->current_state;
int recovery_state;
int ii;
printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
ioc->name, pdev, pci_name(pdev), device_state);
pci_set_power_state(pdev, 0);
pci_restore_state(pdev, ioc->PciState);
pci_enable_device(pdev);
/* enable interrupts */
CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
ioc->active = 1;
/* F/W not running */
if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
/* enable domain validation flags */
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
}
}
printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
ioc->name,
(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
CHIPREG_READ32(&ioc->chip->Doorbell));
/* bring ioc to operational state */
if ((recovery_state = mpt_do_ioc_recovery(ioc,
MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
printk(MYIOC_s_INFO_FMT
"pci-resume: Cannot recover, error:[%x]\n",
ioc->name, recovery_state);
} else {
printk(MYIOC_s_INFO_FMT
"pci-resume: success\n", ioc->name);
}
/* call per device driver resume entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] &&
MptDeviceDriverHandlers[ii]->resume) {
MptDeviceDriverHandlers[ii]->resume(pdev);
}
}
return 0;
}
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* mpt_do_ioc_recovery - Initialize or recover MPT adapter. * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
...@@ -5851,6 +6031,8 @@ EXPORT_SYMBOL(mpt_event_register); ...@@ -5851,6 +6031,8 @@ EXPORT_SYMBOL(mpt_event_register);
EXPORT_SYMBOL(mpt_event_deregister); EXPORT_SYMBOL(mpt_event_deregister);
EXPORT_SYMBOL(mpt_reset_register); EXPORT_SYMBOL(mpt_reset_register);
EXPORT_SYMBOL(mpt_reset_deregister); EXPORT_SYMBOL(mpt_reset_deregister);
EXPORT_SYMBOL(mpt_device_driver_register);
EXPORT_SYMBOL(mpt_device_driver_deregister);
EXPORT_SYMBOL(mpt_get_msg_frame); EXPORT_SYMBOL(mpt_get_msg_frame);
EXPORT_SYMBOL(mpt_put_msg_frame); EXPORT_SYMBOL(mpt_put_msg_frame);
EXPORT_SYMBOL(mpt_free_msg_frame); EXPORT_SYMBOL(mpt_free_msg_frame);
...@@ -5877,16 +6059,32 @@ EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr); ...@@ -5877,16 +6059,32 @@ EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr);
EXPORT_SYMBOL(mpt_ASCQ_TableSz); EXPORT_SYMBOL(mpt_ASCQ_TableSz);
EXPORT_SYMBOL(mpt_ScsiOpcodesPtr); EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
static struct pci_driver mptbase_driver = {
.name = "mptbase",
.id_table = mptbase_pci_table,
.probe = mptbase_probe,
.remove = __devexit_p(mptbase_remove),
.driver = {
.shutdown = mptbase_shutdown,
},
#ifdef CONFIG_PM
.suspend = mptbase_suspend,
.resume = mptbase_resume,
#endif
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* fusion_init - Fusion MPT base driver initialization routine. * fusion_init - Fusion MPT base driver initialization routine.
* *
* Returns 0 for success, non-zero for failure. * Returns 0 for success, non-zero for failure.
*/ */
int __init static int __init
fusion_init(void) fusion_init(void)
{ {
int i; int i;
int r;
if (FusionInitCalled++) { if (FusionInitCalled++) {
dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n")); dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n"));
...@@ -5920,10 +6118,15 @@ fusion_init(void) ...@@ -5920,10 +6118,15 @@ fusion_init(void)
/* FIXME! */ /* FIXME! */
} }
if ((i = mpt_pci_scan()) < 0) r = pci_module_init(&mptbase_driver);
return i; if(r)
return(r);
return 0; #ifdef CONFIG_PROC_FS
(void) procmpt_create();
#endif
return r;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -5933,13 +6136,12 @@ fusion_init(void) ...@@ -5933,13 +6136,12 @@ fusion_init(void)
* This routine frees all resources associated with each MPT adapter * This routine frees all resources associated with each MPT adapter
* and removes all %MPT_PROCFS_MPTBASEDIR entries. * and removes all %MPT_PROCFS_MPTBASEDIR entries.
*/ */
static void static void __exit
fusion_exit(void) fusion_exit(void)
{ {
MPT_ADAPTER *this;
struct pci_dev *pdev = NULL;
dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n")); dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
pci_unregister_driver(&mptbase_driver);
/* Whups? 20010120 -sralston /* Whups? 20010120 -sralston
* Moved this *above* removal of all MptAdapters! * Moved this *above* removal of all MptAdapters!
...@@ -5948,30 +6150,9 @@ fusion_exit(void) ...@@ -5948,30 +6150,9 @@ fusion_exit(void)
(void) procmpt_destroy(); (void) procmpt_destroy();
#endif #endif
while (! Q_IS_EMPTY(&MptAdapters)) {
this = MptAdapters.head;
/* Disable interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
this->active = 0;
pdev = (struct pci_dev *)this->pcidev;
mptscsih_sync_irq(pdev->irq);
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&this->chip->IntStatus, 0);
CHIPREG_READ32(&this->chip->IntStatus);
Q_DEL_ITEM(this);
mpt_adapter_dispose(this);
}
mpt_reset_deregister(mpt_base_index); mpt_reset_deregister(mpt_base_index);
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
module_init(fusion_init); module_init(fusion_init);
module_exit(fusion_exit); module_exit(fusion_exit);
...@@ -80,8 +80,8 @@ ...@@ -80,8 +80,8 @@
#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "2.05.00.06" #define MPT_LINUX_VERSION_COMMON "3.00.02"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.00.06" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.00.02"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -180,6 +180,16 @@ typedef enum { ...@@ -180,6 +180,16 @@ typedef enum {
MPTUNKNOWN_DRIVER MPTUNKNOWN_DRIVER
} MPT_DRIVER_CLASS; } MPT_DRIVER_CLASS;
struct mpt_pci_driver{
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
void (*remove) (struct pci_dev *dev);
int (*suspend) (struct pci_dev *dev, u32 state);
#ifdef CONFIG_PM
int (*resume) (struct pci_dev *dev);
void (*shutdown) (struct device * dev);
#endif
};
/* /*
* MPT adapter / port / bus / device info structures... * MPT adapter / port / bus / device info structures...
*/ */
...@@ -629,6 +639,9 @@ typedef struct _MPT_ADAPTER ...@@ -629,6 +639,9 @@ typedef struct _MPT_ADAPTER
FCPortPage0_t fc_port_page0[2]; FCPortPage0_t fc_port_page0[2];
LANPage0_t lan_cnfg_page0; LANPage0_t lan_cnfg_page0;
LANPage1_t lan_cnfg_page1; LANPage1_t lan_cnfg_page1;
#ifdef CONFIG_PM
u32 PciState[64]; /* save PCI state to this area */
#endif
u8 FirstWhoInit; u8 FirstWhoInit;
u8 upload_fw; /* If set, do a fw upload */ u8 upload_fw; /* If set, do a fw upload */
u8 reload_fw; /* Force a FW Reload on next reset */ u8 reload_fw; /* Force a FW Reload on next reset */
...@@ -1001,6 +1014,8 @@ extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc); ...@@ -1001,6 +1014,8 @@ extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
extern void mpt_event_deregister(int cb_idx); extern void mpt_event_deregister(int cb_idx);
extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func); extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
extern void mpt_reset_deregister(int cb_idx); extern void mpt_reset_deregister(int cb_idx);
extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx);
extern void mpt_device_driver_deregister(int cb_idx);
extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable); extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
extern void mpt_deregister_ascqops_strings(void); extern void mpt_deregister_ascqops_strings(void);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid); extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid);
......
...@@ -75,7 +75,8 @@ ...@@ -75,7 +75,8 @@
#include <linux/interrupt.h> /* needed for in_interrupt() proto */ #include <linux/interrupt.h> /* needed for in_interrupt() proto */
#include <linux/reboot.h> /* notifier code */ #include <linux/reboot.h> /* notifier code */
#include "../../scsi/scsi.h" #include "../../scsi/scsi.h"
#include "../../scsi/hosts.h" #include <scsi/scsi_host.h>
#include "mptbase.h" #include "mptbase.h"
#include "mptscsih.h" #include "mptscsih.h"
...@@ -164,8 +165,8 @@ static u32 SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc); ...@@ -164,8 +165,8 @@ static u32 SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc);
static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx); static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
static void post_pendingQ_commands(MPT_SCSI_HOST *hd); static void post_pendingQ_commands(MPT_SCSI_HOST *hd);
static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag); static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag); static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
...@@ -184,7 +185,7 @@ static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); ...@@ -184,7 +185,7 @@ static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
static struct mpt_work_struct mptscsih_rstTask; static struct mpt_work_struct mptscsih_rstTask;
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd); static void mptscsih_domainValidation(void *hd);
static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
...@@ -194,14 +195,19 @@ static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); ...@@ -194,14 +195,19 @@ static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width); static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
#endif #endif
static int mptscsih_setup(char *str); static int mptscsih_setup(char *str);
static int mptscsih_halt(struct notifier_block *nb, ulong event, void *buf);
/* /* module entry point */
* Reboot Notification static int __init mptscsih_init (void);
*/ static void __exit mptscsih_exit (void);
static struct notifier_block mptscsih_notifier = {
mptscsih_halt, NULL, 0 static int __devinit mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
}; static void __devexit mptscsih_remove(struct pci_dev *);
static void mptscsih_shutdown(struct device *);
#ifdef CONFIG_PM
static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
static int mptscsih_resume(struct pci_dev *pdev);
#endif
/* /*
* Private data... * Private data...
...@@ -216,7 +222,7 @@ static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */ ...@@ -216,7 +222,7 @@ static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
#define SNS_LEN(scp) sizeof((scp)->sense_buffer) #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* /*
* Domain Validation task structure * Domain Validation task structure
*/ */
...@@ -237,6 +243,32 @@ static int scandv_wait_done = 1; ...@@ -237,6 +243,32 @@ static int scandv_wait_done = 1;
static struct mptscsih_driver_setup static struct mptscsih_driver_setup
driver_setup = MPTSCSIH_DRIVER_SETUP; driver_setup = MPTSCSIH_DRIVER_SETUP;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* see mptscsih.h */
static struct scsi_host_template driver_template = {
.proc_name = "mptscsih",
.proc_info = x_scsi_proc_info,
.name = "MPT SCSI Host",
.info = x_scsi_info,
.queuecommand = x_scsi_queuecommand,
.slave_alloc = x_scsi_slave_alloc,
.slave_configure = x_scsi_slave_configure,
.slave_destroy = x_scsi_slave_destroy,
.eh_abort_handler = x_scsi_abort,
.eh_device_reset_handler = x_scsi_dev_reset,
.eh_bus_reset_handler = x_scsi_bus_reset,
.eh_host_reset_handler = x_scsi_host_reset,
.bios_param = x_scsi_bios_param,
.can_queue = MPT_SCSI_CAN_QUEUE,
.this_id = -1,
.sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = MPT_SCSI_MAX_SECTORS,
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* Private inline routines... * Private inline routines...
...@@ -264,12 +296,14 @@ static inline int ...@@ -264,12 +296,14 @@ static inline int
mptscsih_io_direction(Scsi_Cmnd *cmd) mptscsih_io_direction(Scsi_Cmnd *cmd)
{ {
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
case WRITE_6: case WRITE_6:
case WRITE_10: case WRITE_10:
case WRITE_16:
return SCSI_DATA_WRITE; return SCSI_DATA_WRITE;
break; break;
case READ_6: case READ_6:
case READ_10: case READ_10:
case READ_16:
return SCSI_DATA_READ; return SCSI_DATA_READ;
break; break;
} }
...@@ -280,6 +314,7 @@ mptscsih_io_direction(Scsi_Cmnd *cmd) ...@@ -280,6 +314,7 @@ mptscsih_io_direction(Scsi_Cmnd *cmd)
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
/* _DATA_OUT commands */ /* _DATA_OUT commands */
case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_6: case WRITE_10: case WRITE_12:
case WRITE_16:
case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER: case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER:
case WRITE_VERIFY: case WRITE_VERIFY_12: case WRITE_VERIFY: case WRITE_VERIFY_12:
case COMPARE: case COPY: case COPY_VERIFY: case COMPARE: case COPY: case COPY_VERIFY:
...@@ -826,6 +861,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -826,6 +861,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->resid = sc->request_bufflen - xfer_cnt; sc->resid = sc->request_bufflen - xfer_cnt;
dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid)); dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid));
if(sc->underflow > xfer_cnt) {
printk(MYIOC_s_INFO_FMT
"SCSI data underrun: underflow=%02x, xfercnt=%02x\n",
ioc->name, sc->underflow, xfer_cnt);
sc->result = DID_SOFT_ERROR << 16;
}
/* Report Queue Full /* Report Queue Full
*/ */
if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL) if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
...@@ -1235,7 +1277,6 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init) ...@@ -1235,7 +1277,6 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
for(ii=0;ii<hd->ioc->req_depth;ii++) for(ii=0;ii<hd->ioc->req_depth;ii++)
hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN; hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
/* ChainToChain size must equal the total number /* ChainToChain size must equal the total number
* of chain buffers to be allocated. * of chain buffers to be allocated.
* index = chain_idx * index = chain_idx
...@@ -1277,7 +1318,6 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init) ...@@ -1277,7 +1318,6 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
mem = (u8 *) hd->ChainToChain; mem = (u8 *) hd->ChainToChain;
} }
memset(mem, 0xFF, sz); memset(mem, 0xFF, sz);
sz = num_chain * hd->ioc->req_sz; sz = num_chain * hd->ioc->req_sz;
if (hd->ChainBuffer == NULL) { if (hd->ChainBuffer == NULL) {
/* Allocate free chain buffer pool /* Allocate free chain buffer pool
...@@ -1353,28 +1393,25 @@ mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIOReque ...@@ -1353,28 +1393,25 @@ mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIOReque
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int BeenHereDoneThat = 0;
static char *info_kbuf = NULL; static char *info_kbuf = NULL;
/* SCSI host fops start here... */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
* mptscsih_detect - Register MPT adapter(s) as SCSI host(s) with /*
* linux scsi mid-layer. * mptscsih_probe - Installs scsi devices per bus.
* @tpnt: Pointer to Scsi_Host_Template structure * @pdev: Pointer to pci_dev structure
* *
* (linux Scsi_Host_Template.detect routine) * Returns 0 for success, non-zero for failure.
* *
* Returns number of SCSI host adapters that were successfully
* registered with the linux scsi mid-layer via the scsi_register()
* API call.
*/ */
int
mptscsih_detect(Scsi_Host_Template *tpnt) static int __devinit
mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct Scsi_Host *sh = NULL; struct Scsi_Host *sh = NULL;
MPT_SCSI_HOST *hd = NULL; MPT_SCSI_HOST *hd = NULL;
MPT_ADAPTER *this; MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
int portnum;
MPT_DONE_Q *freedoneQ; MPT_DONE_Q *freedoneQ;
unsigned long flags; unsigned long flags;
int sz, ii; int sz, ii;
...@@ -1382,325 +1419,312 @@ mptscsih_detect(Scsi_Host_Template *tpnt) ...@@ -1382,325 +1419,312 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
int scale; int scale;
u8 *mem; u8 *mem;
if (! BeenHereDoneThat++) { for (portnum=0; portnum < ioc->facts.NumberOfPorts; portnum++) {
show_mptmod_ver(my_NAME, my_VERSION);
ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) { /* 20010215 -sralston
dprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); * Added sanity check on SCSI Initiator-mode enabled
} else { * for this MPT adapter.
/* FIXME! */ */
if (!(ioc->pfacts[portnum].ProtocolFlags &
MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
printk(MYIOC_s_WARN_FMT
"Skipping because SCSI Initiator mode is NOT enabled!\n",
ioc->name);
continue;
} }
if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) { /* 20010202 -sralston
dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n")); * Added sanity check on readiness of the MPT adapter.
} else { */
/* FIXME! */ if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
printk(MYIOC_s_WARN_FMT
"Skipping because it's not operational!\n",
ioc->name);
continue;
} }
}
dprintk((KERN_INFO MYNAM ": mpt_scsih_detect()\n"));
#ifdef MODULE sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
/* Evaluate the command line arguments, if any */ if (sh != NULL) {
if (mptscsih) spin_lock_irqsave(&ioc->FreeQlock, flags);
mptscsih_setup(mptscsih);
#endif
this = mpt_adapter_find_first();
while (this != NULL) {
int portnum;
for (portnum=0; portnum < this->facts.NumberOfPorts; portnum++) {
/* 20010215 -sralston /* Attach the SCSI Host to the IOC structure
* Added sanity check on SCSI Initiator-mode enabled
* for this MPT adapter.
*/ */
if (!(this->pfacts[portnum].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) { ioc->sh = sh;
printk(MYIOC_s_WARN_FMT "Skipping because SCSI Initiator mode is NOT enabled!\n",
this->name); sh->io_port = 0;
continue; sh->n_io_port = 0;
} sh->irq = 0;
/* 20010202 -sralston /* set 16 byte cdb's */
* Added sanity check on readiness of the MPT adapter. sh->max_cmd_len = 16;
/* Yikes! This is important!
* Otherwise, by default, linux
* only scans target IDs 0-7!
* pfactsN->MaxDevices unreliable
* (not supported in early
* versions of the FW).
* max_id = 1 + actual max id,
* max_lun = 1 + actual last lun,
* see hosts.h :o(
*/ */
if (this->last_state != MPI_IOC_STATE_OPERATIONAL) { if ((int)ioc->chip_type > (int)FC929) {
printk(MYIOC_s_WARN_FMT "Skipping because it's not operational!\n", sh->max_id = MPT_MAX_SCSI_DEVICES;
this->name); } else {
continue; /* For FC, increase the queue depth
* from MPT_SCSI_CAN_QUEUE (31)
* to MPT_FC_CAN_QUEUE (63).
*/
sh->can_queue = MPT_FC_CAN_QUEUE;
sh->max_id =
MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
} }
tpnt->proc_info = mptscsih_proc_info; sh->max_lun = MPT_LAST_LUN + 1;
sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST)); sh->max_sectors = MPT_SCSI_MAX_SECTORS;
if (sh != NULL) { sh->this_id = ioc->pfacts[portnum].PortSCSIID;
spin_lock_irqsave(&this->FreeQlock, flags);
sh->io_port = 0;
sh->n_io_port = 0;
sh->irq = 0;
/* Yikes! This is important!
* Otherwise, by default, linux
* only scans target IDs 0-7!
* pfactsN->MaxDevices unreliable
* (not supported in early
* versions of the FW).
* max_id = 1 + actual max id,
* max_lun = 1 + actual last lun,
* see hosts.h :o(
*/
if ((int)this->chip_type > (int)FC929)
sh->max_id = MPT_MAX_SCSI_DEVICES;
else {
/* For FC, increase the queue depth
* from MPT_SCSI_CAN_QUEUE (31)
* to MPT_FC_CAN_QUEUE (63).
*/
sh->can_queue = MPT_FC_CAN_QUEUE;
sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
}
sh->max_lun = MPT_LAST_LUN + 1;
sh->max_sectors = MPT_SCSI_MAX_SECTORS; /* Required entry.
sh->this_id = this->pfacts[portnum].PortSCSIID; */
sh->unique_id = ioc->id;
/* Verify that we won't exceed the maximum
* number of chain buffers
* We can optimize: ZZ = req_sz/sizeof(SGE)
* For 32bit SGE's:
* numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
* + (req_sz - 64)/sizeof(SGE)
* A slightly different algorithm is required for
* 64bit SGEs.
*/
scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
if (sizeof(dma_addr_t) == sizeof(u64)) {
numSGE = (scale - 1) *
(ioc->facts.MaxChainDepth-1) + scale +
(ioc->req_sz - 60) / (sizeof(dma_addr_t) +
sizeof(u32));
} else {
numSGE = 1 + (scale - 1) *
(ioc->facts.MaxChainDepth-1) + scale +
(ioc->req_sz - 64) / (sizeof(dma_addr_t) +
sizeof(u32));
}
/* Required entry. if (numSGE < sh->sg_tablesize) {
*/ /* Reset this value */
sh->unique_id = this->id; dprintk((MYIOC_s_INFO_FMT
"Resetting sg_tablesize to %d from %d\n",
/* Verify that we won't exceed the maximum ioc->name, numSGE, sh->sg_tablesize));
* number of chain buffers sh->sg_tablesize = numSGE;
* We can optimize: ZZ = req_sz/sizeof(SGE) }
* For 32bit SGE's:
* numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
* + (req_sz - 64)/sizeof(SGE)
* A slightly different algorithm is required for
* 64bit SGEs.
*/
scale = this->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
if (sizeof(dma_addr_t) == sizeof(u64)) {
numSGE = (scale - 1) * (this->facts.MaxChainDepth-1) + scale +
(this->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
} else {
numSGE = 1 + (scale - 1) * (this->facts.MaxChainDepth-1) + scale +
(this->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
}
if (numSGE < sh->sg_tablesize) { /* Set the pci device pointer in Scsi_Host structure.
/* Reset this value */ */
dprintk((MYIOC_s_INFO_FMT scsi_set_device(sh, &ioc->pcidev->dev);
"Resetting sg_tablesize to %d from %d\n",
this->name, numSGE, sh->sg_tablesize));
sh->sg_tablesize = numSGE;
}
/* Set the pci device pointer in Scsi_Host structure. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
*/
scsi_set_device(sh, &this->pcidev->dev);
spin_unlock_irqrestore(&this->FreeQlock, flags); hd = (MPT_SCSI_HOST *) sh->hostdata;
hd->ioc = ioc;
hd->max_sge = sh->sg_tablesize;
hd = (MPT_SCSI_HOST *) sh->hostdata; if ((int)ioc->chip_type > (int)FC929)
hd->ioc = this; hd->is_spi = 1;
hd->max_sge = sh->sg_tablesize;
if ((int)this->chip_type > (int)FC929) if (DmpService && (ioc->chip_type == FC919 ||
hd->is_spi = 1; ioc->chip_type == FC929)) {
hd->is_multipath = 1;
}
hd->port = 0; /* FIXME! */
if (DmpService && /* SCSI needs Scsi_Cmnd lookup table!
(this->chip_type == FC919 || this->chip_type == FC929)) * (with size equal to req_depth*PtrSz!)
hd->is_multipath = 1; */
sz = hd->ioc->req_depth * sizeof(void *);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
goto mptscsih_probe_failed;
hd->port = 0; /* FIXME! */ memset(mem, 0, sz);
hd->ScsiLookup = (struct scsi_cmnd **) mem;
/* SCSI needs Scsi_Cmnd lookup table! dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
* (with size equal to req_depth*PtrSz!) ioc->name, hd->ScsiLookup, sz));
*/
sz = hd->ioc->req_depth * sizeof(void *);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
goto done;
memset(mem, 0, sz); if (mptscsih_initChainBuffers(hd, 1) < 0)
hd->ScsiLookup = (struct scsi_cmnd **) mem; goto mptscsih_probe_failed;
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", /* Allocate memory for free and doneQ's
this->name, hd->ScsiLookup, sz)); */
sz = sh->can_queue * sizeof(MPT_DONE_Q);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
goto mptscsih_probe_failed;
if (mptscsih_initChainBuffers(hd, 1) < 0) memset(mem, 0xFF, sz);
goto done; hd->memQ = mem;
/* Allocate memory for free and doneQ's /* Initialize the free, done and pending Qs.
*/ */
sz = sh->can_queue * sizeof(MPT_DONE_Q); Q_INIT(&hd->freeQ, MPT_DONE_Q);
mem = kmalloc(sz, GFP_ATOMIC); Q_INIT(&hd->doneQ, MPT_DONE_Q);
if (mem == NULL) Q_INIT(&hd->pendingQ, MPT_DONE_Q);
goto done; spin_lock_init(&hd->freedoneQlock);
mem = hd->memQ;
for (ii=0; ii < sh->can_queue; ii++) {
freedoneQ = (MPT_DONE_Q *) mem;
Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q);
mem += sizeof(MPT_DONE_Q);
}
memset(mem, 0xFF, sz); /* Initialize this Scsi_Host
hd->memQ = mem; * internal task Q.
*/
Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
hd->taskQcnt = 0;
/* Initialize the free, done and pending Qs. /* Allocate memory for the device structures.
*/ * A non-Null pointer at an offset
Q_INIT(&hd->freeQ, MPT_DONE_Q); * indicates a device exists.
Q_INIT(&hd->doneQ, MPT_DONE_Q); * max_id = 1 + maximum id (hosts.h)
Q_INIT(&hd->pendingQ, MPT_DONE_Q); */
spin_lock_init(&hd->freedoneQlock); sz = sh->max_id * sizeof(void *);
mem = kmalloc(sz, GFP_ATOMIC);
mem = hd->memQ; if (mem == NULL)
for (ii=0; ii < sh->can_queue; ii++) { goto mptscsih_probe_failed;
freedoneQ = (MPT_DONE_Q *) mem;
Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q);
mem += sizeof(MPT_DONE_Q);
}
/* Initialize this Scsi_Host memset(mem, 0, sz);
* internal task Q. hd->Targets = (VirtDevice **) mem;
*/
Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
hd->taskQcnt = 0;
/* Allocate memory for the device structures. dprintk((KERN_INFO
* A non-Null pointer at an offset " Targets @ %p, sz=%d\n", hd->Targets, sz));
* indicates a device exists.
* max_id = 1 + maximum id (hosts.h)
*/
sz = sh->max_id * sizeof(void *);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
goto done;
memset(mem, 0, sz);
hd->Targets = (VirtDevice **) mem;
dprintk((KERN_INFO " Targets @ %p, sz=%d\n", hd->Targets, sz)); /* Clear the TM flags
*/
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
hd->resetPending = 0;
hd->abortSCpnt = NULL;
hd->tmPtr = NULL;
hd->numTMrequests = 0;
/* Clear the pointer used to store
* single-threaded commands, i.e., those
* issued during a bus scan, dv and
* configuration pages.
*/
hd->cmdPtr = NULL;
/* Clear the TM flags /* Initialize this SCSI Hosts' timers
*/ * To use, set the timer expires field
hd->tmPending = 0; * and add_timer
hd->tmState = TM_STATE_NONE; */
hd->resetPending = 0; init_timer(&hd->timer);
hd->abortSCpnt = NULL; hd->timer.data = (unsigned long) hd;
hd->tmPtr = NULL; hd->timer.function = mptscsih_timer_expired;
hd->numTMrequests = 0;
/* Clear the pointer used to store init_timer(&hd->TMtimer);
* single-threaded commands, i.e., those hd->TMtimer.data = (unsigned long) hd;
* issued during a bus scan, dv and hd->TMtimer.function = mptscsih_taskmgmt_timeout;
* configuration pages. hd->qtag_tick = jiffies;
*/
hd->cmdPtr = NULL;
/* Attach the SCSI Host to the IOC structure /* Moved Earlier Pam D */
*/ /* ioc->sh = sh; */
this->sh = sh;
/* Initialize this SCSI Hosts' timers if (hd->is_spi) {
* To use, set the timer expires field /* Update with the driver setup
* and add_timer * values.
*/ */
init_timer(&hd->timer); if (hd->ioc->spi_data.maxBusWidth >
hd->timer.data = (unsigned long) hd; driver_setup.max_width) {
hd->timer.function = mptscsih_timer_expired; hd->ioc->spi_data.maxBusWidth =
driver_setup.max_width;
init_timer(&hd->TMtimer); }
hd->TMtimer.data = (unsigned long) hd;
hd->TMtimer.function = mptscsih_taskmgmt_timeout;
hd->qtag_tick = jiffies;
/* Moved Earlier Pam D */
/* this->sh = sh; */
if (hd->is_spi) { if (hd->ioc->spi_data.minSyncFactor <
/* Update with the driver setup driver_setup.min_sync_fac) {
* values. hd->ioc->spi_data.minSyncFactor =
*/ driver_setup.min_sync_fac;
if (hd->ioc->spi_data.maxBusWidth > driver_setup.max_width) }
hd->ioc->spi_data.maxBusWidth = driver_setup.max_width;
if (hd->ioc->spi_data.minSyncFactor < driver_setup.min_sync_fac)
hd->ioc->spi_data.minSyncFactor = driver_setup.min_sync_fac;
if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) {
hd->ioc->spi_data.maxSyncOffset = 0; hd->ioc->spi_data.maxSyncOffset = 0;
}
hd->negoNvram = 0; hd->negoNvram = 0;
#ifdef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
hd->negoNvram = MPT_SCSICFG_USE_NVRAM; hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
#endif #endif
if (driver_setup.dv == 0) if (driver_setup.dv == 0) {
hd->negoNvram = MPT_SCSICFG_USE_NVRAM; hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
}
hd->ioc->spi_data.forceDv = 0;
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
hd->ioc->spi_data.dvStatus[ii] = MPT_SCSICFG_NEGOTIATE;
if (hd->negoNvram == 0) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_NOT_DONE;
}
ddvprintk((MYIOC_s_INFO_FMT hd->ioc->spi_data.forceDv = 0;
"dv %x width %x factor %x \n", for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
hd->ioc->name, driver_setup.dv, hd->ioc->spi_data.dvStatus[ii] =
driver_setup.max_width, MPT_SCSICFG_NEGOTIATE;
driver_setup.min_sync_fac)); }
if (hd->negoNvram == 0) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
hd->ioc->spi_data.dvStatus[ii] |=
MPT_SCSICFG_DV_NOT_DONE;
} }
mpt_scsi_hosts++; ddvprintk((MYIOC_s_INFO_FMT
"dv %x width %x factor %x \n",
hd->ioc->name, driver_setup.dv,
driver_setup.max_width,
driver_setup.min_sync_fac));
} }
} /* for each adapter port */ mpt_scsi_hosts++;
this = mpt_adapter_find_next(this); if(scsi_add_host (sh, &ioc->pcidev->dev)) {
} dprintk((KERN_ERR MYNAM,
"scsi_add_host failed\n"));
goto mptscsih_probe_failed;
}
done: scsi_scan_host(sh);
if (mpt_scsi_hosts > 0) return 0;
register_reboot_notifier(&mptscsih_notifier);
else {
mpt_reset_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
mpt_event_deregister(ScsiDoneCtx); } /* scsi_host_alloc */
dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
mpt_deregister(ScsiScanDvCtx); } /* for each adapter port */
mpt_deregister(ScsiTaskCtx);
mpt_deregister(ScsiDoneCtx);
if (info_kbuf != NULL) mptscsih_probe_failed:
kfree(info_kbuf);
} mptscsih_remove(pdev);
return -ENODEV;
return mpt_scsi_hosts;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*
/** * mptscsih_remove - Removed scsi devices
* mptscsih_release - Unregister SCSI host from linux scsi mid-layer * @pdev: Pointer to pci_dev structure
* @host: Pointer to Scsi_Host structure
* *
* (linux Scsi_Host_Template.release routine)
* This routine releases all resources associated with the SCSI host
* adapter.
* *
* Returns 0 for success.
*/ */
int static void __devexit
mptscsih_release(struct Scsi_Host *host) mptscsih_remove(struct pci_dev *pdev)
{ {
MPT_SCSI_HOST *hd; MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
int count; struct Scsi_Host *host = ioc->sh;
unsigned long flags; MPT_SCSI_HOST *hd;
int count;
unsigned long flags;
if(!host)
return;
hd = (MPT_SCSI_HOST *) host->hostdata; scsi_remove_host(host);
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* Check DV thread active */ /* Check DV thread active */
count = 10 * HZ; count = 10 * HZ;
spin_lock_irqsave(&dvtaskQ_lock, flags); spin_lock_irqsave(&dvtaskQ_lock, flags);
...@@ -1721,8 +1745,7 @@ mptscsih_release(struct Scsi_Host *host) ...@@ -1721,8 +1745,7 @@ mptscsih_release(struct Scsi_Host *host)
#endif #endif
#endif #endif
unregister_reboot_notifier(&mptscsih_notifier); hd = (MPT_SCSI_HOST *)host->hostdata;
if (hd != NULL) { if (hd != NULL) {
int sz1, sz2, sz3, sztarget=0; int sz1, sz2, sz3, sztarget=0;
int szr2chain = 0; int szr2chain = 0;
...@@ -1730,9 +1753,7 @@ mptscsih_release(struct Scsi_Host *host) ...@@ -1730,9 +1753,7 @@ mptscsih_release(struct Scsi_Host *host)
int szchain = 0; int szchain = 0;
int szQ = 0; int szQ = 0;
/* Synchronize disk caches mptscsih_shutdown(&pdev->dev);
*/
(void) mptscsih_synchronize_cache(hd, 0);
sz1 = sz2 = sz3 = 0; sz1 = sz2 = sz3 = 0;
...@@ -1796,72 +1817,203 @@ mptscsih_release(struct Scsi_Host *host) ...@@ -1796,72 +1817,203 @@ mptscsih_release(struct Scsi_Host *host)
hd->Targets = NULL; hd->Targets = NULL;
} }
dprintk((MYIOC_s_INFO_FMT "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n", dprintk((MYIOC_s_INFO_FMT
hd->ioc->name, sz1, szchain, sz3, sztarget)); "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n",
hd->ioc->name, sz1, szchain, sz3, sztarget));
dprintk(("Free'd done and free Q (%d) memory\n", szQ)); dprintk(("Free'd done and free Q (%d) memory\n", szQ));
/* NULL the Scsi_Host pointer
*/
hd->ioc->sh = NULL;
} }
/* NULL the Scsi_Host pointer
scsi_host_put(host);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_shutdown - reboot notifier
*
*/
static void
mptscsih_shutdown(struct device * dev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
struct Scsi_Host *host = ioc->sh;
MPT_SCSI_HOST *hd;
if(!host)
return;
hd = (MPT_SCSI_HOST *)host->hostdata;
/* Flush the cache of this adapter
*/ */
hd->ioc->sh = NULL; if(hd != NULL)
scsi_unregister(host); mptscsih_synchronize_cache(hd, 0);
if (mpt_scsi_hosts) { }
if (--mpt_scsi_hosts == 0) {
mpt_reset_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
mpt_event_deregister(ScsiDoneCtx); #ifdef CONFIG_PM
dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n")); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_suspend - Fusion MPT scsie driver suspend routine.
*
*
*/
static int
mptscsih_suspend(struct pci_dev *pdev, u32 state)
{
mptscsih_shutdown(&pdev->dev);
return 0;
}
mpt_deregister(ScsiScanDvCtx); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
mpt_deregister(ScsiTaskCtx); /*
mpt_deregister(ScsiDoneCtx); * mptscsih_resume - Fusion MPT scsi driver resume routine.
*
*
*/
static int
mptscsih_resume(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct Scsi_Host *host = ioc->sh;
MPT_SCSI_HOST *hd;
if (info_kbuf != NULL) if(!host)
kfree(info_kbuf); return 0;
}
}
hd = (MPT_SCSI_HOST *)host->hostdata;
if(!hd)
return 0;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
{
unsigned long lflags;
spin_lock_irqsave(&dvtaskQ_lock, lflags);
if (!dvtaskQ_active) {
dvtaskQ_active = 1;
spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
MPT_INIT_WORK(&mptscsih_dvTask,
mptscsih_domainValidation, (void *) hd);
SCHEDULE_TASK(&mptscsih_dvTask);
} else {
spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
}
}
#endif
return 0; return 0;
} }
#endif
static struct mpt_pci_driver mptscsih_driver = {
.probe = mptscsih_probe,
.remove = __devexit_p(mptscsih_remove),
.shutdown = mptscsih_shutdown,
#ifdef CONFIG_PM
.suspend = mptscsih_suspend,
.resume = mptscsih_resume,
#endif
};
/* SCSI host fops start here... */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_halt - Process the reboot notification * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
* @nb: Pointer to a struct notifier_block (ignored) * linux scsi mid-layer.
* @event: event (SYS_HALT, SYS_RESTART, SYS_POWER_OFF)
* @buf: Pointer to a data buffer (ignored)
*
* This routine called if a system shutdown or reboot is to occur.
* *
* Return NOTIFY_DONE if this is something other than a reboot message. * Returns 0 for success, non-zero for failure.
* NOTIFY_OK if this is a reboot message.
*/ */
static int static int
mptscsih_halt(struct notifier_block *nb, ulong event, void *buf) __init mptscsih_init(void)
{ {
MPT_ADAPTER *ioc = NULL; MPT_ADAPTER *ioc;
MPT_SCSI_HOST *hd = NULL;
/* Ignore all messages other than reboot message show_mptmod_ver(my_NAME, my_VERSION);
*/
if ((event != SYS_RESTART) && (event != SYS_HALT)
&& (event != SYS_POWER_OFF))
return (NOTIFY_DONE);
for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) { ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
/* Flush the cache of this adapter ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
*/ ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
if (ioc->sh) {
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; if(mpt_device_driver_register(&mptscsih_driver,
if (hd) { MPTSCSIH_DRIVER) != 0 ) {
mptscsih_synchronize_cache(hd, 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"));
}
if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
dprintk((KERN_INFO MYNAM
": Registered for IOC reset notifications\n"));
}
#ifdef MODULE
/* Evaluate the command line arguments, if any */
if (mptscsih)
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;
} }
} }
unregister_reboot_notifier(&mptscsih_notifier); if (mpt_scsi_hosts > 0)
return NOTIFY_OK; return 0;
mptscsih_exit();
return -ENODEV;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptscsih_exit - Unregisters MPT adapter(s)
*
*/
static void
__exit mptscsih_exit(void)
{
MPT_ADAPTER *ioc;
/* removing devices */
for(ioc = mpt_adapter_find_first(); ioc != NULL;
ioc = mpt_adapter_find_next(ioc)) {
if ((ioc->last_state != MPI_IOC_STATE_OPERATIONAL) ||
(ioc->sh == NULL))
continue;
mptscsih_remove(ioc->pcidev);
}
mpt_reset_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM
": Deregistered for IOC reset notifications\n"));
mpt_event_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM
": Deregistered for IOC event notifications\n"));
mpt_device_driver_deregister(MPTSCSIH_DRIVER);
mpt_deregister(ScsiScanDvCtx);
mpt_deregister(ScsiTaskCtx);
mpt_deregister(ScsiDoneCtx);
if (info_kbuf != NULL)
kfree(info_kbuf);
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -2436,7 +2588,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2436,7 +2588,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
hd->ioc->spi_data.dvStatus[target] = dvStatus; hd->ioc->spi_data.dvStatus[target] = dvStatus;
} }
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if ((dvStatus & MPT_SCSICFG_NEED_DV) || if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
(hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) { (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
unsigned long lflags; unsigned long lflags;
...@@ -2608,7 +2760,7 @@ mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx) ...@@ -2608,7 +2760,7 @@ mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
* Returns 0 for SUCCESS or -1 if FAILED. * Returns 0 for SUCCESS or -1 if FAILED.
*/ */
static int static int
mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag) mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
{ {
MPT_ADAPTER *ioc = NULL; MPT_ADAPTER *ioc = NULL;
int rc = -1; int rc = -1;
...@@ -2664,7 +2816,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ...@@ -2664,7 +2816,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
*/ */
if (hd->hard_resets < -1) if (hd->hard_resets < -1)
hd->hard_resets++; hd->hard_resets++;
rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag); rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, timeout, sleepFlag);
if (rc) { if (rc) {
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
} else { } else {
...@@ -2710,7 +2862,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ...@@ -2710,7 +2862,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
* else other non-zero value returned. * else other non-zero value returned.
*/ */
static int static int
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag) mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
{ {
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm; SCSITaskMgmt_t *pScsiTm;
...@@ -2760,7 +2912,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2ab ...@@ -2760,7 +2912,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2ab
*/ */
hd->tmPtr = mf; hd->tmPtr = mf;
hd->numTMrequests++; hd->numTMrequests++;
hd->TMtimer.expires = jiffies + HZ*20; /* 20 seconds */ hd->TMtimer.expires = jiffies + timeout;
add_timer(&hd->TMtimer); add_timer(&hd->TMtimer);
if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
...@@ -2870,7 +3022,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2870,7 +3022,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
spin_unlock_irq(host_lock); spin_unlock_irq(host_lock);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->id, SCpnt->device->lun, ctx2abort, CAN_SLEEP) SCpnt->device->id, SCpnt->device->lun,
ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
< 0) { < 0) {
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
...@@ -2940,7 +3093,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt) ...@@ -2940,7 +3093,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
} }
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->id, 0, 0, CAN_SLEEP) SCpnt->device->id, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
< 0){ < 0){
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
* Fatal error case. * Fatal error case.
...@@ -3004,7 +3157,7 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt) ...@@ -3004,7 +3157,7 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
/* We are now ready to execute the task management request. */ /* We are now ready to execute the task management request. */
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
0, 0, 0, CAN_SLEEP) 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
< 0){ < 0){
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
...@@ -3087,7 +3240,7 @@ static int ...@@ -3087,7 +3240,7 @@ static int
mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
{ {
unsigned long flags; unsigned long flags;
int loop_count = 60 * 4; /* Wait 60 seconds */ int loop_count = 10 * 4; /* Wait 10 seconds */
int status = FAILED; int status = FAILED;
do { do {
...@@ -3227,18 +3380,50 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m ...@@ -3227,18 +3380,50 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
*/ */
int int
mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
sector_t capacity, int *ip) sector_t capacity, int geom[])
{ {
int size; int heads;
int sectors;
sector_t cylinders;
#ifdef CONFIG_LBD
ulong dummy;
#endif
size = capacity; heads = 64;
ip[0] = 64; /* heads */ sectors = 32;
ip[1] = 32; /* sectors */ #ifdef CONFIG_LBD
if ((ip[2] = size >> 11) > 1024) { /* cylinders, test for big disk */ dummy = heads * sectors;
ip[0] = 255; /* heads */ cylinders = capacity;
ip[1] = 63; /* sectors */ sector_div(cylinders,dummy);
ip[2] = size / (255 * 63); /* cylinders */ #else
cylinders = (ulong)capacity / (heads * sectors);
#endif
/*
* Handle extended translation size for logical drives
* > 1Gb
*/
if ((ulong)capacity >= 0x200000) {
heads = 255;
sectors = 63;
#ifdef CONFIG_LBD
dummy = heads * sectors;
cylinders = capacity;
sector_div(cylinders,dummy);
#else
cylinders = (ulong)capacity / (heads * sectors);
#endif
} }
/* return result */
geom[0] = heads;
geom[1] = sectors;
geom[2] = cylinders;
dprintk((KERN_NOTICE
": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
return 0; return 0;
} }
...@@ -3368,7 +3553,7 @@ mptscsih_slave_configure(Scsi_Device *device) ...@@ -3368,7 +3553,7 @@ mptscsih_slave_configure(Scsi_Device *device)
vdev->raidVolume = 0; vdev->raidVolume = 0;
if (hd->is_spi && (hd->ioc->spi_data.isRaid & (1 << (device->id)))) { if (hd->is_spi && (hd->ioc->spi_data.isRaid & (1 << (device->id)))) {
vdev->raidVolume = 1; vdev->raidVolume = 1;
ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id)); ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", device->id));
} }
mptscsih_target_settings(hd, vdev, device); mptscsih_target_settings(hd, vdev, device);
...@@ -3650,36 +3835,6 @@ SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc) ...@@ -3650,36 +3835,6 @@ SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc)
return -1; return -1;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* see mptscsih.h */
#ifdef MPT_SCSIHOST_NEED_ENTRY_EXIT_HOOKUPS
static Scsi_Host_Template driver_template = {
.proc_name = "mptscsih",
.proc_info = x_scsi_proc_info,
.name = "MPT SCSI Host",
.detect = x_scsi_detect,
.release = x_scsi_release,
.info = x_scsi_info,
.queuecommand = x_scsi_queuecommand,
.slave_alloc = x_scsi_slave_alloc,
.slave_configure = x_scsi_slave_configure,
.slave_destroy = x_scsi_slave_destroy,
.eh_abort_handler = x_scsi_abort,
.eh_device_reset_handler = x_scsi_dev_reset,
.eh_bus_reset_handler = x_scsi_bus_reset,
.eh_host_reset_handler = x_scsi_host_reset,
.bios_param = x_scsi_bios_param,
.can_queue = MPT_SCSI_CAN_QUEUE,
.this_id = -1,
.sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = MPT_SCSI_MAX_SECTORS,
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
};
#include "../../scsi/scsi_module.c"
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Search the pendingQ for a command with specific index. /* Search the pendingQ for a command with specific index.
...@@ -3958,7 +4113,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -3958,7 +4113,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
break; break;
case MPI_EVENT_INTEGRATED_RAID: /* 0B */ case MPI_EVENT_INTEGRATED_RAID: /* 0B */
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* negoNvram set to 0 if DV enabled and to USE_NVRAM if /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
* if DV disabled. Need to check for target mode. * if DV disabled. Need to check for target mode.
*/ */
...@@ -3972,7 +4127,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -3972,7 +4127,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
int numPDisk; int numPDisk;
u8 reason; u8 reason;
u8 physDiskNum; u8 physDiskNum;
reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16; reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
/* New or replaced disk. /* New or replaced disk.
...@@ -4320,6 +4475,8 @@ int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop) ...@@ -4320,6 +4475,8 @@ int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop)
case WRITE_10: case WRITE_10:
case READ_12: case READ_12:
case WRITE_12: case WRITE_12:
case READ_16:
case WRITE_16:
break; break;
default: default:
return 0; return 0;
...@@ -4618,7 +4775,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -4618,7 +4775,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
//negoFlags = MPT_TARGET_NO_NEGO_SYNC; //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
} }
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* Force to async and narrow if DV has not been executed /* Force to async and narrow if DV has not been executed
* for this ID * for this ID
*/ */
...@@ -5000,7 +5157,7 @@ static void mptscsih_timer_expired(unsigned long data) ...@@ -5000,7 +5157,7 @@ static void mptscsih_timer_expired(unsigned long data)
return; return;
} }
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptscsih_do_raid - Format and Issue a RAID volume request message. /* mptscsih_do_raid - Format and Issue a RAID volume request message.
* @hd: Pointer to scsi host structure * @hd: Pointer to scsi host structure
...@@ -5071,7 +5228,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io) ...@@ -5071,7 +5228,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
return 0; return 0;
} }
#endif /* ~MPTSCSIH_DISABLE_DOMAIN_VALIDATION */ #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
...@@ -5383,7 +5540,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) ...@@ -5383,7 +5540,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
if (ioc->spi_data.sdp1length > 0) { if (ioc->spi_data.sdp1length > 0) {
pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
if (pcfg1Data != NULL) { if (pcfg1Data != NULL) {
doConfig = 1; doConfig = 1;
header1.PageVersion = ioc->spi_data.sdp1version; header1.PageVersion = ioc->spi_data.sdp1version;
...@@ -5415,7 +5572,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) ...@@ -5415,7 +5572,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
flags = hd->ioc->spi_data.noQas; flags = hd->ioc->spi_data.noQas;
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id]; data = hd->ioc->spi_data.nvram[id];
if (data & MPT_NVRAM_WIDE_DISABLE) if (data & MPT_NVRAM_WIDE_DISABLE)
flags |= MPT_TARGET_NO_NEGO_WIDE; flags |= MPT_TARGET_NO_NEGO_WIDE;
...@@ -5424,7 +5581,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) ...@@ -5424,7 +5581,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
flags |= MPT_TARGET_NO_NEGO_SYNC; flags |= MPT_TARGET_NO_NEGO_SYNC;
} }
} }
/* Force to async, narrow */ /* Force to async, narrow */
mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
&configuration, flags); &configuration, flags);
...@@ -5467,7 +5624,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) ...@@ -5467,7 +5624,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
return 0; return 0;
} }
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_domainValidation - Top level handler for domain validation. * mptscsih_domainValidation - Top level handler for domain validation.
...@@ -5520,7 +5677,7 @@ mptscsih_domainValidation(void *arg) ...@@ -5520,7 +5677,7 @@ mptscsih_domainValidation(void *arg)
/* DV only to SCSI adapters */ /* DV only to SCSI adapters */
if ((int)ioc->chip_type <= (int)FC929) if ((int)ioc->chip_type <= (int)FC929)
continue; continue;
/* Make sure everything looks ok */ /* Make sure everything looks ok */
if (ioc->sh == NULL) if (ioc->sh == NULL)
continue; continue;
...@@ -6914,7 +7071,7 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width) ...@@ -6914,7 +7071,7 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width)
break; break;
} }
} }
#endif /* ~MPTSCSIH_DISABLE_DOMAIN_VALIDATION */ #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Commandline Parsing routines and defines. /* Commandline Parsing routines and defines.
...@@ -7009,3 +7166,6 @@ mptscsih_setup(char *str) ...@@ -7009,3 +7166,6 @@ mptscsih_setup(char *str)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
module_init(mptscsih_init);
module_exit(mptscsih_exit);
...@@ -98,13 +98,14 @@ ...@@ -98,13 +98,14 @@
#define MPT_SCSI_SG_DEPTH 40 #define MPT_SCSI_SG_DEPTH 40
#endif #endif
/* To disable domain validation, uncomment the /* To disable domain validation, comment the
* following line. No effect for FC devices. * following line. No effect for FC devices.
* For SCSI devices, driver will negotiate to * For SCSI devices, driver will negotiate to
* NVRAM settings (if available) or to maximum adapter * NVRAM settings (if available) or to maximum adapter
* capabilities. * capabilities.
*/ */
/* #define MPTSCSIH_DISABLE_DOMAIN_VALIDATION */
#define MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* SCSI driver setup structure. Settings can be overridden /* SCSI driver setup structure. Settings can be overridden
...@@ -137,15 +138,6 @@ struct mptscsih_driver_setup ...@@ -137,15 +138,6 @@ struct mptscsih_driver_setup
* So here are various HACKS to work around them. * So here are various HACKS to work around them.
*/ */
/*
* Conditionalizing with "#ifdef MODULE/#endif" around:
* static Scsi_Host_Template driver_template = XX;
* #include <../../scsi/scsi_module.c>
* lines was REMOVED @ lk-2.4.0-test9
* Issue discovered 20001213 by: sshirron
*/
#define MPT_SCSIHOST_NEED_ENTRY_EXIT_HOOKUPS 1
/* /*
* tq_scheduler disappeared @ lk-2.4.0-test12 * tq_scheduler disappeared @ lk-2.4.0-test12
* (right when <linux/sched.h> newly defined TQ_ACTIVE) * (right when <linux/sched.h> newly defined TQ_ACTIVE)
...@@ -160,8 +152,6 @@ struct mptscsih_driver_setup ...@@ -160,8 +152,6 @@ struct mptscsih_driver_setup
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define x_scsi_detect mptscsih_detect
#define x_scsi_release mptscsih_release
#define x_scsi_info mptscsih_info #define x_scsi_info mptscsih_info
#define x_scsi_queuecommand mptscsih_qcmd #define x_scsi_queuecommand mptscsih_qcmd
#define x_scsi_abort mptscsih_abort #define x_scsi_abort mptscsih_abort
...@@ -170,9 +160,6 @@ struct mptscsih_driver_setup ...@@ -170,9 +160,6 @@ struct mptscsih_driver_setup
#define x_scsi_host_reset mptscsih_host_reset #define x_scsi_host_reset mptscsih_host_reset
#define x_scsi_bios_param mptscsih_bios_param #define x_scsi_bios_param mptscsih_bios_param
#define x_scsi_taskmgmt_bh mptscsih_taskmgmt_bh
#define x_scsi_old_abort mptscsih_old_abort
#define x_scsi_old_reset mptscsih_old_reset
#define x_scsi_slave_alloc mptscsih_slave_alloc #define x_scsi_slave_alloc mptscsih_slave_alloc
#define x_scsi_slave_configure mptscsih_slave_configure #define x_scsi_slave_configure mptscsih_slave_configure
#define x_scsi_slave_destroy mptscsih_slave_destroy #define x_scsi_slave_destroy mptscsih_slave_destroy
...@@ -182,8 +169,6 @@ struct mptscsih_driver_setup ...@@ -182,8 +169,6 @@ struct mptscsih_driver_setup
/* /*
* MPT SCSI Host / Initiator decls... * MPT SCSI Host / Initiator decls...
*/ */
extern int x_scsi_detect(Scsi_Host_Template *);
extern int x_scsi_release(struct Scsi_Host *host);
extern const char *x_scsi_info(struct Scsi_Host *); extern const char *x_scsi_info(struct Scsi_Host *);
extern int x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
extern int x_scsi_abort(Scsi_Cmnd *); extern int x_scsi_abort(Scsi_Cmnd *);
...@@ -191,8 +176,7 @@ extern int x_scsi_bus_reset(Scsi_Cmnd *); ...@@ -191,8 +176,7 @@ extern int x_scsi_bus_reset(Scsi_Cmnd *);
extern int x_scsi_dev_reset(Scsi_Cmnd *); extern int x_scsi_dev_reset(Scsi_Cmnd *);
extern int x_scsi_host_reset(Scsi_Cmnd *); extern int x_scsi_host_reset(Scsi_Cmnd *);
extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev, extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev,
sector_t capacity, int *ip); sector_t capacity, int geom[]);
extern void x_scsi_taskmgmt_bh(void *);
extern int x_scsi_slave_alloc(Scsi_Device *); extern int x_scsi_slave_alloc(Scsi_Device *);
extern int x_scsi_slave_configure(Scsi_Device *); extern int x_scsi_slave_configure(Scsi_Device *);
extern void x_scsi_slave_destroy(Scsi_Device *); extern void x_scsi_slave_destroy(Scsi_Device *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment