Commit 82ffb671 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[SCSI] fusion core changes for SAS support

 - various bits for SAS support from the LSI driver.
 - use the device private data for the fusion target private data.
   this should be using the midlayer target data framework, but we
   can't move over to that until fusion has been switched to the
   generic DV code
 - use target ID and channel from the fusion target private data,
   because those in scsi_device will be different for mptsas
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 3ed7a470
...@@ -141,7 +141,7 @@ static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); ...@@ -141,7 +141,7 @@ 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);
static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag); static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
...@@ -152,6 +152,7 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); ...@@ -152,6 +152,7 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int GetLanConfigPages(MPT_ADAPTER *ioc); static int GetLanConfigPages(MPT_ADAPTER *ioc);
static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
static int GetIoUnitPage2(MPT_ADAPTER *ioc); static int GetIoUnitPage2(MPT_ADAPTER *ioc);
int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
...@@ -159,6 +160,8 @@ static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); ...@@ -159,6 +160,8 @@ static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
static void mpt_timer_expired(unsigned long data); static void mpt_timer_expired(unsigned long data);
static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static int procmpt_summary_read(char *buf, char **start, off_t offset, static int procmpt_summary_read(char *buf, char **start, off_t offset,
...@@ -509,6 +512,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) ...@@ -509,6 +512,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
pCfg->wait_done = 1; pCfg->wait_done = 1;
wake_up(&mpt_waitq); wake_up(&mpt_waitq);
} }
} else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
/* we should be always getting a reply frame */
memcpy(ioc->persist_reply_frame, reply,
min(MPT_DEFAULT_FRAME_SIZE,
4*reply->u.reply.MsgLength));
del_timer(&ioc->persist_timer);
ioc->persist_wait_done = 1;
wake_up(&mpt_waitq);
} else { } else {
printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n", printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
ioc->name, func); ioc->name, func);
...@@ -750,6 +761,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc) ...@@ -750,6 +761,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR, mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
u.frame.linkage.list); u.frame.linkage.list);
list_del(&mf->u.frame.linkage.list); list_del(&mf->u.frame.linkage.list);
mf->u.frame.linkage.arg1 = 0;
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */ mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
req_offset = (u8 *)mf - (u8 *)ioc->req_frames; req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
/* u16! */ /* u16! */
...@@ -845,6 +857,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) ...@@ -845,6 +857,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
/* Put Request back on FreeQ! */ /* Put Request back on FreeQ! */
spin_lock_irqsave(&ioc->FreeQlock, flags); spin_lock_irqsave(&ioc->FreeQlock, flags);
mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
#ifdef MFCNT #ifdef MFCNT
ioc->mfcnt--; ioc->mfcnt--;
...@@ -971,10 +984,121 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, ...@@ -971,10 +984,121 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
/* Make sure there are no doorbells */ /* Make sure there are no doorbells */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
return r; return r;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_host_page_access_control - provides mechanism for the host
* driver to control the IOC's Host Page Buffer access.
* @ioc: Pointer to MPT adapter structure
* @access_control_value: define bits below
*
* Access Control Value - bits[15:12]
* 0h Reserved
* 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
* 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
* 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
*
* Returns 0 for success, non-zero for failure.
*/
static int
mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
{
int r = 0;
/* return if in use */
if (CHIPREG_READ32(&ioc->chip->Doorbell)
& MPI_DOORBELL_ACTIVE)
return -1;
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
CHIPREG_WRITE32(&ioc->chip->Doorbell,
((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
<<MPI_DOORBELL_FUNCTION_SHIFT) |
(access_control_value<<12)));
/* Wait for IOC to clear Doorbell Status bit */
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
return -2;
}else
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_host_page_alloc - allocate system memory for the fw
* If we already allocated memory in past, then resend the same pointer.
* ioc@: Pointer to pointer to IOC adapter
* ioc_init@: Pointer to ioc init config page
*
* Returns 0 for success, non-zero for failure.
*/
static int
mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
{
char *psge;
int flags_length;
u32 host_page_buffer_sz=0;
if(!ioc->HostPageBuffer) {
host_page_buffer_sz =
le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
if(!host_page_buffer_sz)
return 0; /* fw doesn't need any host buffers */
/* spin till we get enough memory */
while(host_page_buffer_sz > 0) {
if((ioc->HostPageBuffer = pci_alloc_consistent(
ioc->pcidev,
host_page_buffer_sz,
&ioc->HostPageBuffer_dma)) != NULL) {
dinitprintk((MYIOC_s_INFO_FMT
"host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
ioc->name,
ioc->HostPageBuffer,
ioc->HostPageBuffer_dma,
hst_page_buffer_sz));
ioc->alloc_total += host_page_buffer_sz;
ioc->HostPageBuffer_sz = host_page_buffer_sz;
break;
}
host_page_buffer_sz -= (4*1024);
}
}
if(!ioc->HostPageBuffer) {
printk(MYIOC_s_ERR_FMT
"Failed to alloc memory for host_page_buffer!\n",
ioc->name);
return -999;
}
psge = (char *)&ioc_init->HostPageBufferSGE;
flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_SYSTEM_ADDRESS |
MPI_SGE_FLAGS_32_BIT_ADDRESSING |
MPI_SGE_FLAGS_HOST_TO_IOC |
MPI_SGE_FLAGS_END_OF_BUFFER;
if (sizeof(dma_addr_t) == sizeof(u64)) {
flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
}
flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
flags_length |= ioc->HostPageBuffer_sz;
mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mpt_verify_adapter - Given a unique IOC identifier, set pointer to * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
...@@ -1213,6 +1337,33 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1213,6 +1337,33 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->prod_name = "LSI53C1035"; ioc->prod_name = "LSI53C1035";
ioc->bus_type = SCSI; ioc->bus_type = SCSI;
} }
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
ioc->prod_name = "LSISAS1064";
ioc->bus_type = SAS;
ioc->errata_flag_1064 = 1;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
ioc->prod_name = "LSISAS1066";
ioc->bus_type = SAS;
ioc->errata_flag_1064 = 1;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
ioc->prod_name = "LSISAS1068";
ioc->bus_type = SAS;
ioc->errata_flag_1064 = 1;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
ioc->prod_name = "LSISAS1064E";
ioc->bus_type = SAS;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
ioc->prod_name = "LSISAS1066E";
ioc->bus_type = SAS;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
ioc->prod_name = "LSISAS1068E";
ioc->bus_type = SAS;
}
if (ioc->errata_flag_1064) if (ioc->errata_flag_1064)
pci_disable_io_access(pdev); pci_disable_io_access(pdev);
...@@ -1640,7 +1791,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1640,7 +1791,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* and we try GetLanConfigPages again... * and we try GetLanConfigPages again...
*/ */
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
if (ioc->bus_type == FC) { if (ioc->bus_type == SAS) {
/* clear persistency table */
if(ioc->facts.IOCExceptions &
MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
ret = mptbase_sas_persist_operation(ioc,
MPI_SAS_OP_CLEAR_NOT_PRESENT);
if(ret != 0)
return -1;
}
/* Find IM volumes
*/
mpt_findImVolumes(ioc);
} else if (ioc->bus_type == FC) {
/* /*
* Pre-fetch FC port WWN and stuff... * Pre-fetch FC port WWN and stuff...
* (FCPortPage0_t stuff) * (FCPortPage0_t stuff)
...@@ -1783,7 +1949,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) ...@@ -1783,7 +1949,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
if (ioc->cached_fw != NULL) { if (ioc->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n")); ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) { if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
printk(KERN_WARNING MYNAM printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", ret); ": firmware downloadboot failure (%d)!\n", ret);
} }
...@@ -1852,6 +2018,23 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) ...@@ -1852,6 +2018,23 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
kfree(ioc->ChainToChain); kfree(ioc->ChainToChain);
ioc->ChainToChain = NULL; ioc->ChainToChain = NULL;
if (ioc->HostPageBuffer != NULL) {
if((ret = mpt_host_page_access_control(ioc,
MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
printk(KERN_ERR MYNAM
": %s: host page buffers free failed (%d)!\n",
__FUNCTION__, ret);
}
dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
ioc->HostPageBuffer,
ioc->HostPageBuffer_dma);
ioc->HostPageBuffer = NULL;
ioc->HostPageBuffer_sz = 0;
ioc->alloc_total -= ioc->HostPageBuffer_sz;
}
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -2034,7 +2217,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) ...@@ -2034,7 +2217,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Loop here waiting for IOC to come READY. * Loop here waiting for IOC to come READY.
*/ */
ii = 0; ii = 0;
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */ cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
if (ioc_state == MPI_IOC_STATE_OPERATIONAL) { if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
...@@ -2212,6 +2395,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) ...@@ -2212,6 +2395,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
le32_to_cpu(facts->CurrentSenseBufferHighAddr); le32_to_cpu(facts->CurrentSenseBufferHighAddr);
facts->CurReplyFrameSize = facts->CurReplyFrameSize =
le16_to_cpu(facts->CurReplyFrameSize); le16_to_cpu(facts->CurReplyFrameSize);
facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
/* /*
* Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
...@@ -2383,13 +2567,25 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2383,13 +2567,25 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
ioc->name, ioc->upload_fw, ioc->facts.Flags)); ioc->name, ioc->upload_fw, ioc->facts.Flags));
if (ioc->bus_type == FC) if(ioc->bus_type == SAS)
ioc_init.MaxDevices = ioc->facts.MaxDevices;
else if(ioc->bus_type == FC)
ioc_init.MaxDevices = MPT_MAX_FC_DEVICES; ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
else else
ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES; ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
ioc_init.MaxBuses = MPT_MAX_BUS; ioc_init.MaxBuses = MPT_MAX_BUS;
dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
ioc->name, ioc->facts.MsgVersion));
if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
// set MsgVersion and HeaderVersion host driver was built with
ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
} else if(mpt_host_page_alloc(ioc, &ioc_init))
return -99;
}
ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
if (sizeof(dma_addr_t) == sizeof(u64)) { if (sizeof(dma_addr_t) == sizeof(u64)) {
...@@ -2403,17 +2599,21 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2403,17 +2599,21 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ioc_init.HostMfaHighAddr = cpu_to_le32(0); ioc_init.HostMfaHighAddr = cpu_to_le32(0);
ioc_init.SenseBufferHighAddr = cpu_to_le32(0); ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
} }
ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
ioc->facts.MaxDevices = ioc_init.MaxDevices;
ioc->facts.MaxBuses = ioc_init.MaxBuses;
dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n", dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
ioc->name, &ioc_init)); ioc->name, &ioc_init));
r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init, r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag); sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
if (r != 0) if (r != 0) {
printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
return r; return r;
}
/* No need to byte swap the multibyte fields in the reply /* No need to byte swap the multibyte fields in the reply
* since we don't even look at it's contents. * since we don't even look at it's contents.
...@@ -2472,7 +2672,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) ...@@ -2472,7 +2672,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
{ {
PortEnable_t port_enable; PortEnable_t port_enable;
MPIDefaultReply_t reply_buf; MPIDefaultReply_t reply_buf;
int ii; int rc;
int req_sz; int req_sz;
int reply_sz; int reply_sz;
...@@ -2494,22 +2694,15 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) ...@@ -2494,22 +2694,15 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
/* RAID FW may take a long time to enable /* RAID FW may take a long time to enable
*/ */
if (ioc->bus_type == FC) { if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag); rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
} else {
ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
} else {
rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
} }
return rc;
if (ii != 0)
return ii;
/* We do not even look at the reply, so we need not
* swap the multi-byte fields.
*/
return 0;
} }
/* /*
...@@ -2666,9 +2859,8 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2666,9 +2859,8 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
* <0 for fw upload failure. * <0 for fw upload failure.
*/ */
static int static int
mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
{ {
MpiFwHeader_t *pFwHeader;
MpiExtImageHeader_t *pExtImage; MpiExtImageHeader_t *pExtImage;
u32 fwSize; u32 fwSize;
u32 diag0val; u32 diag0val;
...@@ -2679,18 +2871,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2679,18 +2871,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
u32 load_addr; u32 load_addr;
u32 ioc_state=0; u32 ioc_state=0;
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
ioc->name, ioc->facts.FWImageSize, ioc->cached_fw)); ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
if ( ioc->facts.FWImageSize == 0 )
return -1;
if (ioc->cached_fw == NULL)
return -2;
/* prevent a second downloadboot and memory free with alt_ioc */
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
ioc->alt_ioc->cached_fw = NULL;
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
...@@ -2718,16 +2900,17 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2718,16 +2900,17 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
ioc->name, count)); ioc->name, count));
break; break;
} }
/* wait 1 sec */ /* wait .1 sec */
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
msleep_interruptible (1000); msleep_interruptible (100);
} else { } else {
mdelay (1000); mdelay (100);
} }
} }
if ( count == 30 ) { if ( count == 30 ) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
"Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
ioc->name, diag0val)); ioc->name, diag0val));
return -3; return -3;
} }
...@@ -2742,7 +2925,6 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2742,7 +2925,6 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Set the DiagRwEn and Disable ARM bits */ /* Set the DiagRwEn and Disable ARM bits */
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)); CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
fwSize = (pFwHeader->ImageSize + 3)/4; fwSize = (pFwHeader->ImageSize + 3)/4;
ptrFw = (u32 *) pFwHeader; ptrFw = (u32 *) pFwHeader;
...@@ -2792,19 +2974,38 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2792,19 +2974,38 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Clear the internal flash bad bit - autoincrementing register, /* Clear the internal flash bad bit - autoincrementing register,
* so must do two writes. * so must do two writes.
*/ */
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); if (ioc->bus_type == SCSI) {
diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData); /*
diagRwData |= 0x4000000; * 1030 and 1035 H/W errata, workaround to access
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); * the ClearFlashBadSignatureBit
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData); */
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
diagRwData |= 0x40000000;
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
} else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
MPI_DIAG_CLEAR_FLASH_BAD_SIG);
/* wait 1 msec */
if (sleepFlag == CAN_SLEEP) {
msleep_interruptible (1);
} else {
mdelay (1);
}
}
if (ioc->errata_flag_1064) if (ioc->errata_flag_1064)
pci_disable_io_access(ioc->pcidev); pci_disable_io_access(ioc->pcidev);
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
ioc->name, diag0val)); ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM); diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val)); ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
...@@ -2812,10 +3013,23 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2812,10 +3013,23 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Write 0xFF to reset the sequencer */ /* Write 0xFF to reset the sequencer */
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
if (ioc->bus_type == SAS) {
ioc_state = mpt_GetIocState(ioc, 0);
if ( (GetIocFacts(ioc, sleepFlag,
MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
ioc->name, ioc_state));
return -EFAULT;
}
}
for (count=0; count<HZ*20; count++) { for (count=0; count<HZ*20; count++) {
if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) { if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
ioc->name, count, ioc_state)); ioc->name, count, ioc_state));
if (ioc->bus_type == SAS) {
return 0;
}
if ((SendIocInit(ioc, sleepFlag)) != 0) { if ((SendIocInit(ioc, sleepFlag)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
ioc->name)); ioc->name));
...@@ -3049,12 +3263,13 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) ...@@ -3049,12 +3263,13 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* wait 1 sec */ /* wait 1 sec */
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
ssleep(1); msleep_interruptible (1000);
} else { } else {
mdelay (1000); mdelay (1000);
} }
} }
if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) { if ((count = mpt_downloadboot(ioc,
(MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count); ": firmware downloadboot failure (%d)!\n", count);
} }
...@@ -3999,6 +4214,85 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) ...@@ -3999,6 +4214,85 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
return rc; return rc;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
* @ioc: Pointer to MPT_ADAPTER structure
* @sas_address: 64bit SAS Address for operation.
* @target_id: specified target for operation
* @bus: specified bus for operation
* @persist_opcode: see below
*
* MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
* devices not currently present.
* MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
*
* NOTE: Don't use not this function during interrupt time.
*
* Returns: 0 for success, non-zero error
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int
mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
{
SasIoUnitControlRequest_t *sasIoUnitCntrReq;
SasIoUnitControlReply_t *sasIoUnitCntrReply;
MPT_FRAME_HDR *mf = NULL;
MPIHeader_t *mpi_hdr;
/* insure garbage is not sent to fw */
switch(persist_opcode) {
case MPI_SAS_OP_CLEAR_NOT_PRESENT:
case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
break;
default:
return -1;
break;
}
printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
/* Get a MF for this command.
*/
if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
printk("%s: no msg frames!\n",__FUNCTION__);
return -1;
}
mpi_hdr = (MPIHeader_t *) mf;
sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
sasIoUnitCntrReq->Operation = persist_opcode;
init_timer(&ioc->persist_timer);
ioc->persist_timer.data = (unsigned long) ioc;
ioc->persist_timer.function = mpt_timer_expired;
ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
ioc->persist_wait_done=0;
add_timer(&ioc->persist_timer);
mpt_put_msg_frame(mpt_base_index, ioc, mf);
wait_event(mpt_waitq, ioc->persist_wait_done);
sasIoUnitCntrReply =
(SasIoUnitControlReply_t *)ioc->persist_reply_frame;
if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
__FUNCTION__,
sasIoUnitCntrReply->IOCStatus,
sasIoUnitCntrReply->IOCLogInfo);
return -1;
}
printk("%s: success\n",__FUNCTION__);
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* GetIoUnitPage2 - Retrieve BIOS version and boot order information. * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
...@@ -5366,8 +5660,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -5366,8 +5660,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static char * static void
EventDescriptionStr(u8 event, u32 evData0) EventDescriptionStr(u8 event, u32 evData0, char *evStr)
{ {
char *ds; char *ds;
...@@ -5420,8 +5714,95 @@ EventDescriptionStr(u8 event, u32 evData0) ...@@ -5420,8 +5714,95 @@ EventDescriptionStr(u8 event, u32 evData0)
ds = "Events(OFF) Change"; ds = "Events(OFF) Change";
break; break;
case MPI_EVENT_INTEGRATED_RAID: case MPI_EVENT_INTEGRATED_RAID:
ds = "Integrated Raid"; {
u8 ReasonCode = (u8)(evData0 >> 16);
switch (ReasonCode) {
case MPI_EVENT_RAID_RC_VOLUME_CREATED :
ds = "Integrated Raid: Volume Created";
break;
case MPI_EVENT_RAID_RC_VOLUME_DELETED :
ds = "Integrated Raid: Volume Deleted";
break;
case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
ds = "Integrated Raid: Volume Settings Changed";
break;
case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
ds = "Integrated Raid: Volume Status Changed";
break;
case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
ds = "Integrated Raid: Volume Physdisk Changed";
break;
case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
ds = "Integrated Raid: Physdisk Created";
break;
case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
ds = "Integrated Raid: Physdisk Deleted";
break;
case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
ds = "Integrated Raid: Physdisk Settings Changed";
break;
case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
ds = "Integrated Raid: Physdisk Status Changed";
break;
case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
ds = "Integrated Raid: Domain Validation Needed";
break;
case MPI_EVENT_RAID_RC_SMART_DATA :
ds = "Integrated Raid; Smart Data";
break;
case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
ds = "Integrated Raid: Replace Action Started";
break;
default:
ds = "Integrated Raid";
break; break;
}
break;
}
case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
ds = "SCSI Device Status Change";
break;
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
{
u8 ReasonCode = (u8)(evData0 >> 16);
switch (ReasonCode) {
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
ds = "SAS Device Status Change: Added";
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
ds = "SAS Device Status Change: Deleted";
break;
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
ds = "SAS Device Status Change: SMART Data";
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
ds = "SAS Device Status Change: No Persistancy Added";
break;
default:
ds = "SAS Device Status Change: Unknown";
break;
}
break;
}
case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
ds = "Bus Timer Expired";
break;
case MPI_EVENT_QUEUE_FULL:
ds = "Queue Full";
break;
case MPI_EVENT_SAS_SES:
ds = "SAS SES Event";
break;
case MPI_EVENT_PERSISTENT_TABLE_FULL:
ds = "Persistent Table Full";
break;
case MPI_EVENT_SAS_PHY_LINK_STATUS:
ds = "SAS PHY Link Status";
break;
case MPI_EVENT_SAS_DISCOVERY_ERROR:
ds = "SAS Discovery Error";
break;
/* /*
* MPT base "custom" events may be added here... * MPT base "custom" events may be added here...
*/ */
...@@ -5429,7 +5810,7 @@ EventDescriptionStr(u8 event, u32 evData0) ...@@ -5429,7 +5810,7 @@ EventDescriptionStr(u8 event, u32 evData0)
ds = "Unknown"; ds = "Unknown";
break; break;
} }
return ds; strcpy(evStr,ds);
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -5451,7 +5832,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply ...@@ -5451,7 +5832,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
int ii; int ii;
int r = 0; int r = 0;
int handlers = 0; int handlers = 0;
char *evStr; char evStr[100];
u8 event; u8 event;
/* /*
...@@ -5464,7 +5845,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply ...@@ -5464,7 +5845,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
evData0 = le32_to_cpu(pEventReply->Data[0]); evData0 = le32_to_cpu(pEventReply->Data[0]);
} }
evStr = EventDescriptionStr(event, evData0); EventDescriptionStr(event, evData0, evStr);
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n", devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
ioc->name, ioc->name,
evStr, evStr,
...@@ -5481,20 +5862,6 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply ...@@ -5481,20 +5862,6 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* Do general / base driver event processing * Do general / base driver event processing
*/ */
switch(event) { switch(event) {
case MPI_EVENT_NONE: /* 00 */
case MPI_EVENT_LOG_DATA: /* 01 */
case MPI_EVENT_STATE_CHANGE: /* 02 */
case MPI_EVENT_UNIT_ATTENTION: /* 03 */
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
case MPI_EVENT_RESCAN: /* 06 */
case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
case MPI_EVENT_LOGOUT: /* 09 */
case MPI_EVENT_INTEGRATED_RAID: /* 0B */
case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
default:
break;
case MPI_EVENT_EVENT_CHANGE: /* 0A */ case MPI_EVENT_EVENT_CHANGE: /* 0A */
if (evDataLen) { if (evDataLen) {
u8 evState = evData0 & 0xFF; u8 evState = evData0 & 0xFF;
...@@ -5507,6 +5874,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply ...@@ -5507,6 +5874,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
} }
} }
break; break;
default:
break;
} }
/* /*
...@@ -5814,6 +6183,7 @@ EXPORT_SYMBOL(mpt_findImVolumes); ...@@ -5814,6 +6183,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_read_ioc_pg_3); EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory); EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory); EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */ #include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */ #include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
#include "lsi/mpi_tool.h" /* Tools support */ #include "lsi/mpi_tool.h" /* Tools support */
#include "lsi/mpi_sas.h" /* SAS support */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -477,6 +478,14 @@ typedef struct _ScsiCfgData { ...@@ -477,6 +478,14 @@ typedef struct _ScsiCfgData {
u8 rsvd[1]; u8 rsvd[1];
} ScsiCfgData; } ScsiCfgData;
typedef struct _SasCfgData {
u8 ptClear; /* 1 to automatically clear the
* persistent table.
* 0 to disable
* automatic clearing.
*/
}SasCfgData;
/* /*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
*/ */
...@@ -530,11 +539,15 @@ typedef struct _MPT_ADAPTER ...@@ -530,11 +539,15 @@ typedef struct _MPT_ADAPTER
u8 *sense_buf_pool; u8 *sense_buf_pool;
dma_addr_t sense_buf_pool_dma; dma_addr_t sense_buf_pool_dma;
u32 sense_buf_low_dma; u32 sense_buf_low_dma;
u8 *HostPageBuffer; /* SAS - host page buffer support */
u32 HostPageBuffer_sz;
dma_addr_t HostPageBuffer_dma;
int mtrr_reg; int mtrr_reg;
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 */ ScsiCfgData spi_data; /* Scsi 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;
struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
...@@ -554,31 +567,35 @@ typedef struct _MPT_ADAPTER ...@@ -554,31 +567,35 @@ typedef struct _MPT_ADAPTER
#else #else
u32 mfcnt; u32 mfcnt;
#endif #endif
u32 NB_for_64_byte_frame; u32 NB_for_64_byte_frame;
u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)]; u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)]; u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
IOCFactsReply_t facts; IOCFactsReply_t facts;
PortFactsReply_t pfacts[2]; PortFactsReply_t pfacts[2];
FCPortPage0_t fc_port_page0[2]; FCPortPage0_t fc_port_page0[2];
struct timer_list persist_timer; /* persist table timer */
int persist_wait_done; /* persist completion flag */
u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
LANPage0_t lan_cnfg_page0; LANPage0_t lan_cnfg_page0;
LANPage1_t lan_cnfg_page1; LANPage1_t lan_cnfg_page1;
/* /*
* Description: errata_flag_1064 * Description: errata_flag_1064
* If a PCIX read occurs within 1 or 2 cycles after the chip receives * If a PCIX read occurs within 1 or 2 cycles after the chip receives
* a split completion for a read data, an internal address pointer incorrectly * a split completion for a read data, an internal address pointer incorrectly
* increments by 32 bytes * increments by 32 bytes
*/ */
int errata_flag_1064; int errata_flag_1064;
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 */
u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */ u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
u8 pad1[4]; u8 pad1[4];
int DoneCtx; int DoneCtx;
int TaskCtx; int TaskCtx;
int InternalCtx; int InternalCtx;
struct list_head list; struct list_head list;
struct net_device *netdev; struct net_device *netdev;
struct list_head sas_topology;
} MPT_ADAPTER; } MPT_ADAPTER;
/* /*
...@@ -964,6 +981,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); ...@@ -964,6 +981,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
/* /*
* Public data decl's... * Public data decl's...
......
...@@ -1256,8 +1256,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1256,8 +1256,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq; SCSIIORequest_t *pScsiReq;
VirtDevice *pTarget; VirtDevice *pTarget = SCpnt->device->hostdata;
int target;
int lun; int lun;
u32 datalen; u32 datalen;
u32 scsictl; u32 scsictl;
...@@ -1267,12 +1266,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1267,12 +1266,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
int ii; int ii;
hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
target = SCpnt->device->id;
lun = SCpnt->device->lun; lun = SCpnt->device->lun;
SCpnt->scsi_done = done; SCpnt->scsi_done = done;
pTarget = hd->Targets[target];
dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n", dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done)); (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
...@@ -1315,7 +1311,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1315,7 +1311,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated, /* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged. * use the Inquiry data to determine if device supports tagged.
*/ */
if ( pTarget if (pTarget
&& (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) { && (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
...@@ -1325,8 +1321,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1325,8 +1321,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame /* Use the above information to set up the message frame
*/ */
pScsiReq->TargetID = (u8) target; pScsiReq->TargetID = (u8) pTarget->target_id;
pScsiReq->Bus = (u8) SCpnt->device->channel; pScsiReq->Bus = pTarget->bus_id;
pScsiReq->ChainOffset = 0; pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len; pScsiReq->CDBLength = SCpnt->cmd_len;
...@@ -1378,7 +1374,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1378,7 +1374,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if (hd->ioc->bus_type == SCSI) { if (hd->ioc->bus_type == SCSI) {
int dvStatus = hd->ioc->spi_data.dvStatus[target]; int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
int issueCmd = 1; int issueCmd = 1;
if (dvStatus || hd->ioc->spi_data.forceDv) { if (dvStatus || hd->ioc->spi_data.forceDv) {
...@@ -2180,6 +2176,7 @@ mptscsih_slave_alloc(struct scsi_device *device) ...@@ -2180,6 +2176,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
out: out:
vdev->num_luns++; vdev->num_luns++;
device->hostdata = vdev;
return 0; return 0;
} }
......
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