Commit a1ac7138 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] mpt fusion update from vendor

parent 846ca6b2
......@@ -49,7 +49,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptbase.c,v 1.122 2002/10/03 13:10:11 pdelaney Exp $
* $Id: mptbase.c,v 1.123 2002/10/17 20:15:56 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -1156,7 +1156,7 @@ mpt_pci_scan(void)
dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n"));
/*
* NOTE: The 929, 929X and 1030 will appear as 2 separate PCI devices,
* NOTE: The 929, 929X, 1030 and 1035 will appear as 2 separate PCI devices,
* one for each channel.
*/
pci_for_each_dev(pdev) {
......@@ -1170,18 +1170,14 @@ mpt_pci_scan(void)
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
#if 0
/* FIXME! C103x family */
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1035) &&
#endif
(pdev->device != MPI_MANUFACTPAGE_DEVID_1030_53C1035) &&
1) {
dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device));
continue;
}
/* GRRRRR
* dual function devices (929, 929X, 1030) may be presented in Func 1,0 order,
* dual function devices (929, 929X, 1030, 1035) may be presented in Func 1,0 order,
* but we'd really really rather have them in Func 0,1 order.
* Do some kind of look ahead here...
*/
......@@ -1445,15 +1441,24 @@ mpt_adapter_install(struct pci_dev *pdev)
ioc->chip_type = C1030;
ioc->prod_name = "LSI53C1030";
{
u8 revision;
/* 1030 Chip Fix. Disable Split transactions
* for PCIX. Set bits 4 - 6 to zero.
* for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8)
*/
u16 pcixcmd = 0;
pci_read_config_word(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0xFF8F;
pci_write_config_word(pdev, 0x6a, pcixcmd);
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
if (revision < 0x08) {
u16 pcixcmd = 0;
pci_read_config_word(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0xFF8F;
pci_write_config_word(pdev, 0x6a, pcixcmd);
}
}
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
ioc->chip_type = C1035;
ioc->prod_name = "LSI53C1035";
}
sprintf(ioc->name, "ioc%d", ioc->id);
......@@ -1500,9 +1505,10 @@ mpt_adapter_install(struct pci_dev *pdev)
mpt_adapters[ioc->id] = ioc;
/* NEW! 20010220 -sralston
* Check for "bound ports" (929, 929X, 1030) to reduce redundant resets.
* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
*/
if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030) || (ioc->chip_type == FC929X))
if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030)
|| (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))
mpt_detect_bound_ports(ioc, pdev);
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
......@@ -1746,7 +1752,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/*
* mpt_detect_bound_ports - Search for PCI bus/dev_function
* which matches PCI bus/dev_function (+/-1) for newly discovered 929,
* 929X or 1030.
* 929X, 1030 or 1035.
* @ioc: Pointer to MPT adapter structure
* @pdev: Pointer to (struct pci_dev) structure
*
......@@ -1806,8 +1812,7 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
/* Disable the FW */
state = mpt_GetIocState(this, 1);
if (state == MPI_IOC_STATE_OPERATIONAL) {
if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP) != 0)
(void) KickStart(this, 1, NO_SLEEP);
SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP);
}
if (this->cached_fw != NULL) {
......@@ -1819,7 +1824,6 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
}
}
/* Disable adapter interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
this->active = 0;
......@@ -2291,9 +2295,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
ioc->reply_sz = ioc->req_sz;
ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
/* 1030 - should we use a smaller DEFAULT_REPLY_DEPTH?
* FIX
*/
dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
ioc->name, ioc->reply_sz, ioc->reply_depth));
dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
......@@ -2891,6 +2892,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
*/
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
while ((diag0val & MPI_DIAG_DRWE) == 0) {
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
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);
......@@ -3126,6 +3128,18 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
int cnt = 0;
dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
if ((int)ioc->chip_type > (int)FC929) {
/* Always issue a Msg Unit Reset first. This will clear some
* SCSI bus hang conditions.
*/
SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
if (sleepFlag == CAN_SLEEP) {
schedule_timeout(HZ);
} else {
mdelay (1000);
}
}
hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
if (hard_reset_done < 0)
......@@ -5841,6 +5855,15 @@ fusion_exit(void)
while (! Q_IS_EMPTY(&MptAdapters)) {
this = MptAdapters.head;
/* Disable interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
this->active = 0;
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&this->chip->IntStatus, 0);
Q_DEL_ITEM(this);
mpt_adapter_dispose(this);
}
......
......@@ -13,7 +13,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptbase.h,v 1.134 2002/10/03 13:10:12 pdelaney Exp $
* $Id: mptbase.h,v 1.136 2002/10/21 13:51:54 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -80,8 +80,8 @@
#define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "2.02.01.07"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.02.01.07"
#define MPT_LINUX_VERSION_COMMON "2.03.00.02"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.03.00.02"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......@@ -301,6 +301,7 @@ typedef enum {
FC919 = 0x0919,
FC929 = 0x0929,
C1030 = 0x1030,
C1035 = 0x1035,
FCUNK = 0xFBAD
} CHIP_TYPE;
......@@ -368,6 +369,7 @@ typedef struct _ScsiCmndTracker {
typedef struct _VirtDevice {
struct _VirtDevice *forw;
struct _VirtDevice *back;
struct scsi_device *device;
rwlock_t VdevLock;
int ref_cnt;
u8 tflags;
......@@ -912,6 +914,10 @@ typedef struct _MPT_SCSI_HOST {
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt;
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
unsigned long hard_resets; /* driver forced bus resets count */
unsigned long soft_resets; /* fw/external bus resets count */
unsigned long timeouts; /* cmd timeouts */
ushort sel_timeout[MPT_MAX_FC_DEVICES];
} MPT_SCSI_HOST;
/*
......
......@@ -34,7 +34,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptctl.c,v 1.60 2002/10/03 13:10:13 pdelaney Exp $
* $Id: mptctl.c,v 1.61 2002/10/17 20:15:57 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -136,14 +136,8 @@ static int mptctl_eventreport (unsigned long arg);
static int mptctl_replace_fw (unsigned long arg);
static int mptctl_do_reset(unsigned long arg);
static int mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int mptctl_cpq_getpciinfo(unsigned long arg);
static int mptctl_cpq_getdriver(unsigned long arg);
static int mptctl_cpq_ctlr_status(unsigned long arg);
static int mptctl_cpq_target_address(unsigned long arg);
static int mptctl_cpq_passthru(unsigned long arg);
static int mptctl_compaq_scsiio(VENDOR_IOCTL_REQ *pVenReq, cpqfc_passthru_t *pPass);
static int mptctl_hp_hostinfo(unsigned long arg);
static int mptctl_hp_targetinfo(unsigned long arg);
/*
* Private function calls.
......@@ -415,7 +409,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
/* Send request
*/
if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc->id)) == NULL) {
dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
ioctl->ioc->name));
mptctl_free_tm_flags(ioctl->ioc);
......@@ -623,21 +617,13 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
}
ret = -ENXIO; /* (-6) No such device or address */
/* Test for Compaq-specific IOCTL's.
*/
if ((cmd == CPQFCTS_GETPCIINFO) || (cmd == CPQFCTS_CTLR_STATUS) ||
(cmd == CPQFCTS_GETDRIVVER) || (cmd == CPQFCTS_SCSI_PASSTHRU) ||
(cmd == CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS))
return mptctl_compaq_ioctl(file, cmd, arg);
/* Verify intended MPT adapter - set iocnum and the adapter
* pointer (iocp)
*/
iocnumX = khdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnumX));
return -ENODEV;
}
......@@ -683,6 +669,12 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case MPTHARDRESET:
ret = mptctl_do_reset(arg);
break;
case HP_GETHOSTINFO:
ret = mptctl_hp_hostinfo(arg);
break;
case HP_GETTARGETINFO:
ret = mptctl_hp_targetinfo(arg);
break;
default:
ret = -EINVAL;
}
......@@ -708,7 +700,7 @@ static int mptctl_do_reset(unsigned long arg)
}
if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
dtmprintk((KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
__FILE__, __LINE__, krinfo.hdr.iocnum));
return -ENODEV; /* (-6) No such device or address */
}
......@@ -816,7 +808,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc));
if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) {
dtmprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
__FILE__, __LINE__, ioc));
return -ENODEV; /* (-6) No such device or address */
}
......@@ -1252,7 +1244,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1379,7 +1371,7 @@ mptctl_gettargetinfo (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1510,7 +1502,7 @@ mptctl_readtest (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1568,7 +1560,7 @@ mptctl_eventquery (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1606,7 +1598,7 @@ mptctl_eventenable (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1654,7 +1646,7 @@ mptctl_eventreport (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1708,7 +1700,7 @@ mptctl_replace_fw (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1794,7 +1786,7 @@ mptctl_mpt_command (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1842,7 +1834,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
......@@ -1926,6 +1918,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
int target = (int) pScsiReq->TargetID;
int dataSize;
if ((target < 0) || (target >= ioc->sh->max_id)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Target ID out of bounds. \n",
__FILE__, __LINE__);
rc = -ENODEV;
goto done_free_mem;
}
pScsiReq->MsgFlags = mpt_msg_flags();
/* verify that app has not requested
......@@ -2049,9 +2049,37 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
}
break;
case MPI_FUNCTION_IOC_INIT:
{
IOCInit_t *pInit = (IOCInit_t *) mf;
u32 high_addr, sense_high;
/* Verify that all entries in the IOC INIT match
* existing setup (and in LE format).
*/
if (sizeof(dma_addr_t) == sizeof(u64)) {
high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
} else {
high_addr = 0;
sense_high= 0;
}
if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
(pInit->MaxBuses != ioc->facts.MaxBuses) ||
(pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
(pInit->HostMfaHighAddr != high_addr) ||
(pInit->SenseBufferHighAddr != sense_high)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
__FILE__, __LINE__);
rc = -EFAULT;
goto done_free_mem;
}
}
break;
default:
/*
* MPI_FUNCTION_IOC_INIT
* MPI_FUNCTION_PORT_ENABLE
* MPI_FUNCTION_TARGET_CMD_BUFFER_POST
* MPI_FUNCTION_TARGET_ASSIST
......@@ -2357,131 +2385,85 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Routine for the Compaq IOCTL commands.
/* Prototype Routine for the HP HOST INFO command.
*
* Outputs: None.
* Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter
* -ETIME if timer expires
* -ENOMEM if memory allocation error
*/
static int
mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int iocnum = 0;
unsigned iocnumX = 0;
int ret;
int nonblock = (file->f_flags & O_NONBLOCK);
MPT_ADAPTER *iocp = NULL;
if (cmd == CPQFCTS_SCSI_PASSTHRU) {
/* Update the iocnum */
if (copy_from_user(&iocnumX, (int *)arg, sizeof(int))) {
printk(KERN_ERR "%s::mptctl_compaq_ioctl() @%d - "
"Unable to read controller number @ %p\n",
__FILE__, __LINE__, (void*)arg);
return -EFAULT;
}
iocnumX &= 0xFF;
}
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_compaq_ioctl() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnumX));
return -ENODEV;
}
/* All of these commands require an interrupt or
* are unknown/illegal.
*/
if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
return ret;
dctlprintk((MYIOC_s_INFO_FMT ": mptctl_compaq_ioctl()\n", iocp->name));
switch(cmd) {
case CPQFCTS_GETPCIINFO:
ret = mptctl_cpq_getpciinfo(arg);
break;
case CPQFCTS_GETDRIVVER:
ret = mptctl_cpq_getdriver(arg);
break;
case CPQFCTS_CTLR_STATUS:
ret = mptctl_cpq_ctlr_status(arg);
break;
case CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS:
ret = mptctl_cpq_target_address(arg);
break;
case CPQFCTS_SCSI_PASSTHRU:
ret = mptctl_cpq_passthru(arg);
break;
default:
ret = -EINVAL;
}
up(&mptctl_syscall_sem_ioc[iocp->id]);
return ret;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_cpq_getpciinfo - Get PCI Information in format desired by Compaq
*
* Outputs: None.
* Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter
* -ETIME if timer expires
* -ENOMEM if memory allocation error
*/
static int
mptctl_cpq_getpciinfo(unsigned long arg)
mptctl_hp_hostinfo(unsigned long arg)
{
cpqfc_pci_info_struct *uarg = (cpqfc_pci_info_struct *) arg;
cpqfc_pci_info_struct karg;
hp_host_info_t *uarg = (hp_host_info_t *) arg;
MPT_ADAPTER *ioc;
struct pci_dev *pdev;
char *pbuf;
dma_addr_t buf_dma;
hp_host_info_t karg;
CONFIGPARMS cfg;
ConfigPageHeader_t hdr;
int iocnum = 0, iocnumX = 0;
dma_addr_t buf_dma;
u8 *pbuf = NULL;
int failed;
int iocnum;
int rc;
dctlprintk((": mptctl_cpq_pciinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(cpqfc_pci_info_struct))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - "
"Unable to read in cpqfc_pci_info_struct @ %p\n",
dctlprintk((": mptctl_hp_hostinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
"Unable to read in hp_host_info struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EINVAL;
return -EFAULT;
}
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_pciinfo() @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
/* Fill in the data and return the structure to the calling
* program
*/
pdev = (struct pci_dev *) ioc->pcidev;
/* Populate the structure. */
karg.bus = pdev->bus->number;
karg.bus_type = 1; /* 1 = PCI; 4 = unknown */
karg.device_fn = PCI_FUNC(pdev->devfn);
karg.slot_number = PCI_SLOT(pdev->devfn);
karg.vendor_id = pdev->vendor;
karg.device_id = pdev->device;
karg.board_id = (karg.device_id | (karg.vendor_id << 16));
karg.class_code = pdev->class;
karg.vendor = pdev->vendor;
karg.device = pdev->device;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
karg.sub_vendor_id = pdev->subsystem_vendor;
karg.sub_device_id = pdev->subsystem_device;
karg.subsystem_id = pdev->subsystem_device;
karg.subsystem_vendor = pdev->subsystem_vendor;
#endif
karg.devfn = pdev->devfn;
karg.bus = pdev->bus->number;
/* Save the SCSI host no. if
* SCSI driver loaded
*/
if (ioc->sh != NULL)
karg.host_no = ioc->sh->host_no;
else
karg.host_no = -1;
/* Reformat the fw_version into a string
*/
karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
karg.fw_version[2] = '.';
karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
karg.fw_version[5] = '.';
karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
karg.fw_version[8] = '.';
karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
karg.fw_version[11] = '\0';
/* Issue a config request to get the device serial number
*/
......@@ -2496,8 +2478,7 @@ mptctl_cpq_getpciinfo(unsigned long arg)
cfg.dir = 0; /* read */
cfg.timeout = 10;
failed = 1;
strncpy(karg.serial_number, " ", 24);
if (mpt_config(ioc, &cfg) == 0) {
if (cfg.hdr->PageLength > 0) {
/* Issue the second config page request */
......@@ -2508,242 +2489,207 @@ mptctl_cpq_getpciinfo(unsigned long arg)
cfg.physAddr = buf_dma;
if (mpt_config(ioc, &cfg) == 0) {
ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
strncpy(karg.serial_number, pdata->BoardTracerNumber, 17);
failed = 0;
if (strlen(pdata->BoardTracerNumber) > 1)
strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
}
pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
pbuf = NULL;
}
}
}
if (failed)
strncpy(karg.serial_number, " ", 17);
/* Copy the data from kernel memory to user memory
*/
if (copy_to_user((char *)arg, &karg,
sizeof(cpqfc_pci_info_struct))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - "
"Unable to write out cpqfc_pci_info_struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
rc = mpt_GetIocState(ioc, 1);
switch (rc) {
case MPI_IOC_STATE_OPERATIONAL:
karg.ioc_status = HP_STATUS_OK;
break;
return 0;
}
case MPI_IOC_STATE_FAULT:
karg.ioc_status = HP_STATUS_FAILED;
break;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_cpq_getdriver - Get Driver Version in format desired by Compaq
*
* Outputs: None.
* Return: 0 if successful
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter
*/
static int
mptctl_cpq_getdriver(unsigned long arg)
{
int *uarg = (int *)arg;
int karg;
MPT_ADAPTER *ioc = NULL;
int iocnum = 0, iocnumX = 0;
int ii, jj;
char version[10];
char val;
char *vptr = NULL;
char *pptr = NULL;
dctlprintk((": mptctl_cpq_getdriver called.\n"));
if (copy_from_user(&karg, uarg, sizeof(int))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - "
"Unable to read in struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
case MPI_IOC_STATE_RESET:
case MPI_IOC_STATE_READY:
default:
karg.ioc_status = HP_STATUS_OTHER;
break;
}
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_getdriver() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
strncpy(version, MPT_LINUX_VERSION_COMMON, 8);
karg = 0;
vptr = version;
ii = 3;
while (ii > 0) {
pptr = strchr(vptr, '.');
if (pptr) {
*pptr = '\0';
val = 0;
for (jj=0; vptr[jj]>='0' && vptr[jj]<='9'; jj++)
val = 10 * val + (vptr[jj] - '0');
karg |= (val << (8*ii));
pptr++;
vptr = pptr;
} else
break;
ii--;
if ((int)ioc->chip_type <= (int) FC929)
karg.bus_phys_width = HP_BUS_WIDTH_UNK;
else
karg.bus_phys_width = HP_BUS_WIDTH_16;
karg.hard_resets = 0;
karg.soft_resets = 0;
karg.timeouts = 0;
if (ioc->sh != NULL) {
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
if (hd) {
karg.hard_resets = hd->hard_resets;
karg.soft_resets = hd->soft_resets;
karg.timeouts = hd->timeouts;
}
}
/* Copy the data from kernel memory to user memory
*/
if (copy_to_user((char *)arg, &karg,
sizeof(int))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - "
"Unable to write out stuct @ %p\n",
sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
"Unable to write out hp_host_info @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_cpq_ctlr_status - Get controller status in format desired by Compaq
/* Prototype Routine for the HP TARGET INFO command.
*
* Outputs: None.
* Return: 0 if successful
* -EFAULT if data unavailable
* -EBUSY if previous command timout and IOC reset is not complete.
* -ENODEV if no such device/adapter
* -ETIME if timer expires
* -ENOMEM if memory allocation error
*/
static int
mptctl_cpq_ctlr_status(unsigned long arg)
mptctl_hp_targetinfo(unsigned long arg)
{
cpqfc_ctlr_status *uarg = (cpqfc_ctlr_status *) arg;
cpqfc_ctlr_status karg;
hp_target_info_t *uarg = (hp_target_info_t *) arg;
SCSIDevicePage0_t *pg0_alloc;
SCSIDevicePage3_t *pg3_alloc;
MPT_ADAPTER *ioc;
int iocnum = 0, iocnumX = 0;
MPT_SCSI_HOST *hd = NULL;
hp_target_info_t karg;
int iocnum;
int data_sz;
dma_addr_t page_dma;
CONFIGPARMS cfg;
ConfigPageHeader_t hdr;
int tmp, np, rc = 0;
dctlprintk((": mptctl_cpq_pciinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(cpqfc_ctlr_status))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - "
"Unable to read in cpqfc_ctlr_status @ %p\n",
dctlprintk((": mptctl_hp_targetinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
"Unable to read in hp_host_targetinfo struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_ctlr_status() @%d - ioc%d not found!\n",
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
karg.status = ioc->last_state;
karg.offline_reason = 0;
/* Copy the data from kernel memory to user memory
/* There is nothing to do for FCP parts.
*/
if (copy_to_user((char *)arg, &karg,
sizeof(cpqfc_ctlr_status))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - "
"Unable to write out cpqfc_ctlr_status @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
return 0;
}
if ((int) ioc->chip_type <= (int) FC929)
return 0;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_cpq_target_address - Get WWN Information in format desired by Compaq
*
* Outputs: None.
* Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter
* -ETIME if timer expires
*/
static int
mptctl_cpq_target_address(unsigned long arg)
{
Scsi_FCTargAddress *uarg = (Scsi_FCTargAddress *) arg;
Scsi_FCTargAddress karg;
MPT_ADAPTER *ioc;
int iocnum = 0, iocnumX = 0;
CONFIGPARMS cfg;
ConfigPageHeader_t hdr;
dma_addr_t buf_dma;
u8 *pbuf = NULL;
FCPortPage0_t *ppp0;
int ii, failed;
u32 low, high;
dctlprintk((": mptctl_cpq_target_address called.\n"));
if (copy_from_user(&karg, uarg, sizeof(Scsi_FCTargAddress))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - "
"Unable to read in Scsi_FCTargAddress @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
return 0;
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_target_address() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
if (ioc->sh->host_no != karg.hdr.host)
return -ENODEV;
/* Get the data transfer speeds
*/
data_sz = ioc->spi_data.sdp0length * 4;
pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
if (pg0_alloc) {
hdr.PageVersion = ioc->spi_data.sdp0version;
hdr.PageLength = data_sz;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &hdr;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
cfg.timeout = 0;
cfg.physAddr = page_dma;
cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
if ((rc = mpt_config(ioc, &cfg)) == 0) {
np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
if (tmp < 0x09)
karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
else if (tmp <= 0x09)
karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
else if (tmp <= 0x0A)
karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
else if (tmp <= 0x0C)
karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
else if (tmp <= 0x25)
karg.negotiated_speed = HP_DEV_SPEED_FAST;
else
karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
} else
karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
}
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
}
karg.host_port_id = 0;
/* Set defaults
*/
karg.message_rejects = -1;
karg.phase_errors = -1;
karg.parity_errors = -1;
karg.select_timeouts = -1;
/* Issue a config request to get the device wwn
/* Get the target error parameters
*/
hdr.PageVersion = 0;
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
hdr.PageNumber = 3;
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &hdr;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0; /* read */
cfg.timeout = 10;
failed = 1;
if (mpt_config(ioc, &cfg) == 0) {
if (cfg.hdr->PageLength > 0) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
if (pbuf) {
cfg.physAddr = buf_dma;
if (mpt_config(ioc, &cfg) == 0) {
ppp0 = (FCPortPage0_t *) pbuf;
low = le32_to_cpu(ppp0->WWNN.Low);
high = le32_to_cpu(ppp0->WWNN.High);
for (ii = 0; ii < 4; ii++) {
karg.host_wwn[7-ii] = low & 0xFF;
karg.host_wwn[3-ii] = high & 0xFF;
low = (low >> 8);
high = (high >> 8);
}
failed = 0;
}
pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
pbuf = NULL;
cfg.dir = 0;
cfg.timeout = 0;
cfg.physAddr = -1;
if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
data_sz = (int) cfg.hdr->PageLength * 4;
pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
ioc->pcidev, data_sz, &page_dma);
if (pg3_alloc) {
cfg.physAddr = page_dma;
cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
if ((rc = mpt_config(ioc, &cfg)) == 0) {
karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
}
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
}
}
if (failed) {
for (ii = 7; ii >= 0; ii--)
karg.host_wwn[ii] = 0;
}
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
if (hd != NULL)
karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
/* Copy the data from kernel memory to user memory
*/
if (copy_to_user((char *)arg, &karg,
sizeof(Scsi_FCTargAddress))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - "
"Unable to write out Scsi_FCTargAddress @ %p\n",
if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
......@@ -2751,161 +2697,6 @@ mptctl_cpq_target_address(unsigned long arg)
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_cpq_passthru - Construct and issue a SCSI IO Passthru
*
* Requires the SCSI host driver to be loaded.
* I386 version.
*
* Outputs: None.
* Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter
* -ETIME if timer expires
*/
static int
mptctl_cpq_passthru(unsigned long arg)
{
VENDOR_IOCTL_REQ *uarg = (VENDOR_IOCTL_REQ *) arg;
VENDOR_IOCTL_REQ karg;
cpqfc_passthru_t kpass;
MPT_ADAPTER *ioc;
int iocnum = 0, iocnumX = 0;
int rc;
dctlprintk((": mptctl_cpq_passthru called.\n"));
if (copy_from_user(&karg, uarg, sizeof(VENDOR_IOCTL_REQ))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_passthru - "
"Unable to read in VENDOR_IOCTL_REQ @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
/* Set the IOC number */
iocnumX = karg.lc & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_passthru() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
if (ioc->sh == NULL) {
printk(KERN_ERR "%s::mptctl_cpq_passthru() @%d - SCSI Host driver not loaded!\n",
__FILE__, __LINE__);
return -EFAULT;
}
/* Read in the second buffer */
if (copy_from_user(&kpass, uarg->argp, sizeof(cpqfc_passthru_t))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_passthru - "
"Unable to read in cpqfc_passthru_t @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
/* Generate the SCSI IO command and issue */
rc = mptctl_compaq_scsiio(&karg, &kpass);
return rc;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_compaq_scsiio - Reformat Compaq structures into driver structures
* Call the generic _do_mpt_command function.
*
* Requires the SCSI host driver to be loaded.
* I386 version.
*
* Outputs: None.
* Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter
* -ETIME if timer expires
*/
static int
mptctl_compaq_scsiio(VENDOR_IOCTL_REQ *pVenReq, cpqfc_passthru_t *pPass)
{
struct mpt_ioctl_command karg;
SCSIIORequest_t request ;
SCSIIORequest_t *pMf;
int ii, rc;
u8 opcode;
/* Fill in parameters to karg */
karg.hdr.iocnum = pVenReq->lc;
karg.hdr.port = 0;
karg.hdr.maxDataSize = 0; /* not used */
karg.timeout = 0; /* use default */
karg.replyFrameBufPtr = NULL; /* no reply data */
karg.maxReplyBytes = 0;
karg.senseDataPtr = pPass->sense_data;
karg.maxSenseBytes = pPass->sense_len; /* max is 40 */
if (pPass->rw_flag == MPT_COMPAQ_WRITE) {
karg.dataOutBufPtr = pPass->bufp;
karg.dataOutSize = pPass->len;
karg.dataInBufPtr = NULL;
karg.dataInSize = 0;
} else {
karg.dataInBufPtr = pPass->bufp;
karg.dataInSize = pPass->len;
karg.dataOutBufPtr = NULL;
karg.dataOutSize = 0;
}
karg.dataSgeOffset = (sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION))/4;
/* Construct the Message frame */
pMf = &request;
pMf->TargetID = (u8) pVenReq->ld; /* ???? FIXME */
pMf->Bus = (u8) pPass->bus;
pMf->ChainOffset = 0;
pMf->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
/* May need some tweaking here */
opcode = (u8) pPass->cdb[0];
if (opcode < 0x20)
pMf->CDBLength = 6;
else if (opcode < 0x60)
pMf->CDBLength = 10;
else if ((opcode < 0xC0) && (opcode >= 0xA0))
pMf->CDBLength = 12;
else
pMf->CDBLength = 16;
pMf->SenseBufferLength = karg.maxSenseBytes; /* max is 40 */
pMf->Reserved = 0;
pMf->MsgFlags = 0; /* set later */
pMf->MsgContext = 0; /* set later */
for (ii = 0; ii < 8; ii++)
pMf->LUN[ii] = 0;
pMf->LUN[1] = 0; /* ???? FIXME */
/* Tag values set by _do_mpt_command */
if (pPass->rw_flag == MPT_COMPAQ_WRITE)
pMf->Control = MPI_SCSIIO_CONTROL_WRITE;
else
pMf->Control = MPI_SCSIIO_CONTROL_READ;
for (ii = 0; ii < 16; ii++)
pMf->CDB[ii] = pPass->cdb[ii];
pMf->DataLength = pPass->len;
/* All remaining fields are set by the next function
*/
rc = mptctl_do_mpt_command (karg, (char *)pMf, 1);
return rc;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
......@@ -2971,7 +2762,7 @@ sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
iocnumX = kfw32.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
dtmprintk((KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
__LINE__, iocnumX));
return -ENODEV;
}
......@@ -3011,7 +2802,7 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd,
iocnumX = karg32.hdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
dtmprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
dctlprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
__LINE__, iocnumX));
return -ENODEV;
}
......@@ -3044,70 +2835,6 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd,
return ret;
}
static int
sparc32_mptctl_cpq_passthru(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *filp)
{
VENDOR_IOCTL_REQ32 *uarg = (VENDOR_IOCTL_REQ32 *) arg;
VENDOR_IOCTL_REQ32 karg32;
VENDOR_IOCTL_REQ karg;
cpqfc_passthru32_t kpass32;
cpqfc_passthru_t kpass;
MPT_ADAPTER *ioc;
int nonblock = (filp->f_flags & O_NONBLOCK);
int iocnum = 0, iocnumX = 0;
int rc;
int ii;
dctlprintk((KERN_INFO MYNAM "::sparc32_mptctl_cpq_passthru() called\n"));
if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
return -EFAULT;
/* Verify intended MPT adapter */
iocnumX = karg32.lc & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
(ioc == NULL)) {
dtmprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
__LINE__, iocnumX));
return -ENODEV;
}
if ((rc = mptctl_syscall_down(ioc, nonblock)) != 0)
return rc;
/* Copy data to karg */
karg.ld = karg32.ld;
karg.node = karg32.node;
karg.lc = karg32.lc;
karg.nexus = karg32.nexus;
karg.argp = (void *)(unsigned long)karg32.argp;
/* Read in the second buffer */
if (copy_from_user(&kpass32, karg.argp, sizeof(cpqfc_passthru32_t))) {
printk(KERN_ERR "%s@%d::sparc32_mptctl_cpq_passthru - "
"Unable to read in cpqfc_passthru_t @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
/* Copy the 32bit buffer to kpass */
for (ii = 0; ii < 16; ii++)
kpass.cdb[ii] = kpass32.cdb[ii];
kpass.bus = kpass32.bus;
kpass.pdrive = kpass32.pdrive;
kpass.len = kpass32.len;
kpass.sense_len = kpass32.sense_len;
kpass.bufp = (void *)(unsigned long)kpass32.bufp;
kpass.rw_flag = kpass32.rw_flag;
/* Generate the SCSI IO command and issue */
rc = mptctl_compaq_scsiio(&karg, &kpass);
up(&mptctl_syscall_sem_ioc[ioc->id]);
return rc;
}
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
......@@ -3176,15 +2903,9 @@ int __init mptctl_init(void)
err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
sparc32_mptfwxfer_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(CPQFCTS_GETPCIINFO, NULL);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(CPQFCTS_CTLR_STATUS, NULL);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(CPQFCTS_GETDRIVVER, NULL);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS, NULL);
err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32, sparc32_mptctl_cpq_passthru);
err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL);
if (++where && err) goto out_fail;
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
......@@ -3233,11 +2954,8 @@ int __init mptctl_init(void)
unregister_ioctl32_conversion(MPTHARDRESET);
unregister_ioctl32_conversion(MPTCOMMAND32);
unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
unregister_ioctl32_conversion(CPQFCTS_GETPCIINFO);
unregister_ioctl32_conversion(CPQFCTS_GETDRIVVER);
unregister_ioctl32_conversion(CPQFCTS_CTLR_STATUS);
unregister_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS);
unregister_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32);
unregister_ioctl32_conversion(HP_GETHOSTINFO);
unregister_ioctl32_conversion(HP_GETTARGETINFO);
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
......
......@@ -20,7 +20,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptctl.h,v 1.11 2002/10/03 13:10:13 pdelaney Exp $
* $Id: mptctl.h,v 1.12 2002/10/17 20:15:58 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -310,95 +310,91 @@ struct mpt_ioctl_command32 {
#endif /*}*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* COMPAQ Specific IOCTL Defines and Structures
*/
/*
* HP Specific IOCTL Defines and Structures
*/
#define CPQFCTS_IOC_MAGIC 'Z'
#define HP_IOC_MAGIC 'Z'
#define HP_GETHOSTINFO _IOR(HP_IOC_MAGIC, 20, hp_host_info_t)
#define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
#define CPQFCTS_GETPCIINFO _IOR(CPQFCTS_IOC_MAGIC, 1, cpqfc_pci_info_struct)
#define CPQFCTS_GETDRIVVER _IOR(CPQFCTS_IOC_MAGIC, 9, int)
#define CPQFCTS_CTLR_STATUS _IOR(CPQFCTS_IOC_MAGIC, 3, struct _cpqfc_ctlr_status)
#define CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS _IOR(CPQFCTS_IOC_MAGIC, 13, struct scsi_fctargaddress)
#define CPQFCTS_SCSI_PASSTHRU _IOWR(CPQFCTS_IOC_MAGIC, 11, VENDOR_IOCTL_REQ)
#if defined(__sparc__) && defined(__sparc_v9__)
#define CPQFCTS_SCSI_PASSTHRU32 _IOWR(CPQFCTS_IOC_MAGIC, 11, VENDOR_IOCTL_REQ32)
#endif
typedef struct {
unsigned short bus;
unsigned short bus_type;
unsigned short device_fn;
u32 board_id;
u32 slot_number;
unsigned short vendor_id;
unsigned short device_id;
unsigned short class_code;
unsigned short sub_vendor_id;
unsigned short sub_device_id;
u8 serial_number[81];
} cpqfc_pci_info_struct;
typedef struct scsi_fctargaddress {
unsigned int host_port_id;
u8 host_wwn[8]; /* WW Network Name */
} Scsi_FCTargAddress;
typedef struct _cpqfc_ctlr_status {
u32 status;
u32 offline_reason;
} cpqfc_ctlr_status;
/* Compaq SCSI I/O Passthru structures.
/* All HP IOCTLs must include this header
*/
#define MPT_COMPAQ_READ 0x26
#define MPT_COMPAQ_WRITE 0x27
typedef struct {
int lc; /* controller number */
int node; /* node number */
int ld; /* target logical id */
u32 nexus;
void *argp;
} VENDOR_IOCTL_REQ;
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
typedef struct {
int lc; /* controller number */
int node; /* node number */
int ld; /* target logical id */
u32 nexus;
u32 argp;
} VENDOR_IOCTL_REQ32;
#endif
typedef struct {
char cdb[16]; /* cdb */
unsigned short bus; /* bus number */
unsigned short pdrive; /* physical drive */
int len; /* data area size */
int sense_len; /* sense size */
char sense_data[40]; /* sense buffer */
void *bufp; /* data buffer pointer */
char rw_flag;
} cpqfc_passthru_t;
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
typedef struct {
char cdb[16]; /* cdb */
unsigned short bus; /* bus number */
unsigned short pdrive; /* physical drive */
int len; /* data area size */
int sense_len; /* sense size */
char sense_data[40]; /* sense buffer */
u32 bufp; /* data buffer pointer */
char rw_flag;
} cpqfc_passthru32_t;
#endif
typedef struct _hp_header {
unsigned int iocnum;
unsigned int host;
unsigned int channel;
unsigned int id;
unsigned int lun;
} hp_header_t;
/*
* Header:
* iocnum required (input)
* host ignored
* channe ignored
* id ignored
* lun ignored
*/
typedef struct _hp_host_info {
hp_header_t hdr;
u16 vendor;
u16 device;
u16 subsystem_vendor;
u16 subsystem_id;
u8 devfn;
u8 bus;
ushort host_no; /* SCSI Host number, if scsi driver not loaded*/
u8 fw_version[16]; /* string */
u8 serial_number[24]; /* string */
u32 ioc_status;
u32 bus_phys_width;
u32 base_io_addr;
u32 rsvd;
unsigned long hard_resets; /* driver initiated resets */
unsigned long soft_resets; /* ioc, external resets */
unsigned long timeouts; /* num timeouts */
} hp_host_info_t;
/*
* Header:
* iocnum required (input)
* host required
* channel required (bus number)
* id required
* lun ignored
*
* All error values between 0 and 0xFFFF in size.
*/
typedef struct _hp_target_info {
hp_header_t hdr;
u32 parity_errors;
u32 phase_errors;
u32 select_timeouts;
u32 message_rejects;
u32 negotiated_speed;
u8 negotiated_width;
u8 rsvd[7]; /* 8 byte alignment */
} hp_target_info_t;
#define HP_STATUS_OTHER 1
#define HP_STATUS_OK 2
#define HP_STATUS_FAILED 3
#define HP_BUS_WIDTH_UNK 1
#define HP_BUS_WIDTH_8 2
#define HP_BUS_WIDTH_16 3
#define HP_BUS_WIDTH_32 4
#define HP_DEV_SPEED_ASYNC 2
#define HP_DEV_SPEED_FAST 3
#define HP_DEV_SPEED_ULTRA 4
#define HP_DEV_SPEED_ULTRA2 5
#define HP_DEV_SPEED_ULTRA160 6
#define HP_DEV_SPEED_SCSI1 7
#define HP_DEV_SPEED_ULTRA320 8
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......
......@@ -26,7 +26,7 @@
* Copyright (c) 2000-2002 LSI Logic Corporation
* Originally By: Noah Romer
*
* $Id: mptlan.c,v 1.52 2002/05/06 13:45:07 sshirron Exp $
* $Id: mptlan.c,v 1.53 2002/10/17 20:15:58 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......
......@@ -8,7 +8,6 @@
#include <linux/module.h>
#endif
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/errno.h>
// #include <linux/etherdevice.h>
......
......@@ -26,7 +26,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptscsih.c,v 1.102 2002/10/03 13:10:14 pdelaney Exp $
* $Id: mptscsih.c,v 1.103 2002/10/17 20:15:59 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -78,6 +78,9 @@
#include <linux/reboot.h> /* notifier code */
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
#include "../../scsi/sd.h"
#endif
#include "mptbase.h"
#include "mptscsih.h"
......@@ -198,7 +201,7 @@ static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
static void mptscsih_qas_check(MPT_SCSI_HOST *hd);
static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
......@@ -399,6 +402,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
/* Spoof to SCSI Selection Timeout! */
sc->result = DID_NO_CONNECT << 16;
if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
hd->sel_timeout[pScsiReq->TargetID]++;
break;
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
......@@ -1289,11 +1295,17 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
sh->max_sectors = MPT_SCSI_MAX_SECTORS;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) || defined CONFIG_HIGHIO
sh->highmem_io = 1;
#endif
sh->this_id = this->pfacts[portnum].PortSCSIID;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
/* OS entry to allow host drivers to force
* a queue depth on a per device basis.
*/
sh->select_queue_depths = mptscsih_select_queue_depths;
#endif
/* Required entry.
*/
sh->unique_id = this->id;
......@@ -2546,14 +2558,13 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
/* Isse the Task Mgmt request.
*/
if (hd->hard_resets < -1)
hd->hard_resets++;
rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag);
if (rc) {
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_ERROR;
#endif
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
} else {
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name);
dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
}
}
#ifdef DROP_TEST
......@@ -2681,7 +2692,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
unsigned long flags;
u32 ctx2abort;
int scpnt_idx;
......@@ -2696,10 +2706,11 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
hd->ioc->name, SCpnt);
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt, atomic_read(&queue_depth));
if (hd->timeouts < -1)
hd->timeouts++;
/* Find this command
*/
......@@ -2753,11 +2764,9 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
hd->abortSCpnt = SCpnt;
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->target, SCpnt->lun, ctx2abort, CAN_SLEEP)
< 0
|| hd->tmState == TM_STATE_ERROR) {
SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP)
< 0) {
/* The TM request failed and the subsequent FW-reload failed!
* Fatal error case.
......@@ -2765,14 +2774,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
hd->ioc->name, SCpnt);
/* If command not found, do not do callback,
* just return failed. CHECKME
*/
if (hd->ScsiLookup[scpnt_idx] != NULL) {
SCpnt->result = STS_BUSY;
SCpnt->scsi_done(SCpnt);
}
/* We must clear our pending flag before clearing our state.
*/
hd->tmPending = 0;
......@@ -2780,34 +2781,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED;
}
return FAILED;
/* Our task management request will either complete or time out. So we
* spin until tmPending is != 1. If tmState is set to TM_STATE_ERROR,
* we encountered an error executing the task management request.
*/
while (hd->tmPending == 1){
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/4);
}
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if (hd->tmState == TM_STATE_ERROR){
hd->tmState = TM_STATE_NONE;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"TM timeout error! (sc=%p)\n",
hd->ioc->name,
SCpnt));
return FAILED;
}
hd->tmState = TM_STATE_NONE;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"Abort was successful! (sc=%p)\n",
hd->ioc->name,
SCpnt));
return SUCCESS;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -2823,7 +2798,6 @@ int
mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
unsigned long flags;
/* If we can't locate our host adapter structure, return FAILED status.
*/
......@@ -2834,10 +2808,13 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt, atomic_read(&queue_depth));
/* Unsupported for SCSI. Suppored for FCP
*/
if (hd->is_spi)
return FAILED;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
......@@ -2853,7 +2830,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
}
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->target, 0, 0, CAN_SLEEP)
SCpnt->target, 0, 0, NO_SLEEP)
< 0){
/* The TM request failed and the subsequent FW-reload failed!
* Fatal error case.
......@@ -2864,34 +2841,8 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
hd->tmState = TM_STATE_NONE;
return FAILED;
}
/* Our task management request will either complete or time out. So we
* spin until tmPending is != 1. If tmState is set to TM_STATE_ERROR,
* we encountered an error executing the task management request.
*/
while (hd->tmPending == 1){
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/4);
}
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if (hd->tmState == TM_STATE_ERROR){
hd->tmState = TM_STATE_NONE;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: "
"TM timeout error! (sc=%p)\n",
hd->ioc->name,
SCpnt));
return FAILED;
}
hd->tmState = TM_STATE_NONE;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: "
"Device reset was successful! (sc=%p)\n",
hd->ioc->name,
SCpnt));
return SUCCESS;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -2907,7 +2858,6 @@ int
mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
unsigned long flags;
/* If we can't locate our host adapter structure, return FAILED status.
*/
......@@ -2918,10 +2868,11 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt, atomic_read(&queue_depth));
if (hd->timeouts < -1)
hd->timeouts++;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
......@@ -2932,13 +2883,13 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
"Timed out waiting for previous TM to complete! "
"(sc = %p)\n",
hd->ioc->name, SCpnt ) );
hd->ioc->name, SCpnt));
return FAILED;
}
/* We are now ready to execute the task management request. */
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
0, 0, 0, CAN_SLEEP)
0, 0, 0, NO_SLEEP)
< 0){
/* The TM request failed and the subsequent FW-reload failed!
......@@ -2952,32 +2903,6 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
/* Our task management request will either complete or time out. So we
* spin until tmPending is != 1. If tmState is set to TM_STATE_ERROR,
* we encountered an error executing the task management request.
*/
while (hd->tmPending == 1){
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/4);
}
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if (hd->tmState == TM_STATE_ERROR){
hd->tmState = TM_STATE_NONE;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
"TM timeout error! (sc=%p)\n",
hd->ioc->name,
SCpnt));
return FAILED;
}
hd->tmState = TM_STATE_NONE;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
"Bus reset was successful! (sc=%p)\n",
hd->ioc->name,
SCpnt));
return SUCCESS;
}
......@@ -3013,7 +2938,7 @@ mptscsih_host_reset(Scsi_Cmnd *SCpnt)
/* If our attempts to reset the host failed, then return a failed
* status. The host will be taken off line by the SCSI mid-layer.
*/
if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0){
status = FAILED;
} else {
/* Make sure TM pending is cleared and TM state is set to
......@@ -3056,9 +2981,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/4);
mdelay(250);
} while (--loop_count);
return status;
......@@ -3093,6 +3016,9 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt)
return SCSI_ABORT_NOT_RUNNING;
}
if (hd->timeouts < -1)
hd->timeouts++;
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
/* Cmd not found in ScsiLookup.
* If found in doneQ, delete from Q.
......@@ -3166,7 +3092,7 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt)
SCpnt->host_scribble = (u8 *) MPT_INDEX_2_MFPTR (hd->ioc, scpnt_idx);
/* For the time being, force bus reset on any abort
* requests for the 1030 FW.
* requests for the 1030/1035 FW.
*/
if (hd->is_spi)
mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
......@@ -3226,6 +3152,9 @@ mptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
return SCSI_RESET_SUCCESS;
}
if (hd->timeouts < -1)
hd->timeouts++;
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
/* Cmd not found in ScsiLookup.
* If found in doneQ, delete from Q.
......@@ -3583,9 +3512,6 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
}
}
}
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_ERROR;
#endif
} else {
dtmprintk((KERN_INFO " SCSI TaskMgmt SUCCESS!\n"));
......@@ -3629,6 +3555,9 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_NONE;
#endif
return 1;
}
......@@ -3638,14 +3567,18 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
* This is anyones guess quite frankly.
*/
int
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
sector_t capacity, int *ip)
{
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
mptscsih_bios_param(Disk * disk, struct block_device *bdev, int *ip)
{
sector_t capacity = disk->capacity;
#else
mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
{
sector_t capacity = disk->capacity;
unsigned capacity = disk->capacity;
#endif
int size;
......@@ -3666,20 +3599,63 @@ mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
* Called once per device the bus scan. Use it to force the queue_depth
* member to 1 if a device does not support Q tags.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
int
mptscsih_slave_attach(Scsi_Device *device)
{
struct Scsi_Host *host = device->host;
VirtDevice *pTarget;
pTarget = device->hostdata;
if (!device->tagged_supported ||
!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
scsi_adjust_queue_depth(device, 0, 1);
} else {
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
device->host->can_queue >> 1);
MPT_SCSI_HOST *hd;
hd = (MPT_SCSI_HOST *)host->hostdata;
if (hd && (hd->Targets != NULL)) {
pTarget = hd->Targets[device->id];
if (pTarget) {
if (!device->tagged_supported ||
!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
scsi_adjust_queue_depth(device, 0, 1);
} else {
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
device->host->can_queue >> 1);
}
}
}
return 0;
}
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) */
void
mptscsih_select_queue_depths(struct Scsi_Host *sh, Scsi_Device *sdList)
{
struct scsi_device *device;
VirtDevice *pTarget;
MPT_SCSI_HOST *hd;
int ii, max;
for (device = sdList; device != NULL; device = device->next) {
if (device->host != sh)
continue;
hd = (MPT_SCSI_HOST *) sh->hostdata;
if (hd == NULL)
continue;
if (hd->Targets != NULL) {
if (hd->is_spi)
max = MPT_MAX_SCSI_DEVICES;
else
max = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
for (ii=0; ii < max; ii++) {
pTarget = hd->Targets[ii];
if (pTarget && !(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
device->queue_depth = 1;
}
}
}
}
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -4126,6 +4102,9 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd->resetPending = 0;
hd->numTMrequests = 0;
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_NONE;
#endif
/* 6. If there was an internal command,
* wake this process up.
......@@ -4167,10 +4146,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/* FIXME! */
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
/* FIXME! */
break;
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
/* FIXME! */
hd = NULL;
if (ioc->sh) {
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
if (hd && (hd->is_spi) && (hd->soft_resets < -1))
hd->soft_resets++;
}
break;
case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */
......@@ -4804,9 +4786,10 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
}
if (vdev) {
if (hd->ioc->spi_data.isRaid & (1 << target_id))
if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
vdev->raidVolume = 1;
else
ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
} else
vdev->raidVolume = 0;
}
......@@ -4868,6 +4851,8 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
u8 version, nfactor;
u8 noQas = 1;
ddvtprintk((KERN_INFO "set Target: (id %d) byte56 0x%x\n", id, byte56));
/* Set flags based on Inquiry data
*/
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
......@@ -4886,12 +4871,18 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
*/
if ((byte56 & 0x04) == 0)
factor = MPT_ULTRA2;
else if ((byte56 & 0x03) == 0)
factor = MPT_ULTRA160;
else
factor = MPT_ULTRA320;
/* bit 1 QAS support, non-raid only
/* If RAID, never disable QAS
* else if non RAID, do not disable
* QAS if bit 1 is set
* bit 1 QAS support, non-raid only
* bit 0 IU support
*/
if ((target->raidVolume == 0) && (byte56 & 0x02) != 0)
if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0))
noQas = 0;
offset = pspi_data->maxSyncOffset;
......@@ -4976,6 +4967,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
VirtDevice *vdev;
int ii;
ddvtprintk((KERN_INFO "Disabling QAS!\n"));
pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS;
for (ii = 0; ii < id; ii++) {
vdev = hd->Targets[id];
......@@ -5204,6 +5196,17 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
//negoFlags = MPT_TARGET_NO_NEGO_SYNC;
}
#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
/* Force to async and narrow if DV has not been executed
* for this ID
*/
if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
width = 0;
factor = MPT_ASYNC;
offset = 0;
}
#endif
/* If id is not a raid volume, get the updated
* transmission settings from the target structure.
*/
......@@ -5313,13 +5316,6 @@ static void mptscsih_taskmgmt_timeout(unsigned long data)
*/
del_timer(&hd->TMtimer);
#ifdef MPT_SCSI_USE_NEW_EH
/* Set the error flag to 1 so that the function that started the
* task management request knows it timed out.
*/
hd->tmState = TM_STATE_ERROR;
#endif
/* Call the reset handler. Already had a TM request
* timeout - so issue a diagnostic reset
*/
......@@ -5853,6 +5849,12 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
else
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
if (cmd == CMD_RequestSense) {
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
hd->ioc->name, cmd));
}
for (ii=0; ii < 16; ii++)
pScsiReq->CDB[ii] = CDB[ii];
......@@ -6184,7 +6186,7 @@ mptscsih_domainValidation(void *arg)
post_pendingQ_commands(hd);
if (hd->ioc->spi_data.noQas)
mptscsih_qas_check(hd);
mptscsih_qas_check(hd, id);
}
}
}
......@@ -6218,7 +6220,7 @@ static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
/* Write SDP1 if no QAS has been enabled
*/
static void mptscsih_qas_check(MPT_SCSI_HOST *hd)
static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
{
VirtDevice *pTarget = NULL;
int ii;
......@@ -6227,6 +6229,9 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd)
return;
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
if (ii == id)
continue;
if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
continue;
......@@ -6510,6 +6515,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
rc = hd->pLocal->completion;
if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
dv.max.width = 0;
doFallback = 0;
} else
goto target_done;
}
......@@ -7059,6 +7065,10 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
dv.cmd = MPT_SAVE;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
#if 0
/* Double writes to SDP1 can cause problems,
* skip here since unnecessary
*/
/* Save the final negotiated settings to
* SCSI device page 1.
*/
......@@ -7067,13 +7077,14 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
mpt_config(hd->ioc, &cfg);
#endif
}
/* If this is a RAID Passthrough, enable internal IOs
*/
if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
}
/* Done with the DV scan of the current target
......@@ -7227,8 +7238,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
pPage1->Configuration = le32_to_cpu(configuration);
}
ddvprintk(("width %d, factor %x, offset %x request %x config %x\n",
dv->now.width, dv->now.factor,
dv->now.offset, val, configuration));
width, factor, offset, val, configuration));
break;
case MPT_FALLBACK:
......
......@@ -20,7 +20,7 @@
* (mailto:netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptscsih.h,v 1.19 2002/10/03 13:10:15 pdelaney Exp $
* $Id: mptscsih.h,v 1.20 2002/10/17 20:16:00 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -206,12 +206,15 @@ struct mptscsih_driver_setup
#define x_scsi_dev_reset mptscsih_dev_reset
#define x_scsi_host_reset mptscsih_host_reset
#define x_scsi_bios_param mptscsih_bios_param
#define x_scsi_slave_attach mptscsih_slave_attach
#define x_scsi_taskmgmt_bh mptscsih_taskmgmt_bh
#define x_scsi_old_abort mptscsih_old_abort
#define x_scsi_old_reset mptscsih_old_reset
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
#define x_scsi_slave_attach mptscsih_slave_attach
#else
#define x_scsi_select_queue_depths mptscsih_select_queue_depths
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
......@@ -231,13 +234,19 @@ extern int x_scsi_old_abort(Scsi_Cmnd *);
extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
extern int x_scsi_bios_param(Scsi_Device *, struct block_device *, sector_t, int[]);
extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev,
sector_t capacity, int *ip);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
extern int x_scsi_bios_param(Disk *, struct block_device *, int *);
#else
extern int x_scsi_bios_param(Disk *, kdev_t, int *);
#endif
extern int x_scsi_slave_attach(Scsi_Device *);
extern void x_scsi_taskmgmt_bh(void *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
extern int x_scsi_slave_attach(Scsi_Device *);
#else
extern void x_scsi_select_queue_depths(struct Scsi_Host *, Scsi_Device *);
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
#define PROC_SCSI_DECL
......@@ -247,7 +256,7 @@ extern int x_scsi_slave_attach(Scsi_Device *);
#ifdef MPT_SCSI_USE_NEW_EH
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
#define MPT_SCSIHOST { \
PROC_SCSI_DECL \
......@@ -255,8 +264,35 @@ extern int x_scsi_slave_attach(Scsi_Device *);
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \
.slave_attach = x_scsi_slave_attach, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \
.eh_host_reset_handler = x_scsi_host_reset, \
.bios_param = x_scsi_bios_param, \
.can_queue = MPT_SCSI_CAN_QUEUE, \
.this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.max_sectors = MPT_SCSI_MAX_SECTORS, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
#define MPT_SCSIHOST { \
PROC_SCSI_DECL \
.name = "MPT SCSI Host", \
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \
......@@ -267,27 +303,32 @@ extern int x_scsi_slave_attach(Scsi_Device *);
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.max_sectors = MPT_SCSI_MAX_SECTORS, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \
.slave_attach x_scsi_slave_attach, \
}
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */
#define MPT_SCSIHOST { \
.next = NULL, \
PROC_SCSI_DECL \
.name = "MPT SCSI Host", \
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \
.eh_host_reset_handler = NULL, \
.bios_param = x_scsi_bios_param, \
.can_queue = MPT_SCSI_CAN_QUEUE, \
.this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \
.use_new_eh_code = 1 \
}
......@@ -297,11 +338,13 @@ extern int x_scsi_slave_attach(Scsi_Device *);
#else /* MPT_SCSI_USE_NEW_EH */
#define MPT_SCSIHOST { \
.next = NULL, \
PROC_SCSI_DECL \
.name = "MPT SCSI Host", \
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \
.abort = x_scsi_old_abort, \
.reset = x_scsi_old_reset, \
......@@ -310,6 +353,7 @@ extern int x_scsi_slave_attach(Scsi_Device *);
.this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING \
}
#endif /* MPT_SCSI_USE_NEW_EH */
......
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