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 @@
#ifndef 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 */
This diff is collapsed.
......@@ -85,8 +85,8 @@
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.01.07"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.07"
#define MPT_LINUX_VERSION_COMMON "3.01.09"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.09"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......@@ -581,13 +581,6 @@ typedef struct _ScsiCfgData {
u8 rsvd[1];
} 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
*/
......@@ -659,9 +652,9 @@ typedef struct _MPT_ADAPTER
int timeout_maxcnt;
#endif
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 */
int num_fw_frags; /* Number of SGE in FW SG List */
int hs_reply_idx;
#ifndef MFCNT
u32 pad0;
......@@ -682,6 +675,7 @@ typedef struct _MPT_ADAPTER
u8 upload_fw; /* If set, do a fw upload */
u8 reload_fw; /* Force a FW Reload on next reset */
u8 pad1[5];
struct list_head list;
} MPT_ADAPTER;
......@@ -742,6 +736,33 @@ typedef struct _mpt_sge {
#define dprintk(x)
#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
#define dhsprintk(x) printk x
#else
......@@ -975,19 +996,6 @@ typedef struct _MPT_SCSI_HOST {
ushort sel_timeout[MPT_MAX_FC_DEVICES];
} 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...
......@@ -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 int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
extern void mpt_deregister_ascqops_strings(void);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid);
extern void mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
extern void mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc);
extern void mpt_free_msg_frame(int handle, MPT_ADAPTER *ioc, 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_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_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 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_config(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_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img);
extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
/*
* 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 DmpServices_t *DmpService;
......
......@@ -87,10 +87,11 @@
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/kdev_t.h> /* needed for access to Scsi_Host struct */
#include <linux/blkdev.h>
#include "../../scsi/scsi.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>
#define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation"
#define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney"
......@@ -399,7 +400,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
/* 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",
ioctl->ioc->name));
......@@ -434,7 +435,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
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);
if (retval != 0) {
......@@ -443,7 +444,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
mptctl_free_tm_flags(ioctl->ioc);
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;
}
......@@ -518,7 +519,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioc->id, ioctl->tmPtr);
mpt_free_msg_frame(mptctl_id, ioc, ioctl->tmPtr);
}
} else {
......@@ -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.
*/
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
return -EAGAIN;
dlmsg = (FWDownload_t*) mf;
ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
......@@ -866,7 +867,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
* Finally, perform firmware download.
*/
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
......@@ -1317,6 +1318,7 @@ mptctl_gettargetinfo (unsigned long arg)
char *pmem;
int *pdata;
IOCPage2_t *pIoc2;
IOCPage3_t *pIoc3;
int iocnum;
int numDevices = 0;
unsigned int max_id;
......@@ -1393,9 +1395,9 @@ mptctl_gettargetinfo (unsigned long arg)
if (hd && hd->Targets) {
mpt_findImVolumes(ioc);
pIoc2 = ioc->spi_data.pIocPg2;
for ( id = 0; id <= max_id; id++ ) {
if ( pIoc2 && pIoc2->NumActiveVolumes &&
( id == pIoc2->RaidVolume[0].VolumeID ) ) {
for ( id = 0; id <= max_id; ) {
if ( pIoc2 && pIoc2->NumActiveVolumes ) {
if ( id == pIoc2->RaidVolume[0].VolumeID ) {
if (maxWordsLeft <= 0) {
printk(KERN_ERR "mptctl_gettargetinfo - "
"buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
......@@ -1412,34 +1414,38 @@ mptctl_gettargetinfo (unsigned long arg)
"volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
pdata++;
--maxWordsLeft;
goto next_id;
} else {
vdev = hd->Targets[id];
if (vdev) {
pIoc3 = ioc->spi_data.pIocPg3;
for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
goto next_id;
}
}
}
if ( (vdev = hd->Targets[id]) ) {
for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
lun_index = (jj >> 5);
indexed_lun = (jj % 32);
lun = (1 << indexed_lun);
if (vdev->luns[lun_index] & lun) {
if (maxWordsLeft <= 0) {
printk(KERN_ERR
"mptctl_gettargetinfo - "
"buffer is full but more targets are available on ioc %d numDevices=%d\n",
iocnum, numDevices);
printk(KERN_ERR "mptctl_gettargetinfo - "
"buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
goto data_space_full;
}
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));
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)
struct mpt_ioctl_replace_fw *uarg = (struct mpt_ioctl_replace_fw *) arg;
struct mpt_ioctl_replace_fw karg;
MPT_ADAPTER *ioc;
fw_image_t **fwmem = NULL;
int iocnum;
int newFwSize;
int num_frags, alloc_sz;
int ii;
u32 offset;
dctlprintk(("mptctl_replace_fw called.\n"));
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
......@@ -1703,52 +1705,39 @@ mptctl_replace_fw (unsigned long arg)
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;
mpt_free_fw_memory(ioc);
/* Allocate memory for the new FW image
*/
newFwSize = karg.newImageSize;
fwmem = mpt_alloc_fw_memory(ioc, newFwSize, &num_frags, &alloc_sz);
if (fwmem == NULL)
if (newFwSize & 0x01)
newFwSize += 1;
if (newFwSize & 0x02)
newFwSize += 2;
mpt_alloc_fw_memory(ioc, newFwSize);
if (ioc->cached_fw == NULL)
return -ENOMEM;
offset = 0;
for (ii = 0; ii < num_frags; ii++) {
/* Copy the data from user memory to kernel space
*/
if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) {
if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
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);
"Unable to read in mpt_ioctl_replace_fw image "
"@ %p\n", __FILE__, __LINE__, uarg);
mpt_free_fw_memory(ioc);
return -EFAULT;
}
offset += fwmem[ii]->size;
}
/* Free the old FW image
*/
if (ioc->cached_fw) {
mpt_free_fw_memory(ioc, 0);
ioc->cached_fw = fwmem;
ioc->alloc_total += alloc_sz;
} else if ((ioc->alt_ioc) && (ioc->alt_ioc->cached_fw)) {
mpt_free_fw_memory(ioc->alt_ioc, 0);
ioc->alt_ioc->cached_fw = fwmem;
ioc->alt_ioc->alloc_total += alloc_sz;
}
/* Update IOCFactsReply
*/
ioc->facts.FWImageSize = newFwSize;
if (ioc->alt_ioc)
ioc->alt_ioc->facts.FWImageSize = newFwSize;
return 0;
}
......@@ -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.
*/
if ((mf = mpt_get_msg_frame(mptctl_id, ioc->id)) == NULL)
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
return -EAGAIN;
hdr = (MPIHeader_t *) mf;
......@@ -2214,7 +2203,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
add_timer(&ioc->ioctl->timer);
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);
if (rc == 0) {
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)
del_timer(&ioc->ioctl->timer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
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 {
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);
}
......@@ -2342,7 +2331,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
* otherwise, failure occured after mf acquired.
*/
if (mf)
mpt_free_msg_frame(mptctl_id, ioc->id, mf);
mpt_free_msg_frame(mptctl_id, ioc, mf);
return rc;
}
......
......@@ -502,7 +502,7 @@ mpt_lan_reset(struct net_device *dev)
LANResetRequest_t *pResetReq;
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) {
/* dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
......@@ -520,7 +520,7 @@ mpt_lan_reset(struct net_device *dev)
pResetReq->MsgFlags = 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;
}
......@@ -754,7 +754,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
return 1;
}
mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
mf = mpt_get_msg_frame(LanCtx, mpt_dev);
if (mf == NULL) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&priv->txfidx_lock, flags);
......@@ -859,7 +859,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
else
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;
dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n",
......@@ -1244,7 +1244,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
(MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t));
while (buckets) {
mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
mf = mpt_get_msg_frame(LanCtx, mpt_dev);
if (mf == NULL) {
printk (KERN_ERR "%s: Unable to alloc request frame\n",
__FUNCTION__);
......@@ -1334,7 +1334,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
if (pSimple == NULL) {
/**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n",
/**/ __FUNCTION__);
mpt_free_msg_frame(LanCtx, mpt_dev->id, mf);
mpt_free_msg_frame(LanCtx, mpt_dev, mf);
goto out;
}
......@@ -1348,7 +1348,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
* printk ("\n");
*/
mpt_put_msg_frame(LanCtx, mpt_dev->id, mf);
mpt_put_msg_frame(LanCtx, mpt_dev, mf);
priv->total_posted += i;
buckets -= i;
......@@ -1489,7 +1489,7 @@ static int __init mpt_lan_init (void)
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++) {
printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
p->name,
......
This diff is collapsed.
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