Commit 466544d8 authored by Moore, Eric Dean's avatar Moore, Eric Dean Committed by James Bottomley

[SCSI] fusion SAS support (mptsas driver) updates

Summary of Changes:
* splitting mpt_interrupt per Christophs suggestion
about a month ago
* rename ScsiCfgData to SpiCfgData structure,
then move all the raid related info into
new structure called RaidCfgData.  This is
done because SAS supports RAID, as well as SPI,
so the raid stuff should be seperate.
* incorrect timeout calculation for cntdn
inside WaitForDoorbellAck and WaitForDoortbellInt
* add support for interpreting SAS Log Info
* Increase Event Log Size from 0xA to 0x32
* Fix bug in mptsas/mptfc/mptspi - when controller
has Initiator Mode Disabled, and only running in
TargetMode, the mptctl would panic when loading.
The fix is to return 0, instead of -ENODEV, in
SCSI LLD respective probe routines
* Fix bug in mptlan.c - driver will panic if
there is host reset, due to dev being set to
zero in mpt_lan_ioc_reset
* Fix's for SPI - Echo Buffer
* Several fix's in mptscsih_io_done - FCP Response
info, RESIDUAL_MISMATCH, Data Underrun, etc.
* Cleanup Error Handling - EH handlers,
mptscsih_flush_cmds, and zeroing out ScsiLookup
from mptscsih_qcmd
* Cleanup asyn event handling from
mptscsih -> mptscsih_event_process.  Also
added support for SAS Persistent Table Full,
an asyn event
Signed-off-by: default avatarEric Moore <Eric.Moore@lsil.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 0c33b27d
...@@ -135,7 +135,6 @@ static void mpt_adapter_dispose(MPT_ADAPTER *ioc); ...@@ -135,7 +135,6 @@ static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
//static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
...@@ -178,6 +177,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t * ...@@ -178,6 +177,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *
static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
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);
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
/* module entry point */ /* module entry point */
static int __init fusion_init (void); static int __init fusion_init (void);
...@@ -209,58 +209,79 @@ pci_enable_io_access(struct pci_dev *pdev) ...@@ -209,58 +209,79 @@ pci_enable_io_access(struct pci_dev *pdev)
pci_write_config_word(pdev, PCI_COMMAND, command_reg); pci_write_config_word(pdev, PCI_COMMAND, command_reg);
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler. * Process turbo (context) reply...
* @irq: irq number (not used)
* @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
* @r: pt_regs pointer (not used)
*
* This routine is registered via the request_irq() kernel API call,
* and handles all interrupts generated from a specific MPT adapter
* (also referred to as a IO Controller or IOC).
* This routine must clear the interrupt from the adapter and does
* so by reading the reply FIFO. Multiple replies may be processed
* per single call to this routine.
*
* This routine handles register-level access of the adapter but
* dispatches (calls) a protocol-specific callback routine to handle
* the protocol-specific details of the MPT request completion.
*/ */
static irqreturn_t static void
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
{ {
MPT_ADAPTER *ioc; MPT_FRAME_HDR *mf = NULL;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mr = NULL;
MPT_FRAME_HDR *mr; int req_idx = 0;
u32 pa;
int req_idx;
int cb_idx; int cb_idx;
int type;
int freeme;
ioc = (MPT_ADAPTER *)bus_id; dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
ioc->name, pa));
switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
req_idx = pa & 0x0000FFFF;
cb_idx = (pa & 0x00FF0000) >> 16;
mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
break;
case MPI_CONTEXT_REPLY_TYPE_LAN:
cb_idx = mpt_lan_index;
/* /*
* Drain the reply FIFO! * Blind set of mf to NULL here was fatal
* * after lan_reply says "freeme"
* NOTES: I've seen up to 10 replies processed in this loop, so far... * Fix sort of combined with an optimization here;
* Update: I've seen up to 9182 replies processed in this loop! ?? * added explicit check for case where lan_reply
* Update: Limit ourselves to processing max of N replies * was just returning 1 and doing nothing else.
* (bottom of loop). * For this case skip the callback, but set up
* proper mf value first here:-)
*/ */
while (1) { if ((pa & 0x58000000) == 0x58000000) {
req_idx = pa & 0x0000FFFF;
mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
mpt_free_msg_frame(ioc, mf);
mb();
return;
break;
}
mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
break;
case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
cb_idx = mpt_stm_index;
mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
break;
default:
cb_idx = 0;
BUG();
}
if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF) /* Check for (valid) IO callback! */
return IRQ_HANDLED; if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
MptCallbacks[cb_idx] == NULL) {
printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
__FUNCTION__, ioc->name, cb_idx);
goto out;
}
cb_idx = 0; if (MptCallbacks[cb_idx](ioc, mf, mr))
freeme = 0; mpt_free_msg_frame(ioc, mf);
out:
mb();
}
static void
mpt_reply(MPT_ADAPTER *ioc, u32 pa)
{
MPT_FRAME_HDR *mf;
MPT_FRAME_HDR *mr;
int req_idx;
int cb_idx;
int freeme;
/*
* Check for non-TURBO reply!
*/
if (pa & MPI_ADDRESS_REPLY_A_BIT) {
u32 reply_dma_low; u32 reply_dma_low;
u16 ioc_stat; u16 ioc_stat;
...@@ -273,7 +294,8 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) ...@@ -273,7 +294,8 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
* pa is 32 bits - but the dma address may be 32 or 64 bits * pa is 32 bits - but the dma address may be 32 or 64 bits
* get offset based only only the low addresses * get offset based only only the low addresses
*/ */
reply_dma_low = (pa = (pa << 1));
reply_dma_low = (pa <<= 1);
mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames + mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
(reply_dma_low - ioc->reply_frames_low_dma)); (reply_dma_low - ioc->reply_frames_low_dma));
...@@ -294,100 +316,73 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) ...@@ -294,100 +316,73 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
mpt_fc_log_info(ioc, log_info); mpt_fc_log_info(ioc, log_info);
else if (ioc->bus_type == SCSI) else if (ioc->bus_type == SCSI)
mpt_sp_log_info(ioc, log_info); mpt_sp_log_info(ioc, log_info);
else if (ioc->bus_type == SAS)
mpt_sas_log_info(ioc, log_info);
} }
if (ioc_stat & MPI_IOCSTATUS_MASK) { if (ioc_stat & MPI_IOCSTATUS_MASK) {
if (ioc->bus_type == SCSI) if (ioc->bus_type == SCSI &&
cb_idx != mpt_stm_index &&
cb_idx != mpt_lan_index)
mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf); mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
} }
} else {
/*
* Process turbo (context) reply...
*/
dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
cb_idx = mpt_stm_index;
mf = NULL;
mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
} else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
cb_idx = mpt_lan_index;
/* Blind set of mf to NULL here was fatal
* after lan_reply says "freeme"
* Fix sort of combined with an optimization here;
* added explicit check for case where lan_reply
* was just returning 1 and doing nothing else.
* For this case skip the callback, but set up
* proper mf value first here:-)
*/
if ((pa & 0x58000000) == 0x58000000) {
req_idx = pa & 0x0000FFFF;
mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
freeme = 1;
/*
* IMPORTANT! Invalidate the callback!
*/
cb_idx = 0;
} else {
mf = NULL;
}
mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
} else {
req_idx = pa & 0x0000FFFF;
cb_idx = (pa & 0x00FF0000) >> 16;
mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
mr = NULL;
}
pa = 0; /* No reply flush! */
}
#ifdef MPT_DEBUG_IRQ
if (ioc->bus_type == SCSI) {
/* Verify mf, mr are reasonable.
*/
if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
|| (mf < ioc->req_frames)) ) {
printk(MYIOC_s_WARN_FMT
"mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf);
cb_idx = 0;
pa = 0;
freeme = 0;
}
if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
|| (mr < ioc->reply_frames)) ) {
printk(MYIOC_s_WARN_FMT
"mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
cb_idx = 0;
pa = 0;
freeme = 0;
}
if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
printk(MYIOC_s_WARN_FMT
"mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
cb_idx = 0;
pa = 0;
freeme = 0;
}
}
#endif
/* Check for (valid) IO callback! */ /* Check for (valid) IO callback! */
if (cb_idx) { if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
/* Do the callback! */ MptCallbacks[cb_idx] == NULL) {
freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr); printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
__FUNCTION__, ioc->name, cb_idx);
freeme = 0;
goto out;
} }
if (pa) { freeme = MptCallbacks[cb_idx](ioc, mf, mr);
out:
/* Flush (non-TURBO) reply with a WRITE! */ /* Flush (non-TURBO) reply with a WRITE! */
CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa); CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
}
if (freeme) { if (freeme)
/* Put Request back on FreeQ! */
mpt_free_msg_frame(ioc, mf); mpt_free_msg_frame(ioc, mf);
}
mb(); mb();
} /* drain reply FIFO */ }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
* @irq: irq number (not used)
* @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
* @r: pt_regs pointer (not used)
*
* This routine is registered via the request_irq() kernel API call,
* and handles all interrupts generated from a specific MPT adapter
* (also referred to as a IO Controller or IOC).
* This routine must clear the interrupt from the adapter and does
* so by reading the reply FIFO. Multiple replies may be processed
* per single call to this routine.
*
* This routine handles register-level access of the adapter but
* dispatches (calls) a protocol-specific callback routine to handle
* the protocol-specific details of the MPT request completion.
*/
static irqreturn_t
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
{
MPT_ADAPTER *ioc = bus_id;
u32 pa;
/*
* Drain the reply FIFO!
*/
while (1) {
pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
if (pa == 0xFFFFFFFF)
return IRQ_HANDLED;
else if (pa & MPI_ADDRESS_REPLY_A_BIT)
mpt_reply(ioc, pa);
else
mpt_turbo_reply(ioc, pa);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -1065,7 +1060,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) ...@@ -1065,7 +1060,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
ioc->name, ioc->name,
ioc->HostPageBuffer, ioc->HostPageBuffer,
ioc->HostPageBuffer_dma, ioc->HostPageBuffer_dma,
hst_page_buffer_sz)); host_page_buffer_sz));
ioc->alloc_total += host_page_buffer_sz; ioc->alloc_total += host_page_buffer_sz;
ioc->HostPageBuffer_sz = host_page_buffer_sz; ioc->HostPageBuffer_sz = host_page_buffer_sz;
break; break;
...@@ -1208,7 +1203,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1208,7 +1203,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initilize SCSI Config Data structure /* Initilize SCSI Config Data structure
*/ */
memset(&ioc->spi_data, 0, sizeof(ScsiCfgData)); memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
/* Initialize the running configQ head. /* Initialize the running configQ head.
*/ */
...@@ -1755,8 +1750,23 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1755,8 +1750,23 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
*/ */
if (ret == 0) { if (ret == 0) {
rc = mpt_do_upload(ioc, sleepFlag); rc = mpt_do_upload(ioc, sleepFlag);
if (rc != 0) if (rc == 0) {
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
/*
* Maintain only one pointer to FW memory
* so there will not be two attempt to
* downloadboot onboard dual function
* chips (mpt_adapter_disable,
* mpt_diag_reset)
*/
ioc->cached_fw = NULL;
ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
}
} else {
printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
ret = -5;
}
} }
} }
} }
...@@ -1997,9 +2007,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) ...@@ -1997,9 +2007,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
} }
kfree(ioc->spi_data.nvram); kfree(ioc->spi_data.nvram);
kfree(ioc->spi_data.pIocPg3); kfree(ioc->raid_data.pIocPg3);
ioc->spi_data.nvram = NULL; ioc->spi_data.nvram = NULL;
ioc->spi_data.pIocPg3 = NULL; ioc->raid_data.pIocPg3 = NULL;
if (ioc->spi_data.pIocPg4 != NULL) { if (ioc->spi_data.pIocPg4 != NULL) {
sz = ioc->spi_data.IocPg4Sz; sz = ioc->spi_data.IocPg4Sz;
...@@ -3852,7 +3862,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -3852,7 +3862,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0; int count = 0;
u32 intstat=0; u32 intstat=0;
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
while (--cntdn) { while (--cntdn) {
...@@ -3902,7 +3912,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -3902,7 +3912,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0; int count = 0;
u32 intstat=0; u32 intstat=0;
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
while (--cntdn) { while (--cntdn) {
intstat = CHIPREG_READ32(&ioc->chip->IntStatus); intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
...@@ -4634,10 +4644,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc) ...@@ -4634,10 +4644,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
if (mpt_config(ioc, &cfg) != 0) if (mpt_config(ioc, &cfg) != 0)
goto done_and_free; goto done_and_free;
if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) { if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
mem = kmalloc(iocpage2sz, GFP_ATOMIC); mem = kmalloc(iocpage2sz, GFP_ATOMIC);
if (mem) { if (mem) {
ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem; ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
} else { } else {
goto done_and_free; goto done_and_free;
} }
...@@ -4654,7 +4664,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc) ...@@ -4654,7 +4664,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* At least 1 RAID Volume /* At least 1 RAID Volume
*/ */
pIocRv = pIoc2->RaidVolume; pIocRv = pIoc2->RaidVolume;
ioc->spi_data.isRaid = 0; ioc->raid_data.isRaid = 0;
for (jj = 0; jj < nVols; jj++, pIocRv++) { for (jj = 0; jj < nVols; jj++, pIocRv++) {
vid = pIocRv->VolumeID; vid = pIocRv->VolumeID;
vbus = pIocRv->VolumeBus; vbus = pIocRv->VolumeBus;
...@@ -4663,7 +4673,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc) ...@@ -4663,7 +4673,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* find the match /* find the match
*/ */
if (vbus == 0) { if (vbus == 0) {
ioc->spi_data.isRaid |= (1 << vid); ioc->raid_data.isRaid |= (1 << vid);
} else { } else {
/* Error! Always bus 0 /* Error! Always bus 0
*/ */
...@@ -4698,8 +4708,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) ...@@ -4698,8 +4708,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
/* Free the old page /* Free the old page
*/ */
kfree(ioc->spi_data.pIocPg3); kfree(ioc->raid_data.pIocPg3);
ioc->spi_data.pIocPg3 = NULL; ioc->raid_data.pIocPg3 = NULL;
/* There is at least one physical disk. /* There is at least one physical disk.
* Read and save IOC Page 3 * Read and save IOC Page 3
...@@ -4736,7 +4746,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) ...@@ -4736,7 +4746,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
mem = kmalloc(iocpage3sz, GFP_ATOMIC); mem = kmalloc(iocpage3sz, GFP_ATOMIC);
if (mem) { if (mem) {
memcpy(mem, (u8 *)pIoc3, iocpage3sz); memcpy(mem, (u8 *)pIoc3, iocpage3sz);
ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem; ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
} }
} }
...@@ -6022,6 +6032,111 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) ...@@ -6022,6 +6032,111 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
} }
/* strings for sas loginfo */
static char *originator_str[] = {
"IOP", /* 00h */
"PL", /* 01h */
"IR" /* 02h */
};
static char *iop_code_str[] = {
NULL, /* 00h */
"Invalid SAS Address", /* 01h */
NULL, /* 02h */
"Invalid Page", /* 03h */
NULL, /* 04h */
"Task Terminated" /* 05h */
};
static char *pl_code_str[] = {
NULL, /* 00h */
"Open Failure", /* 01h */
"Invalid Scatter Gather List", /* 02h */
"Wrong Relative Offset or Frame Length", /* 03h */
"Frame Transfer Error", /* 04h */
"Transmit Frame Connected Low", /* 05h */
"SATA Non-NCQ RW Error Bit Set", /* 06h */
"SATA Read Log Receive Data Error", /* 07h */
"SATA NCQ Fail All Commands After Error", /* 08h */
"SATA Error in Receive Set Device Bit FIS", /* 09h */
"Receive Frame Invalid Message", /* 0Ah */
"Receive Context Message Valid Error", /* 0Bh */
"Receive Frame Current Frame Error", /* 0Ch */
"SATA Link Down", /* 0Dh */
"Discovery SATA Init W IOS", /* 0Eh */
"Config Invalid Page", /* 0Fh */
"Discovery SATA Init Timeout", /* 10h */
"Reset", /* 11h */
"Abort", /* 12h */
"IO Not Yet Executed", /* 13h */
"IO Executed", /* 14h */
NULL, /* 15h */
NULL, /* 16h */
NULL, /* 17h */
NULL, /* 18h */
NULL, /* 19h */
NULL, /* 1Ah */
NULL, /* 1Bh */
NULL, /* 1Ch */
NULL, /* 1Dh */
NULL, /* 1Eh */
NULL, /* 1Fh */
"Enclosure Management" /* 20h */
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_sas_log_info - Log information returned from SAS IOC.
* @ioc: Pointer to MPT_ADAPTER structure
* @log_info: U32 LogInfo reply word from the IOC
*
* Refer to lsi/mpi_log_sas.h.
*/
static void
mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
{
union loginfo_type {
u32 loginfo;
struct {
u32 subcode:16;
u32 code:8;
u32 originator:4;
u32 bus_type:4;
}dw;
};
union loginfo_type sas_loginfo;
char *code_desc = NULL;
sas_loginfo.loginfo = log_info;
if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
(sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
return;
if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
(sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
code_desc = iop_code_str[sas_loginfo.dw.code];
}else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
(sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
code_desc = pl_code_str[sas_loginfo.dw.code];
}
if (code_desc != NULL)
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code={%s},"
" SubCode(0x%04x)\n",
ioc->name,
log_info,
originator_str[sas_loginfo.dw.originator],
code_desc,
sas_loginfo.dw.subcode);
else
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
" SubCode(0x%04x)\n",
ioc->name,
log_info,
originator_str[sas_loginfo.dw.originator],
sas_loginfo.dw.code,
sas_loginfo.dw.subcode);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC. * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
......
...@@ -77,8 +77,8 @@ ...@@ -77,8 +77,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.03.02" #define MPT_LINUX_VERSION_COMMON "3.03.03"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.02" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -424,7 +424,7 @@ typedef struct _MPT_IOCTL { ...@@ -424,7 +424,7 @@ typedef struct _MPT_IOCTL {
/* /*
* Event Structure and define * Event Structure and define
*/ */
#define MPTCTL_EVENT_LOG_SIZE (0x0000000A) #define MPTCTL_EVENT_LOG_SIZE (0x000000032)
typedef struct _mpt_ioctl_events { typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */ u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */ u32 eventContext; /* Index or counter */
...@@ -452,16 +452,13 @@ typedef struct _mpt_ioctl_events { ...@@ -452,16 +452,13 @@ typedef struct _mpt_ioctl_events {
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */ #define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ /* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
typedef struct _ScsiCfgData { typedef struct _SpiCfgData {
u32 PortFlags; u32 PortFlags;
int *nvram; /* table of device NVRAM values */ int *nvram; /* table of device NVRAM values */
IOCPage2_t *pIocPg2; /* table of Raid Volumes */
IOCPage3_t *pIocPg3; /* table of physical disks */
IOCPage4_t *pIocPg4; /* SEP devices addressing */ IOCPage4_t *pIocPg4; /* SEP devices addressing */
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
int IocPg4Sz; /* IOCPage4 size */ int IocPg4Sz; /* IOCPage4 size */
u8 dvStatus[MPT_MAX_SCSI_DEVICES]; u8 dvStatus[MPT_MAX_SCSI_DEVICES];
int isRaid; /* bit field, 1 if RAID */
u8 minSyncFactor; /* 0xFF if async */ u8 minSyncFactor; /* 0xFF if async */
u8 maxSyncOffset; /* 0 if async */ u8 maxSyncOffset; /* 0 if async */
u8 maxBusWidth; /* 0 if narrow, 1 if wide */ u8 maxBusWidth; /* 0 if narrow, 1 if wide */
...@@ -473,10 +470,14 @@ typedef struct _ScsiCfgData { ...@@ -473,10 +470,14 @@ typedef struct _ScsiCfgData {
u8 dvScheduled; /* 1 if scheduled */ u8 dvScheduled; /* 1 if scheduled */
u8 forceDv; /* 1 to force DV scheduling */ u8 forceDv; /* 1 to force DV scheduling */
u8 noQas; /* Disable QAS for this adapter */ u8 noQas; /* Disable QAS for this adapter */
u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */ u8 Saf_Te; /* 1 to force all Processors as
* SAF-TE if Inquiry data length
* is too short to check for SAF-TE
*/
u8 mpt_dv; /* command line option: enhanced=1, basic=0 */ u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
u8 bus_reset; /* 1 to allow bus reset */
u8 rsvd[1]; u8 rsvd[1];
} ScsiCfgData; }SpiCfgData;
typedef struct _SasCfgData { typedef struct _SasCfgData {
u8 ptClear; /* 1 to automatically clear the u8 ptClear; /* 1 to automatically clear the
...@@ -486,6 +487,12 @@ typedef struct _SasCfgData { ...@@ -486,6 +487,12 @@ typedef struct _SasCfgData {
*/ */
}SasCfgData; }SasCfgData;
typedef struct _RaidCfgData {
IOCPage2_t *pIocPg2; /* table of Raid Volumes */
IOCPage3_t *pIocPg3; /* table of physical disks */
int isRaid; /* bit field, 1 if RAID */
}RaidCfgData;
/* /*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
*/ */
...@@ -546,7 +553,8 @@ typedef struct _MPT_ADAPTER ...@@ -546,7 +553,8 @@ typedef struct _MPT_ADAPTER
struct pci_dev *pcidev; /* struct pci_dev pointer */ struct pci_dev *pcidev; /* struct pci_dev pointer */
u8 __iomem *memmap; /* mmap address */ u8 __iomem *memmap; /* mmap address */
struct Scsi_Host *sh; /* Scsi Host pointer */ struct Scsi_Host *sh; /* Scsi Host pointer */
ScsiCfgData spi_data; /* Scsi config. data */ SpiCfgData spi_data; /* Scsi config. data */
RaidCfgData raid_data; /* Raid config. data */
SasCfgData sas_data; /* Sas config. data */ SasCfgData sas_data; /* Sas config. data */
MPT_IOCTL *ioctl; /* ioctl data pointer */ MPT_IOCTL *ioctl; /* ioctl data pointer */
struct proc_dir_entry *ioc_dentry; struct proc_dir_entry *ioc_dentry;
......
...@@ -1326,7 +1326,7 @@ mptctl_gettargetinfo (unsigned long arg) ...@@ -1326,7 +1326,7 @@ mptctl_gettargetinfo (unsigned long arg)
*/ */
if (hd && hd->Targets) { if (hd && hd->Targets) {
mpt_findImVolumes(ioc); mpt_findImVolumes(ioc);
pIoc2 = ioc->spi_data.pIocPg2; pIoc2 = ioc->raid_data.pIocPg2;
for ( id = 0; id <= max_id; ) { for ( id = 0; id <= max_id; ) {
if ( pIoc2 && pIoc2->NumActiveVolumes ) { if ( pIoc2 && pIoc2->NumActiveVolumes ) {
if ( id == pIoc2->RaidVolume[0].VolumeID ) { if ( id == pIoc2->RaidVolume[0].VolumeID ) {
...@@ -1348,7 +1348,7 @@ mptctl_gettargetinfo (unsigned long arg) ...@@ -1348,7 +1348,7 @@ mptctl_gettargetinfo (unsigned long arg)
--maxWordsLeft; --maxWordsLeft;
goto next_id; goto next_id;
} else { } else {
pIoc3 = ioc->spi_data.pIocPg3; pIoc3 = ioc->raid_data.pIocPg3;
for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) { for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
if ( pIoc3->PhysDisk[jj].PhysDiskID == id ) if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
goto next_id; goto next_id;
......
...@@ -189,7 +189,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -189,7 +189,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc); ioc->name, ioc);
return -ENODEV; return 0;
} }
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
......
...@@ -312,7 +312,12 @@ static int ...@@ -312,7 +312,12 @@ static int
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{ {
struct net_device *dev = ioc->netdev; struct net_device *dev = ioc->netdev;
struct mpt_lan_priv *priv = netdev_priv(dev); struct mpt_lan_priv *priv;
if (dev == NULL)
return(1);
else
priv = netdev_priv(dev);
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n", dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
......
...@@ -980,7 +980,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -980,7 +980,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode " "Skipping ioc=%p because SCSI Initiator mode "
"is NOT enabled!\n", ioc->name, ioc); "is NOT enabled!\n", ioc->name, ioc);
return -ENODEV; return 0;
} }
sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST)); sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
......
...@@ -93,8 +93,9 @@ typedef struct _BIG_SENSE_BUF { ...@@ -93,8 +93,9 @@ typedef struct _BIG_SENSE_BUF {
#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */ #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */ #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
...@@ -159,6 +160,8 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR ...@@ -159,6 +160,8 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
static struct work_struct mptscsih_persistTask;
#ifdef MPTSCSIH_ENABLE_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);
...@@ -167,6 +170,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); ...@@ -167,6 +170,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); 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);
static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
#endif #endif
void mptscsih_remove(struct pci_dev *); void mptscsih_remove(struct pci_dev *);
...@@ -606,6 +610,19 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -606,6 +610,19 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
sc->resid = sc->request_bufflen - xfer_cnt; sc->resid = sc->request_bufflen - xfer_cnt;
/*
* if we get a data underrun indication, yet no data was
* transferred and the SCSI status indicates that the
* command was never started, change the data underrun
* to success
*/
if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
(scsi_status == MPI_SCSI_STATUS_BUSY ||
scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
status = MPI_IOCSTATUS_SUCCESS;
}
dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
"resid=%d bufflen=%d xfer_cnt=%d\n", "resid=%d bufflen=%d xfer_cnt=%d\n",
...@@ -619,8 +636,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -619,8 +636,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* /*
* Look for + dump FCP ResponseInfo[]! * Look for + dump FCP ResponseInfo[]!
*/ */
if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) { if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n", pScsiReply->ResponseInfo) {
printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
"FCP_ResponseInfo=%08xh\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
le32_to_cpu(pScsiReply->ResponseInfo)); le32_to_cpu(pScsiReply->ResponseInfo));
} }
...@@ -661,23 +681,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -661,23 +681,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
break; break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
if ( xfer_cnt >= sc->underflow ) { sc->resid = sc->request_bufflen - xfer_cnt;
/* Sufficient data transfer occurred */ if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
sc->result=DID_SOFT_ERROR << 16;
else /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status; sc->result = (DID_OK << 16) | scsi_status;
} else if ( xfer_cnt == 0 ) {
/* A CRC Error causes this condition; retry */
sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
(CHECK_CONDITION << 1);
sc->sense_buffer[0] = 0x70;
sc->sense_buffer[2] = NO_SENSE;
sc->sense_buffer[12] = 0;
sc->sense_buffer[13] = 0;
} else {
sc->result = DID_SOFT_ERROR << 16;
}
dreplyprintk((KERN_NOTICE dreplyprintk((KERN_NOTICE
"RESIDUAL_MISMATCH: result=%x on id=%d\n", "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
sc->result, sc->device->id));
break; break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
...@@ -692,6 +702,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -692,6 +702,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
; ;
} else { } else {
if (xfer_cnt < sc->underflow) { if (xfer_cnt < sc->underflow) {
if (scsi_status == SAM_STAT_BUSY)
sc->result = SAM_STAT_BUSY;
else
sc->result = DID_SOFT_ERROR << 16; sc->result = DID_SOFT_ERROR << 16;
} }
if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) { if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
...@@ -717,7 +730,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -717,7 +730,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
scsi_status = pScsiReply->SCSIStatus; if (scsi_status == MPI_SCSI_STATUS_BUSY)
sc->result = (DID_BUS_BUSY << 16) | scsi_status;
else
sc->result = (DID_OK << 16) | scsi_status; sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state == 0) { if (scsi_state == 0) {
; ;
...@@ -890,12 +905,13 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) ...@@ -890,12 +905,13 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
SCSIIORequest_t *mf = NULL; SCSIIORequest_t *mf = NULL;
int ii; int ii;
int max = hd->ioc->req_depth; int max = hd->ioc->req_depth;
struct scsi_cmnd *sc;
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
target, lun, max)); target, lun, max));
for (ii=0; ii < max; ii++) { for (ii=0; ii < max; ii++) {
if (hd->ScsiLookup[ii] != NULL) { if ((sc = hd->ScsiLookup[ii]) != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
...@@ -910,9 +926,22 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) ...@@ -910,9 +926,22 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
hd->ScsiLookup[ii] = NULL; hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii); mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
if (sc->use_sg) {
pci_unmap_sg(hd->ioc->pcidev,
(struct scatterlist *) sc->request_buffer,
sc->use_sg,
sc->sc_data_direction);
} else if (sc->request_bufflen) {
pci_unmap_single(hd->ioc->pcidev,
sc->SCp.dma_handle,
sc->request_bufflen,
sc->sc_data_direction);
}
sc->host_scribble = NULL;
sc->result = DID_NO_CONNECT << 16;
sc->scsi_done(sc);
} }
} }
return; return;
} }
...@@ -967,8 +996,10 @@ mptscsih_remove(struct pci_dev *pdev) ...@@ -967,8 +996,10 @@ mptscsih_remove(struct pci_dev *pdev)
unsigned long flags; unsigned long flags;
int sz1; int sz1;
if(!host) if(!host) {
mpt_detach(pdev);
return; return;
}
scsi_remove_host(host); scsi_remove_host(host);
...@@ -1422,6 +1453,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1422,6 +1453,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return 0; return 0;
fail: fail:
hd->ScsiLookup[my_idx] = NULL;
mptscsih_freeChainBuffers(hd->ioc, my_idx); mptscsih_freeChainBuffers(hd->ioc, my_idx);
mpt_free_msg_frame(hd->ioc, mf); mpt_free_msg_frame(hd->ioc, mf);
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
...@@ -1709,24 +1741,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1709,24 +1741,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
u32 ctx2abort; u32 ctx2abort;
int scpnt_idx; int scpnt_idx;
int retval;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
SCpnt->result = DID_RESET << 16; SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt); SCpnt->scsi_done(SCpnt);
dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: " dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
"Can't locate host! (sc=%p)\n", "Can't locate host! (sc=%p)\n",
SCpnt)); SCpnt));
return FAILED; return FAILED;
} }
ioc = hd->ioc; ioc = hd->ioc;
if (hd->resetPending) if (hd->resetPending) {
return FAILED; return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
hd->ioc->name, SCpnt);
if (hd->timeouts < -1) if (hd->timeouts < -1)
hd->timeouts++; hd->timeouts++;
...@@ -1738,12 +1769,16 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1738,12 +1769,16 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
* Do OS callback. * Do OS callback.
*/ */
SCpnt->result = DID_RESET << 16; SCpnt->result = DID_RESET << 16;
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
"Command not in the active list! (sc=%p)\n", "Command not in the active list! (sc=%p)\n",
hd->ioc->name, SCpnt)); hd->ioc->name, SCpnt));
return SUCCESS; return SUCCESS;
} }
printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
hd->ioc->name, SCpnt);
scsi_print_command(SCpnt);
/* Most important! Set TaskMsgContext to SCpnt's MsgContext! /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
* (the IO to be ABORT'd) * (the IO to be ABORT'd)
* *
...@@ -1756,38 +1791,22 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1756,38 +1791,22 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
hd->abortSCpnt = SCpnt; hd->abortSCpnt = SCpnt;
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
ctx2abort, 2 /* 2 second timeout */) ctx2abort, 2 /* 2 second timeout */);
< 0) {
/* The TM request failed and the subsequent FW-reload failed! printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
* Fatal error case. hd->ioc->name,
*/ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
hd->ioc->name, SCpnt);
/* We must clear our pending flag before clearing our state. if (retval == 0)
*/ return SUCCESS;
if(retval != FAILED ) {
hd->tmPending = 0; hd->tmPending = 0;
hd->tmState = TM_STATE_NONE; hd->tmState = TM_STATE_NONE;
/* Unmap the DMA buffers, if any. */
if (SCpnt->use_sg) {
pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg, SCpnt->sc_data_direction);
} else if (SCpnt->request_bufflen) {
pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
SCpnt->request_bufflen, SCpnt->sc_data_direction);
} }
hd->ScsiLookup[scpnt_idx] = NULL;
SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt); /* Issue the command callback */
mptscsih_freeChainBuffers(ioc, scpnt_idx);
mpt_free_msg_frame(ioc, mf);
return FAILED; return FAILED;
}
return SUCCESS;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -1803,11 +1822,12 @@ int ...@@ -1803,11 +1822,12 @@ int
mptscsih_dev_reset(struct scsi_cmnd * SCpnt) mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
int retval;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: " dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
"Can't locate host! (sc=%p)\n", "Can't locate host! (sc=%p)\n",
SCpnt)); SCpnt));
return FAILED; return FAILED;
...@@ -1816,24 +1836,26 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) ...@@ -1816,24 +1836,26 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
if (hd->resetPending) if (hd->resetPending)
return FAILED; return FAILED;
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n", printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt);
scsi_print_command(SCpnt);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->channel, SCpnt->device->id,
0, 0, 5 /* 5 second timeout */) 0, 0, 5 /* 5 second timeout */);
< 0){
/* The TM request failed and the subsequent FW-reload failed! printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
* Fatal error case. hd->ioc->name,
*/ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
hd->ioc->name, SCpnt); if (retval == 0)
return SUCCESS;
if(retval != FAILED ) {
hd->tmPending = 0; hd->tmPending = 0;
hd->tmState = TM_STATE_NONE; hd->tmState = TM_STATE_NONE;
return FAILED;
} }
return FAILED;
return SUCCESS;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -1849,41 +1871,39 @@ int ...@@ -1849,41 +1871,39 @@ int
mptscsih_bus_reset(struct scsi_cmnd * SCpnt) mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
spinlock_t *host_lock = SCpnt->device->host->host_lock; int retval;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: " dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
"Can't locate host! (sc=%p)\n", "Can't locate host! (sc=%p)\n",
SCpnt ) ); SCpnt ) );
return FAILED; return FAILED;
} }
printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n", printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt);
scsi_print_command(SCpnt);
if (hd->timeouts < -1) if (hd->timeouts < -1)
hd->timeouts++; hd->timeouts++;
/* We are now ready to execute the task management request. */ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
< 0){
/* The TM request failed and the subsequent FW-reload failed! printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
* Fatal error case. hd->ioc->name,
*/ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
printk(MYIOC_s_WARN_FMT
"Error processing TaskMgmt request (sc=%p)\n", if (retval == 0)
hd->ioc->name, SCpnt); return SUCCESS;
if(retval != FAILED ) {
hd->tmPending = 0; hd->tmPending = 0;
hd->tmState = TM_STATE_NONE; hd->tmState = TM_STATE_NONE;
spin_lock_irq(host_lock);
return FAILED;
} }
return FAILED;
return SUCCESS;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -2165,7 +2185,7 @@ mptscsih_slave_alloc(struct scsi_device *device) ...@@ -2165,7 +2185,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
vdev->raidVolume = 0; vdev->raidVolume = 0;
hd->Targets[device->id] = vdev; hd->Targets[device->id] = vdev;
if (hd->ioc->bus_type == SCSI) { if (hd->ioc->bus_type == SCSI) {
if (hd->ioc->spi_data.isRaid & (1 << device->id)) { if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
vdev->raidVolume = 1; vdev->raidVolume = 1;
ddvtprintk((KERN_INFO ddvtprintk((KERN_INFO
"RAID Volume @ id %d\n", device->id)); "RAID Volume @ id %d\n", device->id));
...@@ -2180,22 +2200,6 @@ mptscsih_slave_alloc(struct scsi_device *device) ...@@ -2180,22 +2200,6 @@ mptscsih_slave_alloc(struct scsi_device *device)
return 0; return 0;
} }
static int
mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
{
int i;
if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
return 0;
for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
return 1;
}
return 0;
}
/* /*
* OS entry point to allow for host driver to free allocated memory * OS entry point to allow for host driver to free allocated memory
* Called if no device present or device being unloaded * Called if no device present or device being unloaded
...@@ -2223,7 +2227,7 @@ mptscsih_slave_destroy(struct scsi_device *device) ...@@ -2223,7 +2227,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
hd->Targets[target] = NULL; hd->Targets[target] = NULL;
if (hd->ioc->bus_type == SCSI) { if (hd->ioc->bus_type == SCSI) {
if (mptscsih_is_raid_volume(hd, target)) { if (mptscsih_is_phys_disk(hd->ioc, target)) {
hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
} else { } else {
hd->ioc->spi_data.dvStatus[target] = hd->ioc->spi_data.dvStatus[target] =
...@@ -2436,6 +2440,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -2436,6 +2440,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
unsigned long flags; unsigned long flags;
int ii;
dtmprintk((KERN_WARNING MYNAM dtmprintk((KERN_WARNING MYNAM
": IOC %s_reset routed to SCSI host driver!\n", ": IOC %s_reset routed to SCSI host driver!\n",
...@@ -2493,11 +2498,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -2493,11 +2498,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* ScsiLookup initialization /* ScsiLookup initialization
*/ */
{
int ii;
for (ii=0; ii < hd->ioc->req_depth; ii++) for (ii=0; ii < hd->ioc->req_depth; ii++)
hd->ScsiLookup[ii] = NULL; hd->ScsiLookup[ii] = NULL;
}
/* 2. Chain Buffer initialization /* 2. Chain Buffer initialization
*/ */
...@@ -2545,6 +2547,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -2545,6 +2547,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
return 1; /* currently means nothing really */ return 1; /* currently means nothing really */
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* work queue thread to clear the persitency table */
static void
mptscsih_sas_persist_clear_table(void * arg)
{
MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int int
mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
...@@ -2555,18 +2567,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -2555,18 +2567,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event)); ioc->name, event));
if (ioc->sh == NULL ||
((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
return 1;
switch (event) { switch (event) {
case MPI_EVENT_UNIT_ATTENTION: /* 03 */ case MPI_EVENT_UNIT_ATTENTION: /* 03 */
/* FIXME! */ /* FIXME! */
break; break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */ case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */ case MPI_EVENT_EXT_BUS_RESET: /* 05 */
hd = NULL;
if (ioc->sh) {
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1)) if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
hd->soft_resets++; hd->soft_resets++;
}
break; break;
case MPI_EVENT_LOGOUT: /* 09 */ case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */ /* FIXME! */
...@@ -2585,69 +2597,24 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -2585,69 +2597,24 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
break; break;
case MPI_EVENT_INTEGRATED_RAID: /* 0B */ case MPI_EVENT_INTEGRATED_RAID: /* 0B */
{
pMpiEventDataRaid_t pRaidEventData =
(pMpiEventDataRaid_t) pEvReply->Data;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* negoNvram set to 0 if DV enabled and to USE_NVRAM if /* Domain Validation Needed */
* if DV disabled. Need to check for target mode. if (ioc->bus_type == SCSI &&
*/ pRaidEventData->ReasonCode ==
hd = NULL; MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
if (ioc->sh) mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; #endif
if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
ScsiCfgData *pSpi;
Ioc3PhysDisk_t *pPDisk;
int numPDisk;
u8 reason;
u8 physDiskNum;
reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
/* New or replaced disk.
* Set DV flag and schedule DV.
*/
pSpi = &ioc->spi_data;
physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
if (pSpi->pIocPg3) {
pPDisk = pSpi->pIocPg3->PhysDisk;
numPDisk =pSpi->pIocPg3->NumPhysDisks;
while (numPDisk) {
if (physDiskNum == pPDisk->PhysDiskNum) {
pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
pSpi->forceDv = MPT_SCSICFG_NEED_DV;
ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
break; break;
} }
pPDisk++;
numPDisk--;
}
if (numPDisk == 0) { /* Persistent table is full. */
/* The physical disk that needs DV was not found case MPI_EVENT_PERSISTENT_TABLE_FULL:
* in the stored IOC Page 3. The driver must reload INIT_WORK(&mptscsih_persistTask,
* this page. DV routine will set the NEED_DV flag for mptscsih_sas_persist_clear_table,(void *)ioc);
* all phys disks that have DV_NOT_DONE set. schedule_work(&mptscsih_persistTask);
*/
pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
}
}
}
}
#endif
#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
printk("Raid Event RF: ");
{
u32 *m = (u32 *)pEvReply;
int ii;
int n = (int)pEvReply->MsgLength;
for (ii=6; ii < n; ii++)
printk(" %08x", le32_to_cpu(m[ii]));
printk("\n");
}
#endif
break; break;
case MPI_EVENT_NONE: /* 00 */ case MPI_EVENT_NONE: /* 00 */
...@@ -2684,7 +2651,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * ...@@ -2684,7 +2651,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
{ {
int indexed_lun, lun_index; int indexed_lun, lun_index;
VirtDevice *vdev; VirtDevice *vdev;
ScsiCfgData *pSpi; SpiCfgData *pSpi;
char data_56; char data_56;
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
...@@ -2791,7 +2758,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * ...@@ -2791,7 +2758,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
static void static void
mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
{ {
ScsiCfgData *pspi_data = &hd->ioc->spi_data; SpiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id; int id = (int) target->target_id;
int nvram; int nvram;
VirtDevice *vdev; VirtDevice *vdev;
...@@ -2970,11 +2937,13 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) ...@@ -2970,11 +2937,13 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
static void static void
mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
{ {
MPT_ADAPTER *ioc = hd->ioc;
u8 cmd; u8 cmd;
ScsiCfgData *pSpi; SpiCfgData *pSpi;
ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", ddvtprintk((MYIOC_s_NOTE_FMT
pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
return; return;
...@@ -2982,12 +2951,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) ...@@ -2982,12 +2951,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
cmd = pReq->CDB[0]; cmd = pReq->CDB[0];
if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
pSpi = &hd->ioc->spi_data; pSpi = &ioc->spi_data;
if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) { if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
/* Set NEED_DV for all hidden disks /* Set NEED_DV for all hidden disks
*/ */
Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk; Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
int numPDisk = pSpi->pIocPg3->NumPhysDisks; int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) { while (numPDisk) {
pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
...@@ -3001,6 +2970,50 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) ...@@ -3001,6 +2970,50 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
} }
} }
/* mptscsih_raid_set_dv_flags()
*
* New or replaced disk. Set DV flag and schedule DV.
*/
static void
mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
{
MPT_ADAPTER *ioc = hd->ioc;
SpiCfgData *pSpi = &ioc->spi_data;
Ioc3PhysDisk_t *pPDisk;
int numPDisk;
if (hd->negoNvram != 0)
return;
ddvtprintk(("DV requested for phys disk id %d\n", id));
if (ioc->raid_data.pIocPg3) {
pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (id == pPDisk->PhysDiskNum) {
pSpi->dvStatus[pPDisk->PhysDiskID] =
(MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
pSpi->forceDv = MPT_SCSICFG_NEED_DV;
ddvtprintk(("NEED_DV set for phys disk id %d\n",
pPDisk->PhysDiskID));
break;
}
pPDisk++;
numPDisk--;
}
if (numPDisk == 0) {
/* The physical disk that needs DV was not found
* in the stored IOC Page 3. The driver must reload
* this page. DV routine will set the NEED_DV flag for
* all phys disks that have DV_NOT_DONE set.
*/
pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
}
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* If no Target, bus reset on 1st I/O. Set the flag to * If no Target, bus reset on 1st I/O. Set the flag to
...@@ -3088,7 +3101,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -3088,7 +3101,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
MPT_ADAPTER *ioc = hd->ioc; MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq; Config_t *pReq;
SCSIDevicePage1_t *pData; SCSIDevicePage1_t *pData;
VirtDevice *pTarget; VirtDevice *pTarget=NULL;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
dma_addr_t dataDma; dma_addr_t dataDma;
u16 req_idx; u16 req_idx;
...@@ -3187,7 +3200,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -3187,7 +3200,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
#endif #endif
if (flags & MPT_SCSICFG_BLK_NEGO) if (flags & MPT_SCSICFG_BLK_NEGO)
negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC; negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
mptscsih_setDevicePage1Flags(width, factor, offset, mptscsih_setDevicePage1Flags(width, factor, offset,
&requested, &configuration, negoFlags); &requested, &configuration, negoFlags);
...@@ -4008,7 +4021,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) ...@@ -4008,7 +4021,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
/* If target Ptr NULL or if this target is NOT a disk, skip. /* If target Ptr NULL or if this target is NOT a disk, skip.
*/ */
if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){ if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
for (lun=0; lun <= MPT_LAST_LUN; lun++) { for (lun=0; lun <= MPT_LAST_LUN; lun++) {
/* If LUN present, issue the command /* If LUN present, issue the command
*/ */
...@@ -4103,9 +4116,9 @@ mptscsih_domainValidation(void *arg) ...@@ -4103,9 +4116,9 @@ mptscsih_domainValidation(void *arg)
if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) { if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
mpt_read_ioc_pg_3(ioc); mpt_read_ioc_pg_3(ioc);
if (ioc->spi_data.pIocPg3) { if (ioc->raid_data.pIocPg3) {
Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk; Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks; int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) { while (numPDisk) {
if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE) if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
...@@ -4144,7 +4157,7 @@ mptscsih_domainValidation(void *arg) ...@@ -4144,7 +4157,7 @@ mptscsih_domainValidation(void *arg)
isPhysDisk = mptscsih_is_phys_disk(ioc, id); isPhysDisk = mptscsih_is_phys_disk(ioc, id);
if (isPhysDisk) { if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
if (hd->ioc->spi_data.isRaid & (1 << ii)) { if (hd->ioc->raid_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING; hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
} }
} }
...@@ -4163,7 +4176,7 @@ mptscsih_domainValidation(void *arg) ...@@ -4163,7 +4176,7 @@ mptscsih_domainValidation(void *arg)
if (isPhysDisk) { if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
if (hd->ioc->spi_data.isRaid & (1 << ii)) { if (hd->ioc->raid_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING; hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
} }
} }
...@@ -4183,23 +4196,23 @@ mptscsih_domainValidation(void *arg) ...@@ -4183,23 +4196,23 @@ mptscsih_domainValidation(void *arg)
return; return;
} }
/* Search IOC page 3 to determine if this is hidden physical disk
*/
/* Search IOC page 3 to determine if this is hidden physical disk /* Search IOC page 3 to determine if this is hidden physical disk
*/ */
static int static int
mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
{ {
if (ioc->spi_data.pIocPg3) { int i;
Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
while (numPDisk) { if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
if (pPDisk->PhysDiskID == id) { return 0;
for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
return 1; return 1;
} }
pPDisk++;
numPDisk--;
}
}
return 0; return 0;
} }
...@@ -4405,7 +4418,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4405,7 +4418,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Skip this ID? Set cfg.cfghdr.hdr to force config page write /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
*/ */
{ {
ScsiCfgData *pspi_data = &hd->ioc->spi_data; SpiCfgData *pspi_data = &hd->ioc->spi_data;
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
/* Set the factor from nvram */ /* Set the factor from nvram */
nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
...@@ -4435,11 +4448,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4435,11 +4448,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
} }
/* Finish iocmd inititialization - hidden or visible disk? */ /* Finish iocmd inititialization - hidden or visible disk? */
if (ioc->spi_data.pIocPg3) { if (ioc->raid_data.pIocPg3) {
/* Search IOC page 3 for matching id /* Search IOC page 3 for matching id
*/ */
Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk; Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks; int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) { while (numPDisk) {
if (pPDisk->PhysDiskID == id) { if (pPDisk->PhysDiskID == id) {
...@@ -4463,7 +4476,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4463,7 +4476,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* RAID Volume ID's may double for a physical device. If RAID but /* RAID Volume ID's may double for a physical device. If RAID but
* not a physical ID as well, skip DV. * not a physical ID as well, skip DV.
*/ */
if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK)) if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
goto target_done; goto target_done;
...@@ -4812,6 +4825,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4812,6 +4825,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
notDone = 0; notDone = 0;
if (iocmd.flags & MPT_ICFLAG_ECHO) { if (iocmd.flags & MPT_ICFLAG_ECHO) {
bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3]; bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
if (pbuf1[0] & 0x01)
iocmd.flags |= MPT_ICFLAG_EBOS;
} else { } else {
bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3]; bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
} }
...@@ -4908,6 +4923,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4908,6 +4923,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
} }
iocmd.flags &= ~MPT_ICFLAG_DID_RESET; iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
if (iocmd.flags & MPT_ICFLAG_EBOS)
goto skip_Reserve;
repeat = 5; repeat = 5;
while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) { while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
iocmd.cmd = RESERVE; iocmd.cmd = RESERVE;
...@@ -4951,6 +4969,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4951,6 +4969,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
} }
} }
skip_Reserve:
mptscsih_fillbuf(pbuf1, sz, patt, 1); mptscsih_fillbuf(pbuf1, sz, patt, 1);
iocmd.cmd = WRITE_BUFFER; iocmd.cmd = WRITE_BUFFER;
iocmd.data_dma = buf1_dma; iocmd.data_dma = buf1_dma;
...@@ -5195,11 +5214,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) ...@@ -5195,11 +5214,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* If not an LVD bus, the adapter minSyncFactor has been * If not an LVD bus, the adapter minSyncFactor has been
* already throttled back. * already throttled back.
*/ */
negoFlags = hd->ioc->spi_data.noQas;
if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
width = pTarget->maxWidth; width = pTarget->maxWidth;
offset = pTarget->maxOffset; offset = pTarget->maxOffset;
factor = pTarget->minSyncFactor; factor = pTarget->minSyncFactor;
negoFlags = pTarget->negoFlags; negoFlags |= pTarget->negoFlags;
} else { } else {
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];
...@@ -5220,7 +5240,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) ...@@ -5220,7 +5240,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
} }
/* Set the negotiation flags */ /* Set the negotiation flags */
negoFlags = hd->ioc->spi_data.noQas;
if (!width) if (!width)
negoFlags |= MPT_TARGET_NO_NEGO_WIDE; negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
......
/* /*
* linux/drivers/message/fusion/mptscsi.h * linux/drivers/message/fusion/mptscsih.h
* High performance SCSI / Fibre Channel SCSI Host device driver. * High performance SCSI / Fibre Channel SCSI Host device driver.
* For use with PCI chip/adapter(s): * For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel * LSIFC9xx/LSI409xx Fibre Channel
...@@ -53,8 +53,8 @@ ...@@ -53,8 +53,8 @@
* SCSI Public stuff... * SCSI Public stuff...
*/ */
#define MPT_SCSI_CMD_PER_DEV_HIGH 31 #define MPT_SCSI_CMD_PER_DEV_HIGH 64
#define MPT_SCSI_CMD_PER_DEV_LOW 7 #define MPT_SCSI_CMD_PER_DEV_LOW 32
#define MPT_SCSI_CMD_PER_LUN 7 #define MPT_SCSI_CMD_PER_LUN 7
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
#define MPTSCSIH_MAX_WIDTH 1 #define MPTSCSIH_MAX_WIDTH 1
#define MPTSCSIH_MIN_SYNC 0x08 #define MPTSCSIH_MIN_SYNC 0x08
#define MPTSCSIH_SAF_TE 0 #define MPTSCSIH_SAF_TE 0
#define MPTSCSIH_PT_CLEAR 0
#endif #endif
...@@ -105,3 +106,4 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE ...@@ -105,3 +106,4 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE
extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
extern void mptscsih_timer_expired(unsigned long data); extern void mptscsih_timer_expired(unsigned long data);
extern void scsi_print_command(struct scsi_cmnd *cmd);
...@@ -199,7 +199,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -199,7 +199,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc); ioc->name, ioc);
return -ENODEV; return 0;
} }
sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST)); sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
......
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