Commit c4fb4b17 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[PATCH] MPT Fusion driver 3.01.09 update

On Mon, Jun 21, 2004 at 12:16:08PM -0400, Moore, Eric Dean wrote:
> We are pleased to announce the MPT Fusion release candidate for lk 2.6

I've worked with Eric offline to resolve the issue we had and get some
more changes in, but he has left for his vacation today.  He send me
a patch though and left it to me whether we'd merged it despite only
moderate testing.  Given 2.6.7 was just done and he'll certainly be
back before 2.6.8 I'd go for it.  Below is the patch rediffed against
scsi-misc-2.6:
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent d010bb10
...@@ -3,6 +3,16 @@ ...@@ -3,6 +3,16 @@
#ifndef FUSION_LINUX_COMPAT_H #ifndef FUSION_LINUX_COMPAT_H
#define FUSION_LINUX_COMPAT_H #define FUSION_LINUX_COMPAT_H
#include <linux/version.h>
#include <scsi/scsi_device.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6))
static int inline scsi_device_online(struct scsi_device *sdev)
{
return sdev->online;
}
#endif
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* _LINUX_COMPAT_H */ #endif /* _LINUX_COMPAT_H */
...@@ -150,9 +150,8 @@ int mpt_ASCQ_TableSz; ...@@ -150,9 +150,8 @@ int mpt_ASCQ_TableSz;
/* /*
* Private data... * Private data...
*/ */
/* Adapter lookup table */ /* Adapter link list */
MPT_ADAPTER *mpt_adapters[MPT_MAX_ADAPTERS]; LIST_HEAD(ioc_list);
static MPT_ADAPTER_TRACKER MptAdapters;
/* Callback lookup table */ /* Callback lookup table */
static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS]; static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
/* Protocol driver class lookup table */ /* Protocol driver class lookup table */
...@@ -210,8 +209,6 @@ static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); ...@@ -210,8 +209,6 @@ 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);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static int procmpt_create(void);
static int procmpt_destroy(void);
static int procmpt_summary_read(char *buf, char **start, off_t offset, static int procmpt_summary_read(char *buf, char **start, off_t offset,
int request, int *eof, void *data); int request, int *eof, void *data);
static int procmpt_version_read(char *buf, char **start, off_t offset, static int procmpt_version_read(char *buf, char **start, off_t offset,
...@@ -234,31 +231,6 @@ static void mptbase_shutdown(struct device * ); ...@@ -234,31 +231,6 @@ static void mptbase_shutdown(struct device * );
static int __init fusion_init (void); static int __init fusion_init (void);
static void __exit fusion_exit (void); static void __exit fusion_exit (void);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* more Private data...
*/
#ifdef CONFIG_PROC_FS
struct _mpt_proc_list {
const char *name;
int (*f)(char *, char **, off_t, int, int *, void *);
} mpt_proc_list[] = {
{ "summary", procmpt_summary_read},
{ "version", procmpt_version_read},
};
#define MPT_PROC_ENTRIES (sizeof(mpt_proc_list)/sizeof(mpt_proc_list[0]))
struct _mpt_ioc_proc_list {
const char *name;
int (*f)(char *, char **, off_t, int, int *, void *);
} mpt_ioc_proc_list[] = {
{ "info", procmpt_iocinfo_read},
{ "summary", procmpt_summary_read},
};
#define MPT_IOC_PROC_ENTRIES (sizeof(mpt_ioc_proc_list)/sizeof(mpt_ioc_proc_list[0]))
#endif
/**************************************************************************** /****************************************************************************
* Supported hardware * Supported hardware
*/ */
...@@ -282,7 +254,8 @@ static struct pci_device_id mptbase_pci_table[] = { ...@@ -282,7 +254,8 @@ static struct pci_device_id mptbase_pci_table[] = {
}; };
MODULE_DEVICE_TABLE(pci, mptbase_pci_table); MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
#define CHIPREG_READ32(addr) readl(addr) #define CHIPREG_READ32(addr) readl_relaxed(addr)
#define CHIPREG_READ32_dmasync(addr) readl(addr)
#define CHIPREG_WRITE32(addr,val) writel(val, addr) #define CHIPREG_WRITE32(addr,val) writel(val, addr)
#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr) #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr) #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
...@@ -320,23 +293,6 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) ...@@ -320,23 +293,6 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
ioc = bus_id; ioc = bus_id;
#ifdef MPT_DEBUG_IRQ
/*
* Verify ioc pointer is ok
*/
{
MPT_ADAPTER *iocCmp;
iocCmp = mpt_adapter_find_first();
while ((ioc != iocCmp) && iocCmp)
iocCmp = mpt_adapter_find_next(iocCmp);
if (!iocCmp) {
printk(KERN_WARNING "mpt_interrupt: Invalid ioc!\n");
return IRQ_NONE;
}
}
#endif
/* /*
* Drain the reply FIFO! * Drain the reply FIFO!
* *
...@@ -347,7 +303,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) ...@@ -347,7 +303,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
*/ */
while (1) { while (1) {
if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF) if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
return IRQ_HANDLED; return IRQ_HANDLED;
cb_idx = 0; cb_idx = 0;
...@@ -806,8 +762,7 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) ...@@ -806,8 +762,7 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
/* call per pci device probe entry point */ /* call per pci device probe entry point */
for(ioc = mpt_adapter_find_first(); ioc != NULL; list_for_each_entry(ioc, &ioc_list, list) {
ioc = mpt_adapter_find_next(ioc)) {
if(dd_cbfunc->probe) { if(dd_cbfunc->probe) {
error = dd_cbfunc->probe(ioc->pcidev, error = dd_cbfunc->probe(ioc->pcidev,
ioc->pcidev->driver->id_table); ioc->pcidev->driver->id_table);
...@@ -826,9 +781,19 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) ...@@ -826,9 +781,19 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
void void
mpt_device_driver_deregister(int cb_idx) mpt_device_driver_deregister(int cb_idx)
{ {
struct mpt_pci_driver *dd_cbfunc;
MPT_ADAPTER *ioc;
if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
return; return;
dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
list_for_each_entry(ioc, &ioc_list, list) {
if (dd_cbfunc->remove)
dd_cbfunc->remove(ioc->pcidev);
}
MptDeviceDriverHandlers[cb_idx] = NULL; MptDeviceDriverHandlers[cb_idx] = NULL;
} }
...@@ -844,15 +809,11 @@ mpt_device_driver_deregister(int cb_idx) ...@@ -844,15 +809,11 @@ mpt_device_driver_deregister(int cb_idx)
* or IOC is not active. * or IOC is not active.
*/ */
MPT_FRAME_HDR* MPT_FRAME_HDR*
mpt_get_msg_frame(int handle, int iocid) mpt_get_msg_frame(int handle, MPT_ADAPTER *iocp)
{ {
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
MPT_ADAPTER *iocp;
unsigned long flags; unsigned long flags;
/* validate handle and ioc identifier */
iocp = mpt_adapters[iocid];
#ifdef MFCNT #ifdef MFCNT
if (!iocp->active) if (!iocp->active)
printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n"); printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
...@@ -907,48 +868,39 @@ mpt_get_msg_frame(int handle, int iocid) ...@@ -907,48 +868,39 @@ mpt_get_msg_frame(int handle, int iocid)
* specific MPT adapter. * specific MPT adapter.
*/ */
void void
mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf) mpt_put_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
{ {
MPT_ADAPTER *iocp; u32 mf_dma_addr;
int req_offset;
iocp = mpt_adapters[iocid];
if (iocp != NULL) {
u32 mf_dma_addr;
int req_offset;
/* ensure values are reset properly! */ /* ensure values are reset properly! */
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 *)iocp->req_frames; req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
/* u16! */ /* u16! */
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_offset / iocp->req_sz); mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_offset / iocp->req_sz);
mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
#ifdef MPT_DEBUG_MSG_FRAME #ifdef MPT_DEBUG_MSG_FRAME
{ {
u32 *m = mf->u.frame.hwhdr.__hdr; u32 *m = mf->u.frame.hwhdr.__hdr;
int ii, n; int ii, n;
printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ", printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
iocp->name, m); iocp->name, m);
n = iocp->req_sz/4 - 1; n = iocp->req_sz/4 - 1;
while (m[n] == 0) while (m[n] == 0)
n--; n--;
for (ii=0; ii<=n; ii++) { for (ii=0; ii<=n; ii++) {
if (ii && ((ii%8)==0)) if (ii && ((ii%8)==0))
printk("\n" KERN_INFO " "); printk("\n" KERN_INFO " ");
printk(" %08x", le32_to_cpu(m[ii])); printk(" %08x", le32_to_cpu(m[ii]));
}
printk("\n");
} }
#endif printk("\n");
mf_dma_addr = iocp->req_frames_low_dma + req_offset;
CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
} else {
printk (KERN_ERR
"mpt_put_msg_frame: Invalid iocid=%d\n", iocid);
} }
#endif
mf_dma_addr = iocp->req_frames_low_dma + req_offset;
CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -962,21 +914,17 @@ mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf) ...@@ -962,21 +914,17 @@ mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf)
* FreeQ. * FreeQ.
*/ */
void void
mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf) mpt_free_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
{ {
MPT_ADAPTER *iocp;
unsigned long flags; unsigned long flags;
iocp = mpt_adapters[iocid]; /* Put Request back on FreeQ! */
if (iocp != NULL) { spin_lock_irqsave(&iocp->FreeQlock, flags);
/* Put Request back on FreeQ! */ Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
spin_lock_irqsave(&iocp->FreeQlock, flags);
Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
#ifdef MFCNT #ifdef MFCNT
iocp->mfcnt--; iocp->mfcnt--;
#endif #endif
spin_unlock_irqrestore(&iocp->FreeQlock, flags); spin_unlock_irqrestore(&iocp->FreeQlock, flags);
}
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -1062,127 +1010,80 @@ mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr) ...@@ -1062,127 +1010,80 @@ mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
* Returns 0 for success, non-zero for failure. * Returns 0 for success, non-zero for failure.
*/ */
int int
mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag) mpt_send_handshake_request(int handle, MPT_ADAPTER *iocp, int reqBytes, u32 *req, int sleepFlag)
{ {
MPT_ADAPTER *iocp;
int r = 0; int r = 0;
u8 *req_as_bytes;
int ii;
iocp = mpt_adapters[iocid]; /* State is known to be good upon entering
if (iocp != NULL) { * this function so issue the bus reset
u8 *req_as_bytes; * request.
int ii; */
/* State is known to be good upon entering
* this function so issue the bus reset
* request.
*/
/*
* Emulate what mpt_put_msg_frame() does /wrt to sanity
* setting cb_idx/req_idx. But ONLY if this request
* is in proper (pre-alloc'd) request buffer range...
*/
ii = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
if (reqBytes >= 12 && ii >= 0 && ii < iocp->req_depth) {
MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
}
/* Make sure there are no doorbells */ /*
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0); * Emulate what mpt_put_msg_frame() does /wrt to sanity
* setting cb_idx/req_idx. But ONLY if this request
* is in proper (pre-alloc'd) request buffer range...
*/
ii = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
if (reqBytes >= 12 && ii >= 0 && ii < iocp->req_depth) {
MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
}
CHIPREG_WRITE32(&iocp->chip->Doorbell, /* Make sure there are no doorbells */
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); CHIPREG_WRITE32(&iocp->chip->Doorbell,
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
/* Wait for IOC doorbell int */ /* Wait for IOC doorbell int */
if ((ii = WaitForDoorbellInt(iocp, 5, sleepFlag)) < 0) { ii = WaitForDoorbellInt(iocp, 5, sleepFlag);
return ii; if (ii < 0)
} return ii;
/* Read doorbell and check for active bit */ /* Read doorbell and check for active bit */
if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
return -5; return -5;
dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n", dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
iocp->name, ii)); iocp->name, ii));
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0); CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) { r = WaitForDoorbellAck(iocp, 5, sleepFlag);
return -2; if (r < 0)
} return -2;
/* Send request via doorbell handshake */ /* Send request via doorbell handshake */
req_as_bytes = (u8 *) req; req_as_bytes = (u8 *) req;
for (ii = 0; ii < reqBytes/4; ii++) { for (ii = 0; ii < reqBytes/4; ii++) {
u32 word; u32 word;
word = ((req_as_bytes[(ii*4) + 0] << 0) | word = ((req_as_bytes[(ii*4) + 0] << 0) |
(req_as_bytes[(ii*4) + 1] << 8) | (req_as_bytes[(ii*4) + 1] << 8) |
(req_as_bytes[(ii*4) + 2] << 16) | (req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24)); (req_as_bytes[(ii*4) + 3] << 24));
CHIPREG_WRITE32(&iocp->chip->Doorbell, word); CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) { r = WaitForDoorbellAck(iocp, 5, sleepFlag);
r = -3; if (r < 0) {
break; r = -3;
} break;
} }
if (r >= 0 && WaitForDoorbellInt(iocp, 10, sleepFlag) >= 0)
r = 0;
else
r = -4;
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
} }
return r; if (r >= 0 && WaitForDoorbellInt(iocp, 10, sleepFlag) >= 0)
} r = 0;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_adapter_find_first - Find first MPT adapter pointer.
*
* Returns first MPT adapter pointer or %NULL if no MPT adapters
* are present.
*/
MPT_ADAPTER *
mpt_adapter_find_first(void)
{
MPT_ADAPTER *this;
if (! Q_IS_EMPTY(&MptAdapters))
this = MptAdapters.head;
else else
this = NULL; r = -4;
return this; /* Make sure there are no doorbells */
} CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
return r;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_adapter_find_next - Find next MPT adapter pointer.
* @prev: Pointer to previous MPT adapter
*
* Returns next MPT adapter pointer or %NULL if there are no more.
*/
MPT_ADAPTER *
mpt_adapter_find_next(MPT_ADAPTER *prev)
{
MPT_ADAPTER *next;
if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head))
next = prev->forw;
else
next = NULL;
return next;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mpt_verify_adapter - Given a unique IOC identifier, set pointer to * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
...@@ -1195,18 +1096,17 @@ mpt_adapter_find_next(MPT_ADAPTER *prev) ...@@ -1195,18 +1096,17 @@ mpt_adapter_find_next(MPT_ADAPTER *prev)
int int
mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
{ {
MPT_ADAPTER *p; MPT_ADAPTER *ioc;
list_for_each_entry(ioc,&ioc_list,list) {
if (ioc->id == iocid) {
*iocpp =ioc;
return iocid;
}
}
*iocpp = NULL; *iocpp = NULL;
if (iocid >= MPT_MAX_ADAPTERS) return -1;
return -1;
p = mpt_adapters[iocid];
if (p == NULL)
return -1;
*iocpp = p;
return iocid;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -1240,6 +1140,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1240,6 +1140,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
u64 mask = 0xffffffffffffffffULL; u64 mask = 0xffffffffffffffffULL;
u8 revision; u8 revision;
u8 pcixcmd; u8 pcixcmd;
static int mpt_ids = 0;
struct proc_dir_entry *dent, *ent;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
return r; return r;
...@@ -1296,18 +1198,9 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1296,18 +1198,9 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Q_INIT(&ioc->configQ, Q_ITEM); Q_INIT(&ioc->configQ, Q_ITEM);
/* Find lookup slot. */ /* Find lookup slot. */
for (ii=0; ii < MPT_MAX_ADAPTERS; ii++) { INIT_LIST_HEAD(&ioc->list);
if (mpt_adapters[ii] == NULL) { ioc->id = mpt_ids++;
ioc->id = ii; /* Assign adapter unique id (lookup) */
break;
}
}
if (ii == MPT_MAX_ADAPTERS) {
printk(KERN_ERR MYNAM ": ERROR - mpt_adapters[%d] table overflow!\n", ii);
kfree(ioc);
return -ENFILE;
}
mem_phys = msize = 0; mem_phys = msize = 0;
port = psize = 0; port = psize = 0;
for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
...@@ -1429,11 +1322,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1429,11 +1322,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->active = 0; ioc->active = 0;
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
/* tack onto tail of our MPT adapter list */
Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);
/* Set lookup ptr. */ /* Set lookup ptr. */
mpt_adapters[ioc->id] = ioc; list_add_tail(&ioc->list, &ioc_list);
ioc->pci_irq = -1; ioc->pci_irq = -1;
if (pdev->irq) { if (pdev->irq) {
...@@ -1448,7 +1338,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1448,7 +1338,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->name, __irq_itoa(pdev->irq)); ioc->name, __irq_itoa(pdev->irq));
#endif #endif
Q_DEL_ITEM(ioc); Q_DEL_ITEM(ioc);
mpt_adapters[ioc->id] = NULL; list_del(&ioc->list);
iounmap(mem); iounmap(mem);
kfree(ioc); kfree(ioc);
return -EBUSY; return -EBUSY;
...@@ -1480,7 +1370,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1480,7 +1370,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->name, r); ioc->name, r);
Q_DEL_ITEM(ioc); Q_DEL_ITEM(ioc);
mpt_adapters[ioc->id] = NULL; list_del(&ioc->list);
free_irq(ioc->pci_irq, ioc); free_irq(ioc->pci_irq, ioc);
iounmap(mem); iounmap(mem);
kfree(ioc); kfree(ioc);
...@@ -1496,6 +1386,23 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1496,6 +1386,23 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
} }
} }
/*
* Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
*/
dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
if (dent) {
ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
if (ent) {
ent->read_proc = procmpt_iocinfo_read;
ent->data = ioc;
}
ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
if (ent) {
ent->read_proc = procmpt_summary_read;
ent->data = ioc;
}
}
return 0; return 0;
} }
...@@ -1510,8 +1417,16 @@ static void __devexit ...@@ -1510,8 +1417,16 @@ static void __devexit
mptbase_remove(struct pci_dev *pdev) mptbase_remove(struct pci_dev *pdev)
{ {
MPT_ADAPTER *ioc = pci_get_drvdata(pdev); MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
char pname[32];
int ii; int ii;
sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
remove_proc_entry(pname, NULL);
sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
remove_proc_entry(pname, NULL);
sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
remove_proc_entry(pname, NULL);
/* call per device driver remove entry point */ /* call per device driver remove entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) { for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] && if(MptDeviceDriverHandlers[ii] &&
...@@ -1519,7 +1434,7 @@ mptbase_remove(struct pci_dev *pdev) ...@@ -1519,7 +1434,7 @@ mptbase_remove(struct pci_dev *pdev)
MptDeviceDriverHandlers[ii]->remove(pdev); MptDeviceDriverHandlers[ii]->remove(pdev);
} }
} }
/* Disable interrupts! */ /* Disable interrupts! */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
...@@ -1531,7 +1446,6 @@ mptbase_remove(struct pci_dev *pdev) ...@@ -1531,7 +1446,6 @@ mptbase_remove(struct pci_dev *pdev)
CHIPREG_READ32(&ioc->chip->IntStatus); CHIPREG_READ32(&ioc->chip->IntStatus);
Q_DEL_ITEM(ioc);
mpt_adapter_dispose(ioc); mpt_adapter_dispose(ioc);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
...@@ -1769,11 +1683,17 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1769,11 +1683,17 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
ioc->alt_ioc->name, r); ioc->alt_ioc->name, r);
} }
/* Get IOC facts! Allow 1 retry */ for (ii=0; ii<5; ii++) {
if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) /* Get IOC facts! Allow 1 retry */
r = GetIocFacts(ioc, sleepFlag, reason); if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) {
dinitprintk((MYIOC_s_INFO_FMT
"ii=%d IocFacts failed r=%x\n", ioc->name, ii, r));
} else
break;
}
if (r) { if (r) {
dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed r=%x\n", ioc->name, r));
ret = -2; ret = -2;
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
MptDisplayIocCapabilities(ioc); MptDisplayIocCapabilities(ioc);
...@@ -1781,11 +1701,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1781,11 +1701,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
if (alt_ioc_ready) { if (alt_ioc_ready) {
if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed r=%x\n", ioc->name, r));
/* Retry - alt IOC was initialized once /* Retry - alt IOC was initialized once
*/ */
r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
} }
if (r) { if (r) {
dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed r=%x\n", ioc->name, r));
alt_ioc_ready = 0; alt_ioc_ready = 0;
reset_alt_ioc_active = 0; reset_alt_ioc_active = 0;
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
...@@ -1973,15 +1895,15 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1973,15 +1895,15 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
static void static void
mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
{ {
MPT_ADAPTER *ioc_srch = mpt_adapter_find_first();
unsigned int match_lo, match_hi; unsigned int match_lo, match_hi;
MPT_ADAPTER *ioc_srch;
match_lo = pdev->devfn-1; match_lo = pdev->devfn-1;
match_hi = pdev->devfn+1; match_hi = pdev->devfn+1;
dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n", dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi)); ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
while (ioc_srch != NULL) { list_for_each_entry(ioc_srch, &ioc_list, list) {
struct pci_dev *_pcidev = ioc_srch->pcidev; struct pci_dev *_pcidev = ioc_srch->pcidev;
if ((_pcidev->device == pdev->device) && if ((_pcidev->device == pdev->device) &&
...@@ -2003,7 +1925,6 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) ...@@ -2003,7 +1925,6 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
ioc->alt_ioc = ioc_srch; ioc->alt_ioc = ioc_srch;
break; break;
} }
ioc_srch = mpt_adapter_find_next(ioc_srch);
} }
} }
...@@ -2018,15 +1939,8 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup) ...@@ -2018,15 +1939,8 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
{ {
if (this != NULL) { if (this != NULL) {
int sz=0; int sz=0;
u32 state;
int ret; int ret;
/* Disable the FW */
state = mpt_GetIocState(this, 1);
if (state == MPI_IOC_STATE_OPERATIONAL) {
SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP);
}
if (this->cached_fw != NULL) { if (this->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n")); ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n"));
...@@ -2070,25 +1984,11 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup) ...@@ -2070,25 +1984,11 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
} }
if (freeup && this->cached_fw != NULL) { if (freeup && this->cached_fw != NULL) {
int ii = 0;
while ((ii < this->num_fw_frags) && (this->cached_fw[ii]!= NULL)) {
sz = this->cached_fw[ii]->size;
pci_free_consistent(this->pcidev, sz,
this->cached_fw[ii]->fw, this->cached_fw[ii]->fw_dma);
this->cached_fw[ii]->fw = NULL;
this->alloc_total -= sz;
kfree(this->cached_fw[ii]); sz = this->facts.FWImageSize;
this->cached_fw[ii] = NULL; pci_free_consistent(this->pcidev, sz,
this->alloc_total -= sizeof(fw_image_t); this->cached_fw, this->cached_fw_dma);
ii++;
}
kfree(this->cached_fw);
this->cached_fw = NULL; this->cached_fw = NULL;
sz = this->num_fw_frags * sizeof(void *);
this->alloc_total -= sz; this->alloc_total -= sz;
} }
...@@ -2130,11 +2030,6 @@ mpt_adapter_dispose(MPT_ADAPTER *this) ...@@ -2130,11 +2030,6 @@ mpt_adapter_dispose(MPT_ADAPTER *this)
sz_first = this->alloc_total; sz_first = this->alloc_total;
if (this->alt_ioc != NULL) {
this->alt_ioc->alt_ioc = NULL;
this->alt_ioc = NULL;
}
mpt_adapter_disable(this, 1); mpt_adapter_disable(this, 1);
if (this->pci_irq != -1) { if (this->pci_irq != -1) {
...@@ -2153,7 +2048,7 @@ mpt_adapter_dispose(MPT_ADAPTER *this) ...@@ -2153,7 +2048,7 @@ mpt_adapter_dispose(MPT_ADAPTER *this)
#endif #endif
/* Zap the adapter lookup ptr! */ /* Zap the adapter lookup ptr! */
mpt_adapters[this->id] = NULL; list_del(&this->list);
sz_last = this->alloc_total; sz_last = this->alloc_total;
dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
...@@ -2250,13 +2145,14 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) ...@@ -2250,13 +2145,14 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
if ((int)ioc->chip_type <= (int)FC929) if ((int)ioc->chip_type <= (int)FC929)
return 0; return 0;
else { else {
return 0;
/* Workaround from broken 1030 FW. /* Workaround from broken 1030 FW.
* Force a diagnostic reset if fails. * Force a diagnostic reset if fails.
*/ */
if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0) /* if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
return 0; return 0;
else else
statefault = 4; statefault = 4; */
} }
} }
...@@ -2275,7 +2171,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) ...@@ -2275,7 +2171,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Hmmm... Did it get left operational? * Hmmm... Did it get left operational?
*/ */
if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) { if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
dprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n", dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
ioc->name)); ioc->name));
/* Check WhoInit. /* Check WhoInit.
...@@ -2419,7 +2315,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) ...@@ -2419,7 +2315,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
get_facts.Function = MPI_FUNCTION_IOC_FACTS; get_facts.Function = MPI_FUNCTION_IOC_FACTS;
/* Assert: All other get_facts fields are zero! */ /* Assert: All other get_facts fields are zero! */
dprintk((MYIOC_s_INFO_FMT "Sending get IocFacts request\n", ioc->name)); dinitprintk((MYIOC_s_INFO_FMT "Sending get IocFacts request\n", ioc->name));
/* No non-zero fields in the get_facts request are greater than /* No non-zero fields in the get_facts request are greater than
* 1 byte in size, so we can just fire it off as is. * 1 byte in size, so we can just fire it off as is.
...@@ -2519,8 +2415,10 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) ...@@ -2519,8 +2415,10 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
return r; return r;
} }
} else { } else {
printk(MYIOC_s_ERR_FMT "Invalid IOC facts reply!\n", printk(MYIOC_s_ERR_FMT
ioc->name); "Invalid IOC facts reply, msgLength=%d offsetof=%d!\n",
ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
RequestFrameSize)/sizeof(u32)));
return -66; return -66;
} }
...@@ -2665,7 +2563,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2665,7 +2563,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
dprintk((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,
...@@ -2677,6 +2575,9 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2677,6 +2575,9 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
* since we don't even look at it's contents. * since we don't even look at it's contents.
*/ */
dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
ioc->name, &ioc_init));
if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
return r; return r;
...@@ -2771,86 +2672,14 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) ...@@ -2771,86 +2672,14 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
* Outputs: frags - number of fragments needed * Outputs: frags - number of fragments needed
* Return NULL if failed. * Return NULL if failed.
*/ */
void * void
mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz) mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
{ {
fw_image_t **cached_fw;
u8 *mem;
dma_addr_t fw_dma;
int alloc_total = 0;
int bytes_left, bytes, num_frags;
int sz, ii;
/* cached_fw /* cached_fw
*/ */
sz = ioc->num_fw_frags * sizeof(void *);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return NULL;
memset(mem, 0, sz);
cached_fw = (fw_image_t **)mem;
alloc_total += sz;
/* malloc fragment memory
* fw_image_t struct and dma for fw data
*/
bytes_left = size;
ii = 0;
num_frags = 0;
bytes = bytes_left;
while((bytes_left) && (num_frags < ioc->num_fw_frags)) {
if (cached_fw[ii] == NULL) {
mem = kmalloc(sizeof(fw_image_t), GFP_ATOMIC);
if (mem == NULL)
break;
memset(mem, 0, sizeof(fw_image_t));
cached_fw[ii] = (fw_image_t *)mem;
alloc_total += sizeof(fw_image_t);
}
mem = pci_alloc_consistent(ioc->pcidev, bytes, &fw_dma);
if (mem == NULL) {
if (bytes > 0x10000)
bytes = 0x10000;
else if (bytes > 0x8000)
bytes = 0x8000;
else if (bytes > 0x4000)
bytes = 0x4000;
else if (bytes > 0x2000)
bytes = 0x2000;
else if (bytes > 0x1000)
bytes = 0x1000;
else
break;
continue;
}
cached_fw[ii]->fw = mem;
cached_fw[ii]->fw_dma = fw_dma;
cached_fw[ii]->size = bytes;
memset(mem, 0, bytes);
alloc_total += bytes;
bytes_left -= bytes;
num_frags++;
ii++;
}
if (bytes_left ) {
/* Major Failure.
*/
mpt_free_fw_memory(ioc, cached_fw);
return NULL;
}
*frags = num_frags;
*alloc_sz = alloc_total;
return (void *) cached_fw; if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
ioc->alloc_total += size;
} }
/* /*
...@@ -2858,45 +2687,14 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz) ...@@ -2858,45 +2687,14 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz)
* Else, delete a secondary image in same format. * Else, delete a secondary image in same format.
*/ */
void void
mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img) mpt_free_fw_memory(MPT_ADAPTER *ioc)
{ {
fw_image_t **cached_fw;
int ii;
int sz; int sz;
int alloc_freed = 0;
if (alt_img != NULL)
cached_fw = alt_img;
else
cached_fw = ioc->cached_fw;
if (cached_fw == NULL)
return;
ii = 0;
while ((ii < ioc->num_fw_frags) && (cached_fw[ii]!= NULL)) {
sz = cached_fw[ii]->size;
if (sz > 0) {
pci_free_consistent(ioc->pcidev, sz,
cached_fw[ii]->fw, cached_fw[ii]->fw_dma);
}
cached_fw[ii]->fw = NULL;
alloc_freed += sz;
kfree(cached_fw[ii]); sz = ioc->facts.FWImageSize;
cached_fw[ii] = NULL; pci_free_consistent(ioc->pcidev, sz,
alloc_freed += sizeof(fw_image_t); ioc->cached_fw, ioc->cached_fw_dma);
ioc->cached_fw = NULL;
ii++;
}
kfree(cached_fw);
cached_fw = NULL;
sz = ioc->num_fw_frags * sizeof(void *);
alloc_freed += sz;
if (alt_img == NULL)
ioc->alloc_total -= alloc_freed;
return; return;
} }
...@@ -2925,9 +2723,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2925,9 +2723,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
FWUploadReply_t *preply; FWUploadReply_t *preply;
FWUploadTCSGE_t *ptcsge; FWUploadTCSGE_t *ptcsge;
int sgeoffset; int sgeoffset;
u32 flagsLength;
int ii, sz, reply_sz; int ii, sz, reply_sz;
int cmdStatus, freeMem = 0; int cmdStatus, freeMem = 0;
int num_frags, alloc_sz;
/* If the image size is 0 or if the pointer is /* If the image size is 0 or if the pointer is
* not NULL (error), we are done. * not NULL (error), we are done.
...@@ -2935,24 +2733,21 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2935,24 +2733,21 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
if (((sz = ioc->facts.FWImageSize) == 0) || ioc->cached_fw) if (((sz = ioc->facts.FWImageSize) == 0) || ioc->cached_fw)
return 0; return 0;
ioc->num_fw_frags = ioc->req_sz - sizeof(FWUpload_t) + sizeof(dma_addr_t) + sizeof(u32) -1; if ( sz & 0x01 )
ioc->num_fw_frags /= sizeof(dma_addr_t) + sizeof(u32); sz += 1;
if ( sz & 0x02 )
sz += 2;
ioc->cached_fw = (fw_image_t **) mpt_alloc_fw_memory(ioc, mpt_alloc_fw_memory(ioc, sz);
ioc->facts.FWImageSize, &num_frags, &alloc_sz);
if (ioc->cached_fw == NULL) { if (ioc->cached_fw == NULL) {
/* Major Failure. /* Major Failure.
*/ */
mpt_free_fw_memory(ioc, NULL);
ioc->cached_fw = NULL;
return -ENOMEM; return -ENOMEM;
} }
ioc->alloc_total += alloc_sz;
ddlprintk((KERN_INFO MYNAM ": FW Image @ %p, sz=%d bytes\n", dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
(void *)(ulong)ioc->cached_fw, ioc->facts.FWImageSize)); ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
prequest = (FWUpload_t *)&request; prequest = (FWUpload_t *)&request;
preply = (FWUploadReply_t *)&reply; preply = (FWUploadReply_t *)&reply;
...@@ -2965,39 +2760,27 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2965,39 +2760,27 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM; prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
prequest->Function = MPI_FUNCTION_FW_UPLOAD; prequest->Function = MPI_FUNCTION_FW_UPLOAD;
prequest->MsgContext = 0; /* anything */
ptcsge = (FWUploadTCSGE_t *) &prequest->SGL; ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
ptcsge->Reserved = 0;
ptcsge->ContextSize = 0;
ptcsge->DetailsLength = 12; ptcsge->DetailsLength = 12;
ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT; ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
ptcsge->Reserved1 = 0;
ptcsge->ImageOffset = 0;
ptcsge->ImageSize = cpu_to_le32(sz); ptcsge->ImageSize = cpu_to_le32(sz);
sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t); sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
for (ii = 0; ii < (num_frags-1); ii++) { flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
mpt_add_sge(&request[sgeoffset], MPT_SGE_FLAGS_SIMPLE_ELEMENT | mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
MPT_SGE_FLAGS_ADDRESSING | MPT_TRANSFER_IOC_TO_HOST |
(u32) ioc->cached_fw[ii]->size, ioc->cached_fw[ii]->fw_dma);
sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
}
mpt_add_sge(&request[sgeoffset],
MPT_SGE_FLAGS_SSIMPLE_READ |(u32) ioc->cached_fw[ii]->size,
ioc->cached_fw[ii]->fw_dma);
sgeoffset += sizeof(u32) + sizeof(dma_addr_t); sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
dprintk((MYIOC_s_INFO_FMT "Sending FW Upload (req @ %p) size %d \n", prequest, sgeoffset));
ioc->name, prequest, sgeoffset)); DBG_DUMP_FW_REQUEST_FRAME(prequest)
ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
cmdStatus = -EFAULT; cmdStatus = -EFAULT;
if (ii == 0) { if (ii == 0) {
/* Handshake transfer was complete and successful. /* Handshake transfer was complete and successful.
...@@ -3011,7 +2794,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -3011,7 +2794,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
cmdStatus = 0; cmdStatus = 0;
} }
} }
ddlprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n", dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
ioc->name, cmdStatus)); ioc->name, cmdStatus));
/* Check to see if we have a copy of this image in /* Check to see if we have a copy of this image in
...@@ -3031,8 +2814,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -3031,8 +2814,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT ": do_upload freeing %s image \n", ddlprintk((MYIOC_s_INFO_FMT ": do_upload freeing %s image \n",
ioc->name, cmdStatus ? "incomplete" : "duplicate")); ioc->name, cmdStatus ? "incomplete" : "duplicate"));
mpt_free_fw_memory(ioc, NULL); mpt_free_fw_memory(ioc);
ioc->cached_fw = NULL;
} }
return cmdStatus; return cmdStatus;
...@@ -3055,241 +2837,138 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -3055,241 +2837,138 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
static int static int
mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
{ {
MpiFwHeader_t *FwHdr; MpiFwHeader_t *pFwHeader;
MpiExtImageHeader_t *ExtHdr; MpiExtImageHeader_t *pExtImage;
fw_image_t **pCached=NULL; u32 fwSize;
int fw_sz;
u32 diag0val; u32 diag0val;
#ifdef MPT_DEBUG #ifdef MPT_DEBUG
u32 diag1val = 0; u32 diag1val = 0;
#endif #endif
int count = 0; int count = 0;
u32 *ptru32; u32 *ptrFw;
u32 diagRwData; u32 diagRwData;
u32 nextImage; u32 nextImage;
u32 ext_offset;
u32 load_addr; u32 load_addr;
int max_idx, fw_idx, ext_idx; u32 ioc_state;
int left_u32s;
ddlprintk((MYIOC_s_INFO_FMT "DbGb0: downloadboot entered.\n", ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
ioc->name));
#ifdef MPT_DEBUG
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "DbGb1: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
ddlprintk((MYIOC_s_INFO_FMT "fw size 0x%x, ioc FW Ptr %p\n",
ioc->name, ioc->facts.FWImageSize, ioc->cached_fw)); ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
if (ioc->alt_ioc)
ddlprintk((MYIOC_s_INFO_FMT "alt ioc FW Ptr %p\n",
ioc->name, ioc->alt_ioc->cached_fw));
/* Get dma_addr and data transfer size. /* Get dma_addr and data transfer size.
*/ */
if ((fw_sz = ioc->facts.FWImageSize) == 0) if ( ioc->facts.FWImageSize == 0 )
return -1; return -1;
/* Get the DMA from ioc or ioc->alt_ioc */ /* Get the DMA from ioc or ioc->alt_ioc */
if (ioc->cached_fw != NULL) if (ioc->cached_fw == NULL)
pCached = (fw_image_t **)ioc->cached_fw;
else if (ioc->alt_ioc && (ioc->alt_ioc->cached_fw != NULL))
pCached = (fw_image_t **)ioc->alt_ioc->cached_fw;
else
return -2; return -2;
ddlprintk((MYIOC_s_INFO_FMT "DbGb2: FW Image @ %p\n", CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
ioc->name, pCached)); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
/* Write magic sequence to WriteSequence register
* until enter diagnostic mode
*/
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
while ((diag0val & MPI_DIAG_DRWE) == 0) { diag0val |= (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
/* wait 100 msec */ /* wait 100 msec */
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100 * HZ / 1000);
} else {
mdelay (100);
}
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
for (count = 0; count < 30; count ++) {
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
ioc->name, count));
break;
}
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100 * HZ / 1000); schedule_timeout(HZ);
} else { } else {
mdelay (100); mdelay (1000);
}
count++;
if (count > 20) {
printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
ioc->name, diag0val);
return -EFAULT;
} }
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
ddlprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
ioc->name, diag0val));
} }
/* Set the DiagRwEn and Disable ARM bits */ if ( count == 30 ) {
diag0val |= (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM); ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); ioc->name, diag0val));
return -3;
#ifdef MPT_DEBUG }
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n", CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
ioc->name, diag0val, diag1val)); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
#endif CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
/* max_idx = 1 + maximum valid buffer index /* Set the DiagRwEn and Disable ARM bits */
*/ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
max_idx = 0; CHIPREG_WRITE32(&ioc->chip->Diagnostic, (diag0val | MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
while (pCached[max_idx])
max_idx++;
fw_idx = 0; pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
FwHdr = (MpiFwHeader_t *) pCached[fw_idx]->fw; fwSize = (pFwHeader->ImageSize + 3)/4;
ptru32 = (u32 *) FwHdr; ptrFw = (u32 *) pFwHeader;
count = (FwHdr->ImageSize + 3)/4;
nextImage = FwHdr->NextImageHeaderOffset;
/* Write the LoadStartAddress to the DiagRw Address Register /* Write the LoadStartAddress to the DiagRw Address Register
* using Programmed IO * using Programmed IO
*/ */
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, FwHdr->LoadStartAddress); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n", ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
ioc->name, FwHdr->LoadStartAddress)); ioc->name, pFwHeader->LoadStartAddress));
ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x u32's @ %p\n", ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
ioc->name, count, ptru32)); ioc->name, fwSize*4, ptrFw));
left_u32s = pCached[fw_idx]->size/4; while (fwSize--) {
while (count--) { CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
if (left_u32s == 0) {
fw_idx++;
if (fw_idx >= max_idx) {
/* FIXME
ERROR CASE
*/
;
}
ptru32 = (u32 *) pCached[fw_idx]->fw;
left_u32s = pCached[fw_idx]->size / 4;
}
left_u32s--;
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptru32);
ptru32++;
} }
/* left_u32s, fw_idx and ptru32 are all valid nextImage = pFwHeader->NextImageHeaderOffset;
*/
while (nextImage) { while (nextImage) {
ext_idx = 0; pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
ext_offset = nextImage;
while (ext_offset > pCached[ext_idx]->size) {
ext_idx++;
if (ext_idx >= max_idx) {
/* FIXME
ERROR CASE
*/
;
}
ext_offset -= pCached[ext_idx]->size;
}
ptru32 = (u32 *) ((char *)pCached[ext_idx]->fw + ext_offset);
left_u32s = pCached[ext_idx]->size - ext_offset;
if ((left_u32s * 4) >= sizeof(MpiExtImageHeader_t)) {
ExtHdr = (MpiExtImageHeader_t *) ptru32;
count = (ExtHdr->ImageSize + 3 )/4;
nextImage = ExtHdr->NextImageHeaderOffset;
load_addr = ExtHdr->LoadStartAddress;
} else {
u32 * ptmp = (u32 *)pCached[ext_idx+1]->fw;
switch (left_u32s) { load_addr = pExtImage->LoadStartAddress;
case 5:
count = *(ptru32 + 2);
nextImage = *(ptru32 + 3);
load_addr = *(ptru32 + 4);
break;
case 4:
count = *(ptru32 + 2);
nextImage = *(ptru32 + 3);
load_addr = *ptmp;
break;
case 3:
count = *(ptru32 + 2);
nextImage = *ptmp;
load_addr = *(ptmp + 1);
break;
case 2:
count = *ptmp;
nextImage = *(ptmp + 1);
load_addr = *(ptmp + 2);
break;
case 1: fwSize = (pExtImage->ImageSize + 3) >> 2;
count = *(ptmp + 1); ptrFw = (u32 *)pExtImage;
nextImage = *(ptmp + 2);
load_addr = *(ptmp + 3);
break;
default:
count = 0;
nextImage = 0;
load_addr = 0;
/* FIXME
ERROR CASE
*/
;
}
count = (count +3)/4;
}
ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x u32's @ %p\n", ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
ioc->name, count, ptru32)); ioc->name, fwSize*4, ptrFw, load_addr));
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
while (count--) { while (fwSize--) {
if (left_u32s == 0) { CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
fw_idx++;
if (fw_idx >= max_idx) {
/* FIXME
ERROR CASE
*/
;
}
ptru32 = (u32 *) pCached[fw_idx]->fw;
left_u32s = pCached[fw_idx]->size / 4;
}
left_u32s--;
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptru32);
ptru32++;
} }
nextImage = pExtImage->NextImageHeaderOffset;
} }
/* Write the IopResetVectorRegAddr */ /* Write the IopResetVectorRegAddr */
ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr! \n", ioc->name)); ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, FwHdr->IopResetRegAddr); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
/* Write the IopResetVectorValue */ /* Write the IopResetVectorValue */
ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value! \n", ioc->name)); ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, FwHdr->IopResetVectorValue); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
/* clear the PREVENT_IOC_BOOT bit */
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT\n",
ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
/* 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.
...@@ -3300,15 +2979,63 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -3300,15 +2979,63 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
/* clear the RW enable and DISARM bits */
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_FLASH_BAD_SIG); ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off DISABLE_ARM, RW_ENABLE, RESET_HISTORY\n",
ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_RESET_HISTORY);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
/* wait 100 msec */
if (sleepFlag == CAN_SLEEP) {
ddlprintk((MYIOC_s_INFO_FMT "CAN_SLEEP 100 msec before reset the sequencer\n", ioc->name));
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100 * HZ / 1000);
} else {
ddlprintk((MYIOC_s_INFO_FMT "mdelay 100 msec before reset the sequencer\n", ioc->name));
mdelay (100);
}
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
if ( diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_DISABLE_ARM) ) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed, diag0val=%x FLASH_BAD_SIG | DISABLE_ARM on\n ",
ioc->name, diag0val));
}
/* Write 0xFF to reset the sequencer */ /* Write 0xFF to reset the sequencer */
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
return 0; for (count=0; count<HZ*20; count++) {
if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
ioc->name, count, ioc_state));
/* if ((r = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
if ((r = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed\n",
ioc->name));
return -EFAULT;
}
} */
/* wait 2 sec */
/* if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(5000 * HZ / 1000);
} else {
mdelay (5000);
} */
return 0;
}
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
} else {
mdelay (10);
}
}
ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
ioc->name, ioc_state));
return -EFAULT;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -3344,7 +3071,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) ...@@ -3344,7 +3071,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
u32 ioc_state; u32 ioc_state;
int cntdn, cnt = 0; int cntdn, cnt = 0;
dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name)); dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
if ((int)ioc->chip_type > (int)FC929) { if ((int)ioc->chip_type > (int)FC929) {
/* Always issue a Msg Unit Reset first. This will clear some /* Always issue a Msg Unit Reset first. This will clear some
* SCSI bus hang conditions. * SCSI bus hang conditions.
...@@ -3593,6 +3320,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) ...@@ -3593,6 +3320,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* Write magic sequence to WriteSequence register /* Write magic sequence to WriteSequence register
* Loop until in diagnostic mode * Loop until in diagnostic mode
*/ */
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);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
...@@ -3672,7 +3400,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) ...@@ -3672,7 +3400,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
u32 state; u32 state;
int cntdn, count; int cntdn, count;
dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n", drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
ioc->name, reset_type)); ioc->name, reset_type));
CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT); CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
...@@ -4011,6 +3739,9 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, ...@@ -4011,6 +3739,9 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
*/ */
if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0) if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
failcnt++; failcnt++;
dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
/* /*
* Copy out the cached reply... * Copy out the cached reply...
...@@ -4042,7 +3773,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -4042,7 +3773,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
{ {
int cntdn; int cntdn;
int count = 0; int count = 0;
u32 intstat; u32 intstat=0;
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
...@@ -4066,13 +3797,13 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -4066,13 +3797,13 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
} }
if (cntdn) { if (cntdn) {
dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (cnt=%d)\n", dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
ioc->name, count)); ioc->name, count));
return count; return count;
} }
printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout(%d)!\n", printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
ioc->name, (count+5)/HZ); ioc->name, count, intstat);
return -1; return -1;
} }
...@@ -4093,7 +3824,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -4093,7 +3824,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
{ {
int cntdn; int cntdn;
int count = 0; int count = 0;
u32 intstat; u32 intstat=0;
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
...@@ -4116,13 +3847,13 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -4116,13 +3847,13 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
} }
if (cntdn) { if (cntdn) {
dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d)\n", dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
ioc->name, count)); ioc->name, count, howlong));
return count; return count;
} }
printk(MYIOC_s_ERR_FMT "Doorbell INT timeout(%d)!\n", printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
ioc->name, (count+5)/HZ); ioc->name, count, intstat);
return -1; return -1;
} }
...@@ -4168,8 +3899,8 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -4168,8 +3899,8 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
} }
} }
dhsprintk((MYIOC_s_INFO_FMT "First handshake reply word=%08x%s\n", dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
ioc->name, le32_to_cpu(*(u32 *)hs_reply), ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
/* /*
...@@ -4207,8 +3938,8 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) ...@@ -4207,8 +3938,8 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name)); dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
DBG_DUMP_REPLY_FRAME(mptReply) DBG_DUMP_REPLY_FRAME(mptReply)
dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY (sz=%d)\n", dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
ioc->name, u16cnt/2)); ioc->name, t, u16cnt/2));
return u16cnt/2; return u16cnt/2;
} }
...@@ -5000,7 +4731,7 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch) ...@@ -5000,7 +4731,7 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
{ {
EventNotification_t *evnp; EventNotification_t *evnp;
evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc->id); evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
if (evnp == NULL) { if (evnp == NULL) {
dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
ioc->name)); ioc->name));
...@@ -5015,7 +4746,7 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch) ...@@ -5015,7 +4746,7 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
evnp->MsgFlags = 0; evnp->MsgFlags = 0;
evnp->Switch = EvSwitch; evnp->Switch = EvSwitch;
mpt_put_msg_frame(mpt_base_index, ioc->id, (MPT_FRAME_HDR *)evnp); mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
return 0; return 0;
} }
...@@ -5031,7 +4762,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) ...@@ -5031,7 +4762,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
{ {
EventAck_t *pAck; EventAck_t *pAck;
if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) { if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n", printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
ioc->name); ioc->name);
return -1; return -1;
...@@ -5046,7 +4777,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) ...@@ -5046,7 +4777,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
pAck->Event = evnp->Event; pAck->Event = evnp->Event;
pAck->EventContext = evnp->EventContext; pAck->EventContext = evnp->EventContext;
mpt_put_msg_frame(mpt_base_index, ioc->id, (MPT_FRAME_HDR *)pAck); mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
return 0; return 0;
} }
...@@ -5072,7 +4803,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5072,7 +4803,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
unsigned long flags; unsigned long flags;
int ii, rc; int ii, rc;
int flagsLength; u32 flagsLength;
int in_isr; int in_isr;
/* (Bugzilla:fibrebugs, #513) /* (Bugzilla:fibrebugs, #513)
...@@ -5089,7 +4820,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5089,7 +4820,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
/* Get and Populate a free Frame /* Get and Populate a free Frame
*/ */
if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
ioc->name)); ioc->name));
return -EAGAIN; return -EAGAIN;
...@@ -5148,7 +4879,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5148,7 +4879,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
add_timer(&pCfg->timer); add_timer(&pCfg->timer);
mpt_put_msg_frame(mpt_base_index, ioc->id, mf); mpt_put_msg_frame(mpt_base_index, ioc, mf);
wait_event(mpt_waitq, pCfg->wait_done); wait_event(mpt_waitq, pCfg->wait_done);
/* mf has been freed - do not access */ /* mf has been freed - do not access */
...@@ -5176,10 +4907,11 @@ int ...@@ -5176,10 +4907,11 @@ int
mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
{ {
ToolboxIstwiReadWriteRequest_t *pReq; ToolboxIstwiReadWriteRequest_t *pReq;
struct pci_dev *pdev;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
unsigned long flags; unsigned long flags;
int rc; int rc;
int flagsLength; u32 flagsLength;
int in_isr; int in_isr;
/* (Bugzilla:fibrebugs, #513) /* (Bugzilla:fibrebugs, #513)
...@@ -5196,7 +4928,7 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5196,7 +4928,7 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
/* Get and Populate a free Frame /* Get and Populate a free Frame
*/ */
if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n", dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
ioc->name)); ioc->name));
return -EAGAIN; return -EAGAIN;
...@@ -5215,7 +4947,11 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5215,7 +4947,11 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
pReq->NumAddressBytes = 0x01; pReq->NumAddressBytes = 0x01;
pReq->Reserved4 = 0; pReq->Reserved4 = 0;
pReq->DataLength = 0x04; pReq->DataLength = 0x04;
pReq->DeviceAddr = 0xB0; pdev = (struct pci_dev *) ioc->pcidev;
if (pdev->devfn & 1)
pReq->DeviceAddr = 0xB2;
else
pReq->DeviceAddr = 0xB0;
pReq->Addr1 = 0; pReq->Addr1 = 0;
pReq->Addr2 = 0; pReq->Addr2 = 0;
pReq->Addr3 = 0; pReq->Addr3 = 0;
...@@ -5254,7 +4990,7 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5254,7 +4990,7 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
add_timer(&pCfg->timer); add_timer(&pCfg->timer);
mpt_put_msg_frame(mpt_base_index, ioc->id, mf); mpt_put_msg_frame(mpt_base_index, ioc, mf);
wait_event(mpt_waitq, pCfg->wait_done); wait_event(mpt_waitq, pCfg->wait_done);
/* mf has been freed - do not access */ /* mf has been freed - do not access */
...@@ -5368,61 +5104,19 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -5368,61 +5104,19 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
static int static int
procmpt_create(void) procmpt_create(void)
{ {
MPT_ADAPTER *ioc;
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
int ii;
/*
* BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
* (single level) to multi level (e.g. "driver/message/fusion")
* something here needs to change. -sralston
*/
mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL); mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
if (mpt_proc_root_dir == NULL) if (mpt_proc_root_dir == NULL)
return -ENOTDIR; return -ENOTDIR;
for (ii=0; ii < MPT_PROC_ENTRIES; ii++) { ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
ent = create_proc_entry(mpt_proc_list[ii].name, if (ent)
S_IFREG|S_IRUGO, mpt_proc_root_dir); ent->read_proc = procmpt_summary_read;
if (!ent) {
printk(KERN_WARNING MYNAM
": WARNING - Could not create /proc/mpt/%s entry\n",
mpt_proc_list[ii].name);
continue;
}
ent->read_proc = mpt_proc_list[ii].f;
ent->data = NULL;
}
ioc = mpt_adapter_find_first(); ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
while (ioc != NULL) { if (ent)
struct proc_dir_entry *dent; ent->read_proc = procmpt_version_read;
/*
* Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
*/
if ((dent = proc_mkdir(ioc->name, mpt_proc_root_dir)) != NULL) {
/*
* And populate it with mpt_ioc_proc_list[] entries.
*/
for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
ent = create_proc_entry(mpt_ioc_proc_list[ii].name,
S_IFREG|S_IRUGO, dent);
if (!ent) {
printk(KERN_WARNING MYNAM
": WARNING - Could not create /proc/mpt/%s/%s entry!\n",
ioc->name,
mpt_ioc_proc_list[ii].name);
continue;
}
ent->read_proc = mpt_ioc_proc_list[ii].f;
ent->data = ioc;
}
} else {
printk(MYIOC_s_WARN_FMT "Could not create /proc/mpt/%s subdir entry!\n",
ioc->name, mpt_ioc_proc_list[ii].name);
}
ioc = mpt_adapter_find_next(ioc);
}
return 0; return 0;
} }
...@@ -5433,49 +5127,12 @@ procmpt_create(void) ...@@ -5433,49 +5127,12 @@ procmpt_create(void)
* *
* Returns 0 for success, non-zero for failure. * Returns 0 for success, non-zero for failure.
*/ */
static int static void
procmpt_destroy(void) procmpt_destroy(void)
{ {
MPT_ADAPTER *ioc; remove_proc_entry("version", mpt_proc_root_dir);
int ii; remove_proc_entry("summary", mpt_proc_root_dir);
remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
if (!mpt_proc_root_dir)
return 0;
/*
* BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
* (single level) to multi level (e.g. "driver/message/fusion")
* something here needs to change. -sralston
*/
ioc = mpt_adapter_find_first();
while (ioc != NULL) {
char pname[32];
int namelen;
namelen = sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
/*
* Tear down each "/proc/mpt/iocN" subdirectory.
*/
for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
(void) sprintf(pname+namelen, "/%s", mpt_ioc_proc_list[ii].name);
remove_proc_entry(pname, NULL);
}
remove_proc_entry(ioc->name, mpt_proc_root_dir);
ioc = mpt_adapter_find_next(ioc);
}
for (ii=0; ii < MPT_PROC_ENTRIES; ii++)
remove_proc_entry(mpt_proc_list[ii].name, mpt_proc_root_dir);
if (atomic_read((atomic_t *)&mpt_proc_root_dir->count) == 0) {
remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
mpt_proc_root_dir = NULL;
return 0;
}
return -1;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -5498,26 +5155,25 @@ procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eo ...@@ -5498,26 +5155,25 @@ procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eo
char *out = buf; char *out = buf;
int len; int len;
if (data == NULL) if (data) {
ioc = mpt_adapter_find_first();
else
ioc = data; ioc = data;
while (ioc) {
int more = 0; int more = 0;
mpt_print_ioc_summary(ioc, out, &more, 0, 1); mpt_print_ioc_summary(ioc, out, &more, 0, 1);
out += more; out += more;
if ((out-buf) >= request) { } else {
break; list_for_each_entry(ioc, &ioc_list, list) {
} int more = 0;
if (data == NULL) mpt_print_ioc_summary(ioc, out, &more, 0, 1);
ioc = mpt_adapter_find_next(ioc);
else out += more;
ioc = NULL; /* force exit for iocN */ if ((out-buf) >= request)
break;
}
} }
len = out - buf; len = out - buf;
MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
...@@ -6295,7 +5951,7 @@ mpt_deregister_ascqops_strings(void) ...@@ -6295,7 +5951,7 @@ mpt_deregister_ascqops_strings(void)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
EXPORT_SYMBOL(mpt_adapters); EXPORT_SYMBOL(ioc_list);
EXPORT_SYMBOL(mpt_proc_root_dir); EXPORT_SYMBOL(mpt_proc_root_dir);
EXPORT_SYMBOL(DmpService); EXPORT_SYMBOL(DmpService);
EXPORT_SYMBOL(mpt_register); EXPORT_SYMBOL(mpt_register);
...@@ -6313,8 +5969,6 @@ EXPORT_SYMBOL(mpt_add_sge); ...@@ -6313,8 +5969,6 @@ EXPORT_SYMBOL(mpt_add_sge);
EXPORT_SYMBOL(mpt_add_chain); EXPORT_SYMBOL(mpt_add_chain);
EXPORT_SYMBOL(mpt_send_handshake_request); EXPORT_SYMBOL(mpt_send_handshake_request);
EXPORT_SYMBOL(mpt_handshake_req_reply_wait); EXPORT_SYMBOL(mpt_handshake_req_reply_wait);
EXPORT_SYMBOL(mpt_adapter_find_first);
EXPORT_SYMBOL(mpt_adapter_find_next);
EXPORT_SYMBOL(mpt_verify_adapter); EXPORT_SYMBOL(mpt_verify_adapter);
EXPORT_SYMBOL(mpt_GetIocState); EXPORT_SYMBOL(mpt_GetIocState);
EXPORT_SYMBOL(mpt_print_ioc_summary); EXPORT_SYMBOL(mpt_print_ioc_summary);
...@@ -6369,7 +6023,6 @@ fusion_init(void) ...@@ -6369,7 +6023,6 @@ fusion_init(void)
show_mptmod_ver(my_NAME, my_VERSION); show_mptmod_ver(my_NAME, my_VERSION);
printk(KERN_INFO COPYRIGHT "\n"); printk(KERN_INFO COPYRIGHT "\n");
Q_INIT(&MptAdapters, MPT_ADAPTER); /* set to empty */
for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) { for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
MptCallbacks[i] = NULL; MptCallbacks[i] = NULL;
MptDriverClass[i] = MPTUNKNOWN_DRIVER; MptDriverClass[i] = MPTUNKNOWN_DRIVER;
...@@ -6393,13 +6046,12 @@ fusion_init(void) ...@@ -6393,13 +6046,12 @@ fusion_init(void)
/* FIXME! */ /* FIXME! */
} }
r = pci_module_init(&mptbase_driver);
if(r)
return(r);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
(void) procmpt_create(); (void) procmpt_create();
#endif #endif
r = pci_module_init(&mptbase_driver);
if(r)
return(r);
return r; return r;
} }
...@@ -6415,16 +6067,14 @@ static void __exit ...@@ -6415,16 +6067,14 @@ static void __exit
fusion_exit(void) fusion_exit(void)
{ {
dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n")); dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
/* Whups? 20010120 -sralston
* Moved this *above* removal of all MptAdapters!
*/
#ifdef CONFIG_PROC_FS
(void) procmpt_destroy();
#endif
pci_unregister_driver(&mptbase_driver); pci_unregister_driver(&mptbase_driver);
mpt_reset_deregister(mpt_base_index); mpt_reset_deregister(mpt_base_index);
#ifdef CONFIG_PROC_FS
procmpt_destroy();
#endif
} }
......
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.01.07" #define MPT_LINUX_VERSION_COMMON "3.01.09"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.07" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.09"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -581,13 +581,6 @@ typedef struct _ScsiCfgData { ...@@ -581,13 +581,6 @@ typedef struct _ScsiCfgData {
u8 rsvd[1]; u8 rsvd[1];
} ScsiCfgData; } ScsiCfgData;
typedef struct _fw_image {
char *fw;
dma_addr_t fw_dma;
u32 size;
u32 rsvd;
} fw_image_t;
/* /*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
*/ */
...@@ -659,9 +652,9 @@ typedef struct _MPT_ADAPTER ...@@ -659,9 +652,9 @@ typedef struct _MPT_ADAPTER
int timeout_maxcnt; int timeout_maxcnt;
#endif #endif
struct _mpt_ioctl_events *events; /* pointer to event log */ struct _mpt_ioctl_events *events; /* pointer to event log */
fw_image_t **cached_fw; /* Pointer to FW SG List */ u8 *cached_fw; /* Pointer to FW */
dma_addr_t cached_fw_dma;
Q_TRACKER configQ; /* linked list of config. requests */ Q_TRACKER configQ; /* linked list of config. requests */
int num_fw_frags; /* Number of SGE in FW SG List */
int hs_reply_idx; int hs_reply_idx;
#ifndef MFCNT #ifndef MFCNT
u32 pad0; u32 pad0;
...@@ -682,6 +675,7 @@ typedef struct _MPT_ADAPTER ...@@ -682,6 +675,7 @@ typedef struct _MPT_ADAPTER
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 pad1[5]; u8 pad1[5];
struct list_head list;
} MPT_ADAPTER; } MPT_ADAPTER;
...@@ -742,6 +736,33 @@ typedef struct _mpt_sge { ...@@ -742,6 +736,33 @@ typedef struct _mpt_sge {
#define dprintk(x) #define dprintk(x)
#endif #endif
#ifdef MPT_DEBUG_INIT
#define dinitprintk(x) printk x
#define DBG_DUMP_FW_REQUEST_FRAME(mfp) \
{ int i, n = 10; \
u32 *m = (u32 *)(mfp); \
printk(KERN_INFO " "); \
for (i=0; i<n; i++) \
printk(" %08x", le32_to_cpu(m[i])); \
printk("\n"); \
}
#else
#define dinitprintk(x)
#define DBG_DUMP_FW_REQUEST_FRAME(mfp)
#endif
#ifdef MPT_DEBUG_EXIT
#define dexitprintk(x) printk x
#else
#define dexitprintk(x)
#endif
#ifdef MPT_DEBUG_RESET
#define drsprintk(x) printk x
#else
#define drsprintk(x)
#endif
#ifdef MPT_DEBUG_HANDSHAKE #ifdef MPT_DEBUG_HANDSHAKE
#define dhsprintk(x) printk x #define dhsprintk(x) printk x
#else #else
...@@ -975,19 +996,6 @@ typedef struct _MPT_SCSI_HOST { ...@@ -975,19 +996,6 @@ typedef struct _MPT_SCSI_HOST {
ushort sel_timeout[MPT_MAX_FC_DEVICES]; ushort sel_timeout[MPT_MAX_FC_DEVICES];
} MPT_SCSI_HOST; } MPT_SCSI_HOST;
/*
* Structure for overlaying onto scsi_cmnd->SCp area
* NOTE: SCp area is 36 bytes min, 44 bytes max?
*/
typedef struct _scPrivate {
struct scsi_cmnd *forw;
struct scsi_cmnd *back;
void *p1;
void *p2;
u8 io_path_id; /* DMP */
u8 pad[7];
} scPrivate;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* More Dynamic Multi-Pathing stuff... * More Dynamic Multi-Pathing stuff...
...@@ -1049,31 +1057,29 @@ extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb ...@@ -1049,31 +1057,29 @@ extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb
extern void mpt_device_driver_deregister(int cb_idx); extern void mpt_device_driver_deregister(int cb_idx);
extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable); extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
extern void mpt_deregister_ascqops_strings(void); extern void mpt_deregister_ascqops_strings(void);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid); extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc);
extern void mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf); extern void mpt_free_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf); extern void mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr); extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
extern void mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr); extern void mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr);
extern int mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag); extern int mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag);
extern int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag); extern int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag);
extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
extern MPT_ADAPTER *mpt_adapter_find_first(void);
extern MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev);
extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern void *mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz); extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img); 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);
/* /*
* Public data decl's... * Public data decl's...
*/ */
extern MPT_ADAPTER *mpt_adapters[MPT_MAX_ADAPTERS]; extern struct list_head ioc_list;
extern struct proc_dir_entry *mpt_proc_root_dir; extern struct proc_dir_entry *mpt_proc_root_dir;
extern DmpServices_t *DmpService; extern DmpServices_t *DmpService;
......
...@@ -87,10 +87,11 @@ ...@@ -87,10 +87,11 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/kdev_t.h> /* needed for access to Scsi_Host struct */ #include <scsi/scsi.h>
#include <linux/blkdev.h> #include <scsi/scsi_cmnd.h>
#include "../../scsi/scsi.h" #include <scsi/scsi_device.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation" #define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation"
#define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney" #define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney"
...@@ -399,7 +400,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -399,7 +400,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
/* Send request /* Send request
*/ */
if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc)) == NULL) {
dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n", dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
ioctl->ioc->name)); ioctl->ioc->name));
...@@ -434,7 +435,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -434,7 +435,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE; ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
add_timer(&ioctl->TMtimer); add_timer(&ioctl->TMtimer);
retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc->id, retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, NO_SLEEP); sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, NO_SLEEP);
if (retval != 0) { if (retval != 0) {
...@@ -443,7 +444,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -443,7 +444,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
mptctl_free_tm_flags(ioctl->ioc); mptctl_free_tm_flags(ioctl->ioc);
del_timer(&ioctl->TMtimer); del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioctl->ioc->id, mf); mpt_free_msg_frame(mptctl_id, ioctl->ioc, mf);
ioctl->tmPtr = NULL; ioctl->tmPtr = NULL;
} }
...@@ -518,7 +519,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -518,7 +519,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){ if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE; ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
del_timer(&ioctl->TMtimer); del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioc->id, ioctl->tmPtr); mpt_free_msg_frame(mptctl_id, ioc, ioctl->tmPtr);
} }
} else { } else {
...@@ -750,7 +751,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen) ...@@ -750,7 +751,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
/* Valid device. Get a message frame and construct the FW download message. /* Valid device. Get a message frame and construct the FW download message.
*/ */
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
return -EAGAIN; return -EAGAIN;
dlmsg = (FWDownload_t*) mf; dlmsg = (FWDownload_t*) mf;
ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
...@@ -866,7 +867,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen) ...@@ -866,7 +867,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
* Finally, perform firmware download. * Finally, perform firmware download.
*/ */
ReplyMsg = NULL; ReplyMsg = NULL;
mpt_put_msg_frame(mptctl_id, ioc, mf); mpt_put_msg_frame(mptctl_id, iocp, mf);
/* /*
* Wait until the reply has been received * Wait until the reply has been received
...@@ -1317,6 +1318,7 @@ mptctl_gettargetinfo (unsigned long arg) ...@@ -1317,6 +1318,7 @@ mptctl_gettargetinfo (unsigned long arg)
char *pmem; char *pmem;
int *pdata; int *pdata;
IOCPage2_t *pIoc2; IOCPage2_t *pIoc2;
IOCPage3_t *pIoc3;
int iocnum; int iocnum;
int numDevices = 0; int numDevices = 0;
unsigned int max_id; unsigned int max_id;
...@@ -1393,53 +1395,57 @@ mptctl_gettargetinfo (unsigned long arg) ...@@ -1393,53 +1395,57 @@ 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->spi_data.pIocPg2;
for ( id = 0; id <= max_id; id++ ) { for ( id = 0; id <= max_id; ) {
if ( pIoc2 && pIoc2->NumActiveVolumes && if ( pIoc2 && pIoc2->NumActiveVolumes ) {
( id == pIoc2->RaidVolume[0].VolumeID ) ) { if ( id == pIoc2->RaidVolume[0].VolumeID ) {
if (maxWordsLeft <= 0) { if (maxWordsLeft <= 0) {
printk(KERN_ERR "mptctl_gettargetinfo - " printk(KERN_ERR "mptctl_gettargetinfo - "
"buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices); "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
goto data_space_full; goto data_space_full;
} }
if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 ) if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
devType = 0x80; devType = 0x80;
else else
devType = 0xC0; devType = 0xC0;
bus_id = pIoc2->RaidVolume[0].VolumeBus; bus_id = pIoc2->RaidVolume[0].VolumeBus;
numDevices++; numDevices++;
*pdata = ( (devType << 24) | (bus_id << 8) | id ); *pdata = ( (devType << 24) | (bus_id << 8) | id );
dctlprintk((KERN_ERR "mptctl_gettargetinfo - " dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
"volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
pdata++; pdata++;
--maxWordsLeft; --maxWordsLeft;
} else { goto next_id;
vdev = hd->Targets[id]; } else {
if (vdev) { pIoc3 = ioc->spi_data.pIocPg3;
for (jj = 0; jj <= MPT_LAST_LUN; jj++) { for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
lun_index = (jj >> 5); if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
indexed_lun = (jj % 32); goto next_id;
lun = (1 << indexed_lun); }
if (vdev->luns[lun_index] & lun) { }
if (maxWordsLeft <= 0) { }
printk(KERN_ERR if ( (vdev = hd->Targets[id]) ) {
"mptctl_gettargetinfo - " for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
"buffer is full but more targets are available on ioc %d numDevices=%d\n", lun_index = (jj >> 5);
iocnum, numDevices); indexed_lun = (jj % 32);
goto data_space_full; lun = (1 << indexed_lun);
} if (vdev->luns[lun_index] & lun) {
bus_id = vdev->bus_id; if (maxWordsLeft <= 0) {
numDevices++; printk(KERN_ERR "mptctl_gettargetinfo - "
*pdata = ( (jj << 16) | (bus_id << 8) | id ); "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
dctlprintk((KERN_ERR goto data_space_full;
"mptctl_gettargetinfo - "
"target ioc=%d target=%x numDevices=%d pdata=%p\n",
iocnum, *pdata, numDevices, pdata));
pdata++;
--maxWordsLeft;
} }
bus_id = vdev->bus_id;
numDevices++;
*pdata = ( (jj << 16) | (bus_id << 8) | id );
dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
"target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
pdata++;
--maxWordsLeft;
} }
} }
} }
next_id:
id++;
} }
} }
} }
...@@ -1681,12 +1687,8 @@ mptctl_replace_fw (unsigned long arg) ...@@ -1681,12 +1687,8 @@ mptctl_replace_fw (unsigned long arg)
struct mpt_ioctl_replace_fw *uarg = (struct mpt_ioctl_replace_fw *) arg; struct mpt_ioctl_replace_fw *uarg = (struct mpt_ioctl_replace_fw *) arg;
struct mpt_ioctl_replace_fw karg; struct mpt_ioctl_replace_fw karg;
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
fw_image_t **fwmem = NULL;
int iocnum; int iocnum;
int newFwSize; int newFwSize;
int num_frags, alloc_sz;
int ii;
u32 offset;
dctlprintk(("mptctl_replace_fw called.\n")); dctlprintk(("mptctl_replace_fw called.\n"));
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
...@@ -1703,52 +1705,39 @@ mptctl_replace_fw (unsigned long arg) ...@@ -1703,52 +1705,39 @@ mptctl_replace_fw (unsigned long arg)
return -ENODEV; return -ENODEV;
} }
/* If not caching FW, return 0 /* If caching FW, Free the old FW image
*/ */
if ((ioc->cached_fw == NULL) && (ioc->alt_ioc) && (ioc->alt_ioc->cached_fw == NULL)) if (ioc->cached_fw == NULL)
return 0; return 0;
mpt_free_fw_memory(ioc);
/* Allocate memory for the new FW image /* Allocate memory for the new FW image
*/ */
newFwSize = karg.newImageSize; newFwSize = karg.newImageSize;
fwmem = mpt_alloc_fw_memory(ioc, newFwSize, &num_frags, &alloc_sz);
if (fwmem == NULL)
return -ENOMEM;
offset = 0; if (newFwSize & 0x01)
for (ii = 0; ii < num_frags; ii++) { newFwSize += 1;
/* Copy the data from user memory to kernel space if (newFwSize & 0x02)
*/ newFwSize += 2;
if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) {
printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
"Unable to read in mpt_ioctl_replace_fw image @ %p\n",
__FILE__, __LINE__, (void*)uarg);
mpt_free_fw_memory(ioc, fwmem);
return -EFAULT;
}
offset += fwmem[ii]->size;
}
mpt_alloc_fw_memory(ioc, newFwSize);
if (ioc->cached_fw == NULL)
return -ENOMEM;
/* Free the old FW image /* Copy the data from user memory to kernel space
*/ */
if (ioc->cached_fw) { if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
mpt_free_fw_memory(ioc, 0); printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
ioc->cached_fw = fwmem; "Unable to read in mpt_ioctl_replace_fw image "
ioc->alloc_total += alloc_sz; "@ %p\n", __FILE__, __LINE__, uarg);
} else if ((ioc->alt_ioc) && (ioc->alt_ioc->cached_fw)) { mpt_free_fw_memory(ioc);
mpt_free_fw_memory(ioc->alt_ioc, 0); return -EFAULT;
ioc->alt_ioc->cached_fw = fwmem;
ioc->alt_ioc->alloc_total += alloc_sz;
} }
/* Update IOCFactsReply /* Update IOCFactsReply
*/ */
ioc->facts.FWImageSize = newFwSize; ioc->facts.FWImageSize = newFwSize;
if (ioc->alt_ioc)
ioc->alt_ioc->facts.FWImageSize = newFwSize;
return 0; return 0;
} }
...@@ -1862,7 +1851,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -1862,7 +1851,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
/* Get a free request frame and save the message context. /* Get a free request frame and save the message context.
*/ */
if ((mf = mpt_get_msg_frame(mptctl_id, ioc->id)) == NULL) if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
return -EAGAIN; return -EAGAIN;
hdr = (MPIHeader_t *) mf; hdr = (MPIHeader_t *) mf;
...@@ -2214,7 +2203,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -2214,7 +2203,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
add_timer(&ioc->ioctl->timer); add_timer(&ioc->ioctl->timer);
if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) { if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
rc = mpt_send_handshake_request(mptctl_id, ioc->id, rc = mpt_send_handshake_request(mptctl_id, ioc,
sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP); sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
if (rc == 0) { if (rc == 0) {
wait_event(mptctl_wait, ioc->ioctl->wait_done); wait_event(mptctl_wait, ioc->ioctl->wait_done);
...@@ -2224,10 +2213,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -2224,10 +2213,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
del_timer(&ioc->ioctl->timer); del_timer(&ioc->ioctl->timer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE; ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED; ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
mpt_free_msg_frame(mptctl_id, ioc->id, mf); mpt_free_msg_frame(mptctl_id, ioc, mf);
} }
} else { } else {
mpt_put_msg_frame(mptctl_id, ioc->id, mf); mpt_put_msg_frame(mptctl_id, ioc, mf);
wait_event(mptctl_wait, ioc->ioctl->wait_done); wait_event(mptctl_wait, ioc->ioctl->wait_done);
} }
...@@ -2342,7 +2331,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -2342,7 +2331,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
* otherwise, failure occured after mf acquired. * otherwise, failure occured after mf acquired.
*/ */
if (mf) if (mf)
mpt_free_msg_frame(mptctl_id, ioc->id, mf); mpt_free_msg_frame(mptctl_id, ioc, mf);
return rc; return rc;
} }
......
...@@ -502,7 +502,7 @@ mpt_lan_reset(struct net_device *dev) ...@@ -502,7 +502,7 @@ mpt_lan_reset(struct net_device *dev)
LANResetRequest_t *pResetReq; LANResetRequest_t *pResetReq;
struct mpt_lan_priv *priv = netdev_priv(dev); struct mpt_lan_priv *priv = netdev_priv(dev);
mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id); mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev);
if (mf == NULL) { if (mf == NULL) {
/* dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! " /* dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
...@@ -520,7 +520,7 @@ mpt_lan_reset(struct net_device *dev) ...@@ -520,7 +520,7 @@ mpt_lan_reset(struct net_device *dev)
pResetReq->MsgFlags = 0; pResetReq->MsgFlags = 0;
pResetReq->Reserved2 = 0; pResetReq->Reserved2 = 0;
mpt_put_msg_frame(LanCtx, priv->mpt_dev->id, mf); mpt_put_msg_frame(LanCtx, priv->mpt_dev, mf);
return 0; return 0;
} }
...@@ -754,7 +754,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -754,7 +754,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
return 1; return 1;
} }
mf = mpt_get_msg_frame(LanCtx, mpt_dev->id); mf = mpt_get_msg_frame(LanCtx, mpt_dev);
if (mf == NULL) { if (mf == NULL) {
netif_stop_queue(dev); netif_stop_queue(dev);
spin_unlock_irqrestore(&priv->txfidx_lock, flags); spin_unlock_irqrestore(&priv->txfidx_lock, flags);
...@@ -859,7 +859,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -859,7 +859,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
else else
pSimple->Address.High = 0; pSimple->Address.High = 0;
mpt_put_msg_frame (LanCtx, mpt_dev->id, mf); mpt_put_msg_frame (LanCtx, mpt_dev, mf);
dev->trans_start = jiffies; dev->trans_start = jiffies;
dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n", dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n",
...@@ -1244,7 +1244,7 @@ mpt_lan_post_receive_buckets(void *dev_id) ...@@ -1244,7 +1244,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
(MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t));
while (buckets) { while (buckets) {
mf = mpt_get_msg_frame(LanCtx, mpt_dev->id); mf = mpt_get_msg_frame(LanCtx, mpt_dev);
if (mf == NULL) { if (mf == NULL) {
printk (KERN_ERR "%s: Unable to alloc request frame\n", printk (KERN_ERR "%s: Unable to alloc request frame\n",
__FUNCTION__); __FUNCTION__);
...@@ -1334,7 +1334,7 @@ mpt_lan_post_receive_buckets(void *dev_id) ...@@ -1334,7 +1334,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
if (pSimple == NULL) { if (pSimple == NULL) {
/**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n",
/**/ __FUNCTION__); /**/ __FUNCTION__);
mpt_free_msg_frame(LanCtx, mpt_dev->id, mf); mpt_free_msg_frame(LanCtx, mpt_dev, mf);
goto out; goto out;
} }
...@@ -1348,7 +1348,7 @@ mpt_lan_post_receive_buckets(void *dev_id) ...@@ -1348,7 +1348,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
* printk ("\n"); * printk ("\n");
*/ */
mpt_put_msg_frame(LanCtx, mpt_dev->id, mf); mpt_put_msg_frame(LanCtx, mpt_dev, mf);
priv->total_posted += i; priv->total_posted += i;
buckets -= i; buckets -= i;
...@@ -1489,7 +1489,7 @@ static int __init mpt_lan_init (void) ...@@ -1489,7 +1489,7 @@ static int __init mpt_lan_init (void)
mpt_landev[j] = NULL; mpt_landev[j] = NULL;
} }
for (p = mpt_adapter_find_first(); p; p = mpt_adapter_find_next(p)) { list_for_each_entry(p, &ioc_list, list) {
for (i = 0; i < p->facts.NumberOfPorts; i++) { for (i = 0; i < p->facts.NumberOfPorts; i++) {
printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n", printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
p->name, p->name,
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include "linux_compat.h" /* linux-2.6 tweaks */
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -76,9 +77,12 @@ ...@@ -76,9 +77,12 @@
#include <linux/reboot.h> /* notifier code */ #include <linux/reboot.h> /* notifier code */
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include "../../scsi/scsi.h"
#include <scsi/scsi_host.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "mptbase.h" #include "mptbase.h"
#include "mptscsih.h" #include "mptscsih.h"
...@@ -154,16 +158,16 @@ typedef struct _dv_parameters { ...@@ -154,16 +158,16 @@ typedef struct _dv_parameters {
* Other private/forward protos... * Other private/forward protos...
*/ */
static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static void mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq); static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static int mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt, static int mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
SCSIIORequest_t *pReq, int req_idx); SCSIIORequest_t *pReq, int req_idx);
static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx); static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx);
static int mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init); static int mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init);
static void copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
static u32 SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc); static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx); static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
static void post_pendingQ_commands(MPT_SCSI_HOST *hd); static void post_pendingQ_commands(MPT_SCSI_HOST *hd);
...@@ -248,104 +252,11 @@ static struct mptscsih_driver_setup ...@@ -248,104 +252,11 @@ static struct mptscsih_driver_setup
driver_setup = MPTSCSIH_DRIVER_SETUP; driver_setup = MPTSCSIH_DRIVER_SETUP;
#ifdef MPTSCSIH_DBG_TIMEOUT #ifdef MPTSCSIH_DBG_TIMEOUT
static Scsi_Cmnd *foo_to[8]; static struct scsi_cmnd *foo_to[8];
#endif #endif
static struct scsi_host_template driver_template; static struct scsi_host_template driver_template;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Private inline routines...
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* 19991030 -sralston
* Return absolute SCSI data direction:
* 1 = _DATA_OUT
* 0 = _DIR_NONE
* -1 = _DATA_IN
*
* Changed: 3-20-2002 pdelaney to use the default data
* direction and the defines set up in the
* 2.4 kernel series
* 1 = _DATA_OUT changed to SCSI_DATA_WRITE (1)
* 0 = _DIR_NONE changed to SCSI_DATA_NONE (3)
* -1 = _DATA_IN changed to SCSI_DATA_READ (2)
* If the direction is unknown, fall through to original code.
*
* Mid-layer bug fix(): sg interface generates the wrong data
* direction in some cases. Set the direction the hard way for
* the most common commands.
*/
static inline int
mptscsih_io_direction(Scsi_Cmnd *cmd)
{
switch (cmd->cmnd[0]) {
case WRITE_6:
case WRITE_10:
case WRITE_16:
return SCSI_DATA_WRITE;
break;
case READ_6:
case READ_10:
case READ_16:
return SCSI_DATA_READ;
break;
}
if (cmd->sc_data_direction != SCSI_DATA_UNKNOWN)
return cmd->sc_data_direction;
switch (cmd->cmnd[0]) {
/* _DATA_OUT commands */
case WRITE_6: case WRITE_10: case WRITE_12:
case WRITE_16:
case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER:
case WRITE_VERIFY: case WRITE_VERIFY_12:
case COMPARE: case COPY: case COPY_VERIFY:
case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
case SEARCH_EQUAL_12: case SEARCH_HIGH_12: case SEARCH_LOW_12:
case MODE_SELECT: case MODE_SELECT_10: case LOG_SELECT:
case SEND_DIAGNOSTIC: case CHANGE_DEFINITION: case UPDATE_BLOCK:
case SET_WINDOW: case MEDIUM_SCAN: case SEND_VOLUME_TAG:
case REASSIGN_BLOCKS:
case PERSISTENT_RESERVE_OUT:
case 0xea:
case 0xa3:
return SCSI_DATA_WRITE;
/* No data transfer commands */
case SEEK_6: case SEEK_10:
case RESERVE: case RELEASE:
case TEST_UNIT_READY:
case START_STOP:
case ALLOW_MEDIUM_REMOVAL:
return SCSI_DATA_NONE;
/* Conditional data transfer commands */
case FORMAT_UNIT:
if (cmd->cmnd[1] & 0x10) /* FmtData (data out phase)? */
return SCSI_DATA_WRITE;
else
return SCSI_DATA_NONE;
case VERIFY:
if (cmd->cmnd[1] & 0x02) /* VERIFY:BYTCHK (data out phase)? */
return SCSI_DATA_WRITE;
else
return SCSI_DATA_NONE;
case RESERVE_10:
if (cmd->cmnd[1] & 0x03) /* RESERVE:{LongID|Extent} (data out phase)? */
return SCSI_DATA_WRITE;
else
return SCSI_DATA_NONE;
/* Must be data _IN! */
default:
return SCSI_DATA_READ;
}
} /* mptscsih_io_direction() */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_add_sge - Place a simple SGE at address pAddr. * mptscsih_add_sge - Place a simple SGE at address pAddr.
...@@ -458,13 +369,13 @@ mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex) ...@@ -458,13 +369,13 @@ mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
* mptscsih_AddSGE - Add a SGE (plus chain buffers) to the * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
* SCSIIORequest_t Message Frame. * SCSIIORequest_t Message Frame.
* @hd: Pointer to MPT_SCSI_HOST structure * @hd: Pointer to MPT_SCSI_HOST structure
* @SCpnt: Pointer to Scsi_Cmnd structure * @SCpnt: Pointer to scsi_cmnd structure
* @pReq: Pointer to SCSIIORequest_t structure * @pReq: Pointer to SCSIIORequest_t structure
* *
* Returns ... * Returns ...
*/ */
static int static int
mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt, mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
SCSIIORequest_t *pReq, int req_idx) SCSIIORequest_t *pReq, int req_idx)
{ {
char *psge; char *psge;
...@@ -497,29 +408,20 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt, ...@@ -497,29 +408,20 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
if ( (sges_left = SCpnt->use_sg) ) { if ( (sges_left = SCpnt->use_sg) ) {
sges_left = pci_map_sg(hd->ioc->pcidev, sges_left = pci_map_sg(hd->ioc->pcidev,
(struct scatterlist *) SCpnt->request_buffer, (struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg, SCpnt->use_sg,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); SCpnt->sc_data_direction);
if (sges_left == 0) if (sges_left == 0)
return FAILED; return FAILED;
} else if (SCpnt->request_bufflen) { } else if (SCpnt->request_bufflen) {
dma_addr_t buf_dma_addr; SCpnt->SCp.dma_handle = pci_map_single(hd->ioc->pcidev,
scPrivate *my_priv;
buf_dma_addr = pci_map_single(hd->ioc->pcidev,
SCpnt->request_buffer, SCpnt->request_buffer,
SCpnt->request_bufflen, SCpnt->request_bufflen,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); SCpnt->sc_data_direction);
/* We hide it here for later unmap. */
my_priv = (scPrivate *) &SCpnt->SCp;
my_priv->p1 = (void *)(ulong) buf_dma_addr;
dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n", dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
hd->ioc->name, SCpnt, SCpnt->request_bufflen)); hd->ioc->name, SCpnt, SCpnt->request_bufflen));
mptscsih_add_sge((char *) &pReq->SGL, mptscsih_add_sge((char *) &pReq->SGL,
0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen, 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
buf_dma_addr); SCpnt->SCp.dma_handle);
return SUCCESS; return SUCCESS;
} }
...@@ -708,7 +610,7 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt, ...@@ -708,7 +610,7 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
static int static int
mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
{ {
Scsi_Cmnd *sc; struct scsi_cmnd *sc;
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
SCSIIORequest_t *pScsiReq; SCSIIORequest_t *pScsiReq;
SCSIIOReply_t *pScsiReply; SCSIIOReply_t *pScsiReply;
...@@ -829,6 +731,15 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -829,6 +731,15 @@ 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 */
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;
dprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
/* /*
* Do upfront check for valid SenseData and give it * Do upfront check for valid SenseData and give it
...@@ -946,14 +857,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -946,14 +857,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* Unmap the DMA buffers, if any. */ /* Unmap the DMA buffers, if any. */
if (sc->use_sg) { if (sc->use_sg) {
pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer, pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction)); sc->use_sg, sc->sc_data_direction);
} else if (sc->request_bufflen) { } else if (sc->request_bufflen) {
scPrivate *my_priv; pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
sc->request_bufflen, sc->sc_data_direction);
my_priv = (scPrivate *) &sc->SCp;
pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1,
sc->request_bufflen,
scsi_to_pci_dma_dir(sc->sc_data_direction));
} }
hd->ScsiLookup[req_idx] = NULL; hd->ScsiLookup[req_idx] = NULL;
...@@ -974,7 +881,7 @@ static void ...@@ -974,7 +881,7 @@ static void
flush_doneQ(MPT_SCSI_HOST *hd) flush_doneQ(MPT_SCSI_HOST *hd)
{ {
MPT_DONE_Q *buffer; MPT_DONE_Q *buffer;
Scsi_Cmnd *SCpnt; struct scsi_cmnd *SCpnt;
unsigned long flags; unsigned long flags;
/* Flush the doneQ. /* Flush the doneQ.
...@@ -992,9 +899,9 @@ flush_doneQ(MPT_SCSI_HOST *hd) ...@@ -992,9 +899,9 @@ flush_doneQ(MPT_SCSI_HOST *hd)
*/ */
Q_DEL_ITEM(buffer); Q_DEL_ITEM(buffer);
/* Set the Scsi_Cmnd pointer /* Set the struct scsi_cmnd pointer
*/ */
SCpnt = (Scsi_Cmnd *) buffer->argp; SCpnt = (struct scsi_cmnd *) buffer->argp;
buffer->argp = NULL; buffer->argp = NULL;
/* Add to the freeQ /* Add to the freeQ
...@@ -1015,7 +922,7 @@ flush_doneQ(MPT_SCSI_HOST *hd) ...@@ -1015,7 +922,7 @@ flush_doneQ(MPT_SCSI_HOST *hd)
* Calling function will finish processing. * Calling function will finish processing.
*/ */
static void static void
search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt) search_doneQ_for_cmd(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt)
{ {
unsigned long flags; unsigned long flags;
MPT_DONE_Q *buffer; MPT_DONE_Q *buffer;
...@@ -1024,12 +931,12 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt) ...@@ -1024,12 +931,12 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt)
if (!Q_IS_EMPTY(&hd->doneQ)) { if (!Q_IS_EMPTY(&hd->doneQ)) {
buffer = hd->doneQ.head; buffer = hd->doneQ.head;
do { do {
Scsi_Cmnd *sc = (Scsi_Cmnd *) buffer->argp; struct scsi_cmnd *sc = (struct scsi_cmnd *) buffer->argp;
if (SCpnt == sc) { if (SCpnt == sc) {
Q_DEL_ITEM(buffer); Q_DEL_ITEM(buffer);
SCpnt->result = sc->result; SCpnt->result = sc->result;
/* Set the Scsi_Cmnd pointer /* Set the struct scsi_cmnd pointer
*/ */
buffer->argp = NULL; buffer->argp = NULL;
...@@ -1057,7 +964,7 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt) ...@@ -1057,7 +964,7 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt)
static void static void
mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
{ {
Scsi_Cmnd *SCpnt; struct scsi_cmnd *SCpnt;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
MPT_DONE_Q *buffer; MPT_DONE_Q *buffer;
int ii; int ii;
...@@ -1093,15 +1000,12 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) ...@@ -1093,15 +1000,12 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
pci_unmap_sg(hd->ioc->pcidev, pci_unmap_sg(hd->ioc->pcidev,
(struct scatterlist *) SCpnt->request_buffer, (struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg, SCpnt->use_sg,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); SCpnt->sc_data_direction);
} else if (SCpnt->request_bufflen) { } else if (SCpnt->request_bufflen) {
scPrivate *my_priv;
my_priv = (scPrivate *) &SCpnt->SCp;
pci_unmap_single(hd->ioc->pcidev, pci_unmap_single(hd->ioc->pcidev,
(dma_addr_t)(ulong)my_priv->p1, SCpnt->SCp.dma_handle,
SCpnt->request_bufflen, SCpnt->request_bufflen,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); SCpnt->sc_data_direction);
} }
} }
SCpnt->result = DID_RESET << 16; SCpnt->result = DID_RESET << 16;
...@@ -1111,7 +1015,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) ...@@ -1111,7 +1015,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
mptscsih_freeChainBuffers(hd, ii); mptscsih_freeChainBuffers(hd, ii);
/* Free Message frames */ /* Free Message frames */
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
#if 1 #if 1
/* Post to doneQ, do not reply until POST phase /* Post to doneQ, do not reply until POST phase
...@@ -1123,7 +1027,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) ...@@ -1123,7 +1027,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
buffer = hd->freeQ.head; buffer = hd->freeQ.head;
Q_DEL_ITEM(buffer); Q_DEL_ITEM(buffer);
/* Set the Scsi_Cmnd pointer /* Set the struct scsi_cmnd pointer
*/ */
buffer->argp = (void *)SCpnt; buffer->argp = (void *)SCpnt;
...@@ -1149,7 +1053,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) ...@@ -1149,7 +1053,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
* mptscsih_search_running_cmds - Delete any commands associated * mptscsih_search_running_cmds - Delete any commands associated
* with the specified target and lun. Function called only * with the specified target and lun. Function called only
* when a lun is disable by mid-layer. * when a lun is disable by mid-layer.
* Do NOT access the referenced Scsi_Cmnd structure or * Do NOT access the referenced scsi_cmnd structure or
* members. Will cause either a paging or NULL ptr error. * members. Will cause either a paging or NULL ptr error.
* @hd: Pointer to a SCSI HOST structure * @hd: Pointer to a SCSI HOST structure
* @target: target id * @target: target id
...@@ -1184,7 +1088,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) ...@@ -1184,7 +1088,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
*/ */
hd->ScsiLookup[ii] = NULL; hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd, ii); mptscsih_freeChainBuffers(hd, ii);
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, (MPT_FRAME_HDR *)mf); mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, (MPT_FRAME_HDR *)mf);
} }
} }
...@@ -1307,7 +1211,7 @@ static long last_queue_full = 0; ...@@ -1307,7 +1211,7 @@ static long last_queue_full = 0;
/* /*
* mptscsih_report_queue_full - Report QUEUE_FULL status returned * mptscsih_report_queue_full - Report QUEUE_FULL status returned
* from a SCSI target device. * from a SCSI target device.
* @sc: Pointer to Scsi_Cmnd structure * @sc: Pointer to scsi_cmnd structure
* @pScsiReply: Pointer to SCSIIOReply_t * @pScsiReply: Pointer to SCSIIOReply_t
* @pScsiReq: Pointer to original SCSI request * @pScsiReq: Pointer to original SCSI request
* *
...@@ -1316,7 +1220,7 @@ static long last_queue_full = 0; ...@@ -1316,7 +1220,7 @@ static long last_queue_full = 0;
* printk() API call, not more than once every 10 seconds. * printk() API call, not more than once every 10 seconds.
*/ */
static void static void
mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq) mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
{ {
long time = jiffies; long time = jiffies;
...@@ -1492,7 +1396,7 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1492,7 +1396,7 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->is_multipath = 1; hd->is_multipath = 1;
} }
/* SCSI needs Scsi_Cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
sz = hd->ioc->req_depth * sizeof(void *); sz = hd->ioc->req_depth * sizeof(void *);
...@@ -1932,16 +1836,7 @@ mptscsih_init(void) ...@@ -1932,16 +1836,7 @@ mptscsih_init(void)
static void __exit static void __exit
mptscsih_exit(void) mptscsih_exit(void)
{ {
MPT_ADAPTER *ioc; mpt_device_driver_deregister(MPTSCSIH_DRIVER);
/* removing devices */
for(ioc = mpt_adapter_find_first(); ioc != NULL;
ioc = mpt_adapter_find_next(ioc)) {
if ((ioc->last_state != MPI_IOC_STATE_OPERATIONAL) ||
(ioc->sh == NULL))
continue;
mptscsih_remove(ioc->pcidev);
}
mpt_reset_deregister(ScsiDoneCtx); mpt_reset_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM dprintk((KERN_INFO MYNAM
...@@ -1951,7 +1846,6 @@ mptscsih_exit(void) ...@@ -1951,7 +1846,6 @@ mptscsih_exit(void)
dprintk((KERN_INFO MYNAM dprintk((KERN_INFO MYNAM
": Deregistered for IOC event notifications\n")); ": Deregistered for IOC event notifications\n"));
mpt_device_driver_deregister(MPTSCSIH_DRIVER);
mpt_deregister(ScsiScanDvCtx); mpt_deregister(ScsiScanDvCtx);
mpt_deregister(ScsiTaskCtx); mpt_deregister(ScsiTaskCtx);
mpt_deregister(ScsiDoneCtx); mpt_deregister(ScsiDoneCtx);
...@@ -1966,7 +1860,7 @@ mptscsih_exit(void) ...@@ -1966,7 +1860,7 @@ mptscsih_exit(void)
* mptscsih_info - Return information about MPT adapter * mptscsih_info - Return information about MPT adapter
* @SChost: Pointer to Scsi_Host structure * @SChost: Pointer to Scsi_Host structure
* *
* (linux Scsi_Host_Template.info routine) * (linux scsi_host_template.info routine)
* *
* Returns pointer to buffer where information was written. * Returns pointer to buffer where information was written.
*/ */
...@@ -2176,7 +2070,7 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length) ...@@ -2176,7 +2070,7 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
/** /**
* mptscsih_proc_info - Return information about MPT adapter * mptscsih_proc_info - Return information about MPT adapter
* *
* (linux Scsi_Host_Template.info routine) * (linux scsi_host_template.info routine)
* *
* buffer: if write, user data; if read, buffer for user * buffer: if write, user data; if read, buffer for user
* length: if write, return length; * length: if write, return length;
...@@ -2188,23 +2082,10 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length) ...@@ -2188,23 +2082,10 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
int length, int func) int length, int func)
{ {
MPT_ADAPTER *ioc; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
MPT_SCSI_HOST *hd = NULL; MPT_ADAPTER *ioc = hd->ioc;
int size = 0; int size = 0;
dprintk(("Called mptscsih_proc_info: hostno=%d, func=%d\n", host->host_no, func));
dprintk(("buffer %p, start=%p (%p) offset=%ld length = %d\n",
buffer, start, *start, offset, length));
for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {
if ((ioc->sh) && (ioc->sh == host)) {
hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
break;
}
}
if ((ioc == NULL) || (ioc->sh == NULL) || (hd == NULL))
return 0;
if (func) { if (func) {
size = mptscsih_user_command(ioc, buffer, length); size = mptscsih_user_command(ioc, buffer, length);
} else { } else {
...@@ -2224,17 +2105,17 @@ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t ...@@ -2224,17 +2105,17 @@ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine. * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
* @SCpnt: Pointer to Scsi_Cmnd structure * @SCpnt: Pointer to scsi_cmnd structure
* @done: Pointer SCSI mid-layer IO completion function * @done: Pointer SCSI mid-layer IO completion function
* *
* (linux Scsi_Host_Template.queuecommand routine) * (linux scsi_host_template.queuecommand routine)
* This is the primary SCSI IO start routine. Create a MPI SCSIIORequest * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
* from a linux Scsi_Cmnd request and send it to the IOC. * from a linux scsi_cmnd request and send it to the IOC.
* *
* Returns 0. (rtn value discarded by linux scsi mid-layer) * Returns 0. (rtn value discarded by linux scsi mid-layer)
*/ */
int int
mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) 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;
...@@ -2244,7 +2125,6 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2244,7 +2125,6 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
unsigned long flags; unsigned long flags;
int target; int target;
int lun; int lun;
int datadir;
u32 datalen; u32 datalen;
u32 scsictl; u32 scsictl;
u32 scsidir; u32 scsidir;
...@@ -2282,7 +2162,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2282,7 +2162,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/* /*
* Put together a MPT SCSI request... * Put together a MPT SCSI request...
*/ */
if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n", dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
hd->ioc->name)); hd->ioc->name));
did_errcode = 2; did_errcode = 2;
...@@ -2295,21 +2175,15 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2295,21 +2175,15 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
ADD_INDEX_LOG(my_idx); ADD_INDEX_LOG(my_idx);
/*
* The scsi layer should be handling this stuff
* (In 2.3.x it does -DaveM)
*/
/* BUG FIX! 19991030 -sralston /* BUG FIX! 19991030 -sralston
* TUR's being issued with scsictl=0x02000000 (DATA_IN)! * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
* Seems we may receive a buffer (datalen>0) even when there * Seems we may receive a buffer (datalen>0) even when there
* will be no data transfer! GRRRRR... * will be no data transfer! GRRRRR...
*/ */
datadir = mptscsih_io_direction(SCpnt); if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
if (datadir == SCSI_DATA_READ) {
datalen = SCpnt->request_bufflen; datalen = SCpnt->request_bufflen;
scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */ scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
} else if (datadir == SCSI_DATA_WRITE) { } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
datalen = SCpnt->request_bufflen; datalen = SCpnt->request_bufflen;
scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */ scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
} else { } else {
...@@ -2390,17 +2264,6 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2390,17 +2264,6 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
if (dvStatus || hd->ioc->spi_data.forceDv) { if (dvStatus || hd->ioc->spi_data.forceDv) {
/* Write SDP1 on this I/O to this target */
if (dvStatus & MPT_SCSICFG_NEGOTIATE) {
mptscsih_writeSDP1(hd, 0, target, hd->negoNvram);
dvStatus &= ~MPT_SCSICFG_NEGOTIATE;
hd->ioc->spi_data.dvStatus[target] = dvStatus;
} else if (dvStatus & MPT_SCSICFG_BLK_NEGO) {
mptscsih_writeSDP1(hd, 0, target, MPT_SCSICFG_BLK_NEGO);
dvStatus &= ~MPT_SCSICFG_BLK_NEGO;
hd->ioc->spi_data.dvStatus[target] = dvStatus;
}
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if ((dvStatus & MPT_SCSICFG_NEED_DV) || if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
(hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) { (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
...@@ -2448,7 +2311,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2448,7 +2311,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
#endif #endif
if (issueCmd) { if (issueCmd) {
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
hd->ioc->name, SCpnt, mf, my_idx)); hd->ioc->name, SCpnt, mf, my_idx));
} else { } else {
...@@ -2476,7 +2339,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2476,7 +2339,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
} }
} else { } else {
mptscsih_freeChainBuffers(hd, my_idx); mptscsih_freeChainBuffers(hd, my_idx);
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
did_errcode = 3; did_errcode = 3;
goto did_error; goto did_error;
} }
...@@ -2495,7 +2358,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -2495,7 +2358,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
buffer = hd->freeQ.head; buffer = hd->freeQ.head;
Q_DEL_ITEM(buffer); Q_DEL_ITEM(buffer);
/* Set the Scsi_Cmnd pointer /* Set the scsi_cmnd pointer
*/ */
buffer->argp = (void *)SCpnt; buffer->argp = (void *)SCpnt;
...@@ -2729,7 +2592,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun ...@@ -2729,7 +2592,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
/* Return Fail to calling function if no message frames available. /* Return Fail to calling function if no message frames available.
*/ */
if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n", dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
hd->ioc->name)); hd->ioc->name));
//return FAILED; //return FAILED;
...@@ -2773,7 +2636,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun ...@@ -2773,7 +2636,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
hd->TMtimer.expires = jiffies + timeout; hd->TMtimer.expires = jiffies + timeout;
add_timer(&hd->TMtimer); add_timer(&hd->TMtimer);
if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag)) sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
!= 0) { != 0) {
dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!" dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
...@@ -2781,7 +2644,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun ...@@ -2781,7 +2644,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
hd->numTMrequests--; hd->numTMrequests--;
hd->tmPtr = NULL; hd->tmPtr = NULL;
del_timer(&hd->TMtimer); del_timer(&hd->TMtimer);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc, mf);
} }
return retval; return retval;
...@@ -2789,15 +2652,15 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun ...@@ -2789,15 +2652,15 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_abort - Abort linux Scsi_Cmnd routine, new_eh variant * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
* @SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
* *
* (linux Scsi_Host_Template.eh_abort_handler routine) * (linux scsi_host_template.eh_abort_handler routine)
* *
* Returns SUCCESS or FAILED. * Returns SUCCESS or FAILED.
*/ */
int int
mptscsih_abort(Scsi_Cmnd * SCpnt) mptscsih_abort(struct scsi_cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
...@@ -2845,7 +2708,7 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2845,7 +2708,7 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
* and then following up with the reset request. * and then following up with the reset request.
*/ */
if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) { if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
post_pendingQ_commands(hd); post_pendingQ_commands(hd);
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"Posting pended cmd! (sc=%p)\n", "Posting pended cmd! (sc=%p)\n",
...@@ -2892,14 +2755,14 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2892,14 +2755,14 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
* @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
* *
* (linux Scsi_Host_Template.eh_dev_reset_handler routine) * (linux scsi_host_template.eh_dev_reset_handler routine)
* *
* Returns SUCCESS or FAILED. * Returns SUCCESS or FAILED.
*/ */
int int
mptscsih_dev_reset(Scsi_Cmnd * SCpnt) mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
spinlock_t *host_lock = SCpnt->device->host->host_lock; spinlock_t *host_lock = SCpnt->device->host->host_lock;
...@@ -2947,14 +2810,14 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt) ...@@ -2947,14 +2810,14 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
* @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
* *
* (linux Scsi_Host_Template.eh_bus_reset_handler routine) * (linux scsi_host_template.eh_bus_reset_handler routine)
* *
* Returns SUCCESS or FAILED. * Returns SUCCESS or FAILED.
*/ */
int int
mptscsih_bus_reset(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; spinlock_t *host_lock = SCpnt->device->host->host_lock;
...@@ -3002,14 +2865,14 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt) ...@@ -3002,14 +2865,14 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
/** /**
* mptscsih_host_reset - Perform a SCSI host adapter RESET! * mptscsih_host_reset - Perform a SCSI host adapter RESET!
* new_eh variant * new_eh variant
* @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
* *
* (linux Scsi_Host_Template.eh_host_reset_handler routine) * (linux scsi_host_template.eh_host_reset_handler routine)
* *
* Returns SUCCESS or FAILED. * Returns SUCCESS or FAILED.
*/ */
int int
mptscsih_host_reset(Scsi_Cmnd *SCpnt) mptscsih_host_reset(struct scsi_cmnd *SCpnt)
{ {
MPT_SCSI_HOST * hd; MPT_SCSI_HOST * hd;
int status = SUCCESS; int status = SUCCESS;
...@@ -3245,7 +3108,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, ...@@ -3245,7 +3108,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
* Init memory once per id (not LUN). * Init memory once per id (not LUN).
*/ */
int int
mptscsih_slave_alloc(Scsi_Device *device) mptscsih_slave_alloc(struct scsi_device *device)
{ {
struct Scsi_Host *host = device->host; struct Scsi_Host *host = device->host;
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
...@@ -3285,7 +3148,7 @@ mptscsih_slave_alloc(Scsi_Device *device) ...@@ -3285,7 +3148,7 @@ mptscsih_slave_alloc(Scsi_Device *device)
* Called if no device present or device being unloaded * Called if no device present or device being unloaded
*/ */
void void
mptscsih_slave_destroy(Scsi_Device *device) mptscsih_slave_destroy(struct scsi_device *device)
{ {
struct Scsi_Host *host = device->host; struct Scsi_Host *host = device->host;
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
...@@ -3350,7 +3213,7 @@ mptscsih_slave_destroy(Scsi_Device *device) ...@@ -3350,7 +3213,7 @@ mptscsih_slave_destroy(Scsi_Device *device)
* Return non-zero if fails. * Return non-zero if fails.
*/ */
int int
mptscsih_slave_configure(Scsi_Device *device) mptscsih_slave_configure(struct scsi_device *device)
{ {
struct Scsi_Host *sh = device->host; struct Scsi_Host *sh = device->host;
VirtDevice *pTarget; VirtDevice *pTarget;
...@@ -3433,7 +3296,7 @@ mptscsih_slave_configure(Scsi_Device *device) ...@@ -3433,7 +3296,7 @@ mptscsih_slave_configure(Scsi_Device *device)
* *
*/ */
static void static void
copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
{ {
VirtDevice *target; VirtDevice *target;
SCSIIORequest_t *pReq; SCSIIORequest_t *pReq;
...@@ -3511,7 +3374,7 @@ copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply ...@@ -3511,7 +3374,7 @@ copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply
} }
static u32 static u32
SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc) SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
int i; int i;
...@@ -3608,12 +3471,12 @@ post_pendingQ_commands(MPT_SCSI_HOST *hd) ...@@ -3608,12 +3471,12 @@ post_pendingQ_commands(MPT_SCSI_HOST *hd)
continue; continue;
} }
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
{ {
u16 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); u16 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
Scsi_Cmnd *sc = hd->ScsiLookup[req_idx]; struct scsi_cmnd *sc = hd->ScsiLookup[req_idx];
printk(MYIOC_s_INFO_FMT "Issued SCSI cmd (sc=%p) idx=%d (mf=%p)\n", printk(MYIOC_s_INFO_FMT "Issued SCSI cmd (sc=%p) idx=%d (mf=%p)\n",
hd->ioc->name, sc, req_idx, mf); hd->ioc->name, sc, req_idx, mf);
} }
...@@ -3675,7 +3538,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -3675,7 +3538,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
*/ */
if (hd->cmdPtr) { if (hd->cmdPtr) {
del_timer(&hd->timer); del_timer(&hd->timer);
mpt_free_msg_frame(ScsiScanDvCtx, ioc->id, hd->cmdPtr); mpt_free_msg_frame(ScsiScanDvCtx, ioc, hd->cmdPtr);
} }
/* 2d. If a task management has not completed, /* 2d. If a task management has not completed,
...@@ -3683,7 +3546,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -3683,7 +3546,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
*/ */
if (hd->tmPtr) { if (hd->tmPtr) {
del_timer(&hd->TMtimer); del_timer(&hd->TMtimer);
mpt_free_msg_frame(ScsiTaskCtx, ioc->id, hd->tmPtr); mpt_free_msg_frame(ScsiTaskCtx, ioc, hd->tmPtr);
} }
#ifdef MPTSCSIH_DBG_TIMEOUT #ifdef MPTSCSIH_DBG_TIMEOUT
...@@ -4377,7 +4240,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * ...@@ -4377,7 +4240,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
} }
} }
data_56 = 0; data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
if (dlen > 56) { if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities /* Update the target capabilities
...@@ -4442,14 +4305,16 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4442,14 +4305,16 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
} }
if (target->inq_data[7] & 0x10) { if (target->inq_data[7] & 0x10) {
/* bits 2 & 3 show DT support /* bits 2 & 3 show Clocking support
*/ */
if ((byte56 & 0x04) == 0) if ((byte56 & 0x0C) == 0)
factor = MPT_ULTRA2; factor = MPT_ULTRA2;
else if ((byte56 & 0x03) == 0) else {
factor = MPT_ULTRA160; if ((byte56 & 0x03) == 0)
else factor = MPT_ULTRA160;
factor = MPT_ULTRA320; else
factor = MPT_ULTRA320;
}
offset = pspi_data->maxSyncOffset; offset = pspi_data->maxSyncOffset;
/* If RAID, never disable QAS /* If RAID, never disable QAS
...@@ -4458,8 +4323,9 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4458,8 +4323,9 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
* bit 1 QAS support, non-raid only * bit 1 QAS support, non-raid only
* bit 0 IU support * bit 0 IU support
*/ */
if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0)) if ((target->raidVolume == 1) || (byte56 & 0x02)) {
noQas = 0; noQas = 0;
}
} else { } else {
factor = MPT_ASYNC; factor = MPT_ASYNC;
offset = 0; offset = 0;
...@@ -4538,7 +4404,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4538,7 +4404,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
/* Disable QAS in a mixed configuration case /* Disable QAS in a mixed configuration case
*/ */
// ddvtprintk((KERN_INFO "Disabling QAS!\n")); ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
for (ii = 0; ii < id; ii++) { for (ii = 0; ii < id; ii++) {
if ( (vdev = hd->Targets[ii]) ) { if ( (vdev = hd->Targets[ii]) ) {
vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
...@@ -4546,6 +4412,15 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4546,6 +4412,15 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
} }
} }
} }
/* Write SDP1 on this I/O to this target */
if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
} else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
}
} }
return; return;
...@@ -4778,7 +4653,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -4778,7 +4653,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
/* Get a MF for this command. /* Get a MF for this command.
*/ */
if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n", dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
ioc->name)); ioc->name));
return -EAGAIN; return -EAGAIN;
...@@ -4842,7 +4717,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -4842,7 +4717,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
ioc->name, id, (id | (bus<<8)), ioc->name, id, (id | (bus<<8)),
requested, configuration)); requested, configuration));
mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf); mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
} }
return 0; return 0;
...@@ -4873,7 +4748,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) ...@@ -4873,7 +4748,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
/* Get a MF for this command. /* Get a MF for this command.
*/ */
if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
ioc->name)); ioc->name));
return -EAGAIN; return -EAGAIN;
...@@ -4922,7 +4797,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) ...@@ -4922,7 +4797,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
"writeIOCPage4: pgaddr 0x%x\n", "writeIOCPage4: pgaddr 0x%x\n",
ioc->name, (target_id | (bus<<8)))); ioc->name, (target_id | (bus<<8))));
mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf); mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
return 0; return 0;
} }
...@@ -5234,7 +5109,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io) ...@@ -5234,7 +5109,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
/* Get and Populate a free Frame /* Get and Populate a free Frame
*/ */
if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
hd->ioc->name)); hd->ioc->name));
return -EAGAIN; return -EAGAIN;
...@@ -5259,7 +5134,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io) ...@@ -5259,7 +5134,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
hd->ioc->name, action, io->id)); hd->ioc->name, action, io->id));
hd->pLocal = NULL; hd->pLocal = NULL;
hd->timer.expires = jiffies + HZ*2; /* 2 second timeout */ hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
scandv_wait_done = 0; scandv_wait_done = 0;
/* Save cmd pointer, for resource free if timeout or /* Save cmd pointer, for resource free if timeout or
...@@ -5268,7 +5143,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io) ...@@ -5268,7 +5143,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
hd->cmdPtr = mf; hd->cmdPtr = mf;
add_timer(&hd->timer); add_timer(&hd->timer);
mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf); mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
wait_event(scandv_waitq, scandv_wait_done); wait_event(scandv_waitq, scandv_wait_done);
if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD)) if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
...@@ -5415,7 +5290,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) ...@@ -5415,7 +5290,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
/* Get and Populate a free Frame /* Get and Populate a free Frame
*/ */
if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc->id)) == NULL) { if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n", ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
hd->ioc->name)); hd->ioc->name));
return -EBUSY; return -EBUSY;
...@@ -5505,7 +5380,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) ...@@ -5505,7 +5380,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
hd->cmdPtr = mf; hd->cmdPtr = mf;
add_timer(&hd->timer); add_timer(&hd->timer);
mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf); mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
wait_event(scandv_waitq, scandv_wait_done); wait_event(scandv_waitq, scandv_wait_done);
if (hd->pLocal) { if (hd->pLocal) {
...@@ -5713,7 +5588,7 @@ mptscsih_domainValidation(void *arg) ...@@ -5713,7 +5588,7 @@ mptscsih_domainValidation(void *arg)
did = 1; did = 1;
while (did) { while (did) {
did = 0; did = 0;
for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) { list_for_each_entry(ioc, &ioc_list, list) {
spin_lock_irqsave(&dvtaskQ_lock, flags); spin_lock_irqsave(&dvtaskQ_lock, flags);
if (dvtaskQ_release) { if (dvtaskQ_release) {
dvtaskQ_active = 0; dvtaskQ_active = 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