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 @@ ...@@ -49,7 +49,7 @@
* (mailto:sjralston1@netscape.net) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com) * (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) ...@@ -1156,7 +1156,7 @@ mpt_pci_scan(void)
dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n")); 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. * one for each channel.
*/ */
pci_for_each_dev(pdev) { pci_for_each_dev(pdev) {
...@@ -1170,18 +1170,14 @@ mpt_pci_scan(void) ...@@ -1170,18 +1170,14 @@ mpt_pci_scan(void)
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929X) && (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919X) && (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) && (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
#if 0 (pdev->device != MPI_MANUFACTPAGE_DEVID_1030_53C1035) &&
/* FIXME! C103x family */
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1035) &&
#endif
1) { 1) {
dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device)); dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device));
continue; continue;
} }
/* GRRRRR /* 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. * but we'd really really rather have them in Func 0,1 order.
* Do some kind of look ahead here... * Do some kind of look ahead here...
*/ */
...@@ -1445,15 +1441,24 @@ mpt_adapter_install(struct pci_dev *pdev) ...@@ -1445,15 +1441,24 @@ mpt_adapter_install(struct pci_dev *pdev)
ioc->chip_type = C1030; ioc->chip_type = C1030;
ioc->prod_name = "LSI53C1030"; ioc->prod_name = "LSI53C1030";
{ {
u8 revision;
/* 1030 Chip Fix. Disable Split transactions /* 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_byte(pdev, PCI_CLASS_REVISION, &revision);
pci_read_config_word(pdev, 0x6a, &pcixcmd); if (revision < 0x08) {
pcixcmd &= 0xFF8F; u16 pcixcmd = 0;
pci_write_config_word(pdev, 0x6a, pcixcmd); 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); sprintf(ioc->name, "ioc%d", ioc->id);
...@@ -1500,9 +1505,10 @@ mpt_adapter_install(struct pci_dev *pdev) ...@@ -1500,9 +1505,10 @@ mpt_adapter_install(struct pci_dev *pdev)
mpt_adapters[ioc->id] = ioc; mpt_adapters[ioc->id] = ioc;
/* NEW! 20010220 -sralston /* 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); mpt_detect_bound_ports(ioc, pdev);
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { 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) ...@@ -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 * mpt_detect_bound_ports - Search for PCI bus/dev_function
* which matches PCI bus/dev_function (+/-1) for newly discovered 929, * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
* 929X or 1030. * 929X, 1030 or 1035.
* @ioc: Pointer to MPT adapter structure * @ioc: Pointer to MPT adapter structure
* @pdev: Pointer to (struct pci_dev) structure * @pdev: Pointer to (struct pci_dev) structure
* *
...@@ -1806,8 +1812,7 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup) ...@@ -1806,8 +1812,7 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
/* Disable the FW */ /* Disable the FW */
state = mpt_GetIocState(this, 1); state = mpt_GetIocState(this, 1);
if (state == MPI_IOC_STATE_OPERATIONAL) { if (state == MPI_IOC_STATE_OPERATIONAL) {
if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP) != 0) SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP);
(void) KickStart(this, 1, NO_SLEEP);
} }
if (this->cached_fw != NULL) { if (this->cached_fw != NULL) {
...@@ -1819,7 +1824,6 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup) ...@@ -1819,7 +1824,6 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
} }
} }
/* Disable adapter interrupts! */ /* Disable adapter interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF); CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
this->active = 0; this->active = 0;
...@@ -2291,9 +2295,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) ...@@ -2291,9 +2295,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
ioc->reply_sz = ioc->req_sz; ioc->reply_sz = ioc->req_sz;
ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); 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", dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
ioc->name, ioc->reply_sz, ioc->reply_depth)); ioc->name, ioc->reply_sz, ioc->reply_depth));
dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n", dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
...@@ -2891,6 +2892,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) ...@@ -2891,6 +2892,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
*/ */
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
while ((diag0val & MPI_DIAG_DRWE) == 0) { 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_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);
...@@ -3126,6 +3128,18 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) ...@@ -3126,6 +3128,18 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
int cnt = 0; int cnt = 0;
dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name)); 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); hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
if (hard_reset_done < 0) if (hard_reset_done < 0)
...@@ -5841,6 +5855,15 @@ fusion_exit(void) ...@@ -5841,6 +5855,15 @@ fusion_exit(void)
while (! Q_IS_EMPTY(&MptAdapters)) { while (! Q_IS_EMPTY(&MptAdapters)) {
this = MptAdapters.head; 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); Q_DEL_ITEM(this);
mpt_adapter_dispose(this); mpt_adapter_dispose(this);
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* (mailto:sjralston1@netscape.net) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com) * (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 @@ ...@@ -80,8 +80,8 @@
#define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "2.02.01.07" #define MPT_LINUX_VERSION_COMMON "2.03.00.02"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.02.01.07" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.03.00.02"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -301,6 +301,7 @@ typedef enum { ...@@ -301,6 +301,7 @@ typedef enum {
FC919 = 0x0919, FC919 = 0x0919,
FC929 = 0x0929, FC929 = 0x0929,
C1030 = 0x1030, C1030 = 0x1030,
C1035 = 0x1035,
FCUNK = 0xFBAD FCUNK = 0xFBAD
} CHIP_TYPE; } CHIP_TYPE;
...@@ -368,6 +369,7 @@ typedef struct _ScsiCmndTracker { ...@@ -368,6 +369,7 @@ typedef struct _ScsiCmndTracker {
typedef struct _VirtDevice { typedef struct _VirtDevice {
struct _VirtDevice *forw; struct _VirtDevice *forw;
struct _VirtDevice *back; struct _VirtDevice *back;
struct scsi_device *device;
rwlock_t VdevLock; rwlock_t VdevLock;
int ref_cnt; int ref_cnt;
u8 tflags; u8 tflags;
...@@ -912,6 +914,10 @@ typedef struct _MPT_SCSI_HOST { ...@@ -912,6 +914,10 @@ typedef struct _MPT_SCSI_HOST {
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */ MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt; struct scsi_cmnd *abortSCpnt;
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */ 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; } MPT_SCSI_HOST;
/* /*
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
* (mailto:sjralston1@netscape.net) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com) * (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); ...@@ -136,14 +136,8 @@ static int mptctl_eventreport (unsigned long arg);
static int mptctl_replace_fw (unsigned long arg); static int mptctl_replace_fw (unsigned long arg);
static int mptctl_do_reset(unsigned long arg); static int mptctl_do_reset(unsigned long arg);
static int mptctl_hp_hostinfo(unsigned long arg);
static int mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int mptctl_hp_targetinfo(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);
/* /*
* Private function calls. * Private function calls.
...@@ -415,7 +409,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -415,7 +409,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->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)); ioctl->ioc->name));
mptctl_free_tm_flags(ioctl->ioc); mptctl_free_tm_flags(ioctl->ioc);
...@@ -623,21 +617,13 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned ...@@ -623,21 +617,13 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
} }
ret = -ENXIO; /* (-6) No such device or address */ 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 /* Verify intended MPT adapter - set iocnum and the adapter
* pointer (iocp) * pointer (iocp)
*/ */
iocnumX = khdr.iocnum & 0xFF; iocnumX = khdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (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)); __FILE__, __LINE__, iocnumX));
return -ENODEV; return -ENODEV;
} }
...@@ -683,6 +669,12 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned ...@@ -683,6 +669,12 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case MPTHARDRESET: case MPTHARDRESET:
ret = mptctl_do_reset(arg); ret = mptctl_do_reset(arg);
break; break;
case HP_GETHOSTINFO:
ret = mptctl_hp_hostinfo(arg);
break;
case HP_GETTARGETINFO:
ret = mptctl_hp_targetinfo(arg);
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
...@@ -708,7 +700,7 @@ static int mptctl_do_reset(unsigned long arg) ...@@ -708,7 +700,7 @@ static int mptctl_do_reset(unsigned long arg)
} }
if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) { 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)); __FILE__, __LINE__, krinfo.hdr.iocnum));
return -ENODEV; /* (-6) No such device or address */ return -ENODEV; /* (-6) No such device or address */
} }
...@@ -816,7 +808,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen) ...@@ -816,7 +808,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc)); dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc));
if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) { 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)); __FILE__, __LINE__, ioc));
return -ENODEV; /* (-6) No such device or address */ return -ENODEV; /* (-6) No such device or address */
} }
...@@ -1252,7 +1244,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) ...@@ -1252,7 +1244,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1379,7 +1371,7 @@ mptctl_gettargetinfo (unsigned long arg) ...@@ -1379,7 +1371,7 @@ mptctl_gettargetinfo (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1510,7 +1502,7 @@ mptctl_readtest (unsigned long arg) ...@@ -1510,7 +1502,7 @@ mptctl_readtest (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1568,7 +1560,7 @@ mptctl_eventquery (unsigned long arg) ...@@ -1568,7 +1560,7 @@ mptctl_eventquery (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1606,7 +1598,7 @@ mptctl_eventenable (unsigned long arg) ...@@ -1606,7 +1598,7 @@ mptctl_eventenable (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1654,7 +1646,7 @@ mptctl_eventreport (unsigned long arg) ...@@ -1654,7 +1646,7 @@ mptctl_eventreport (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1708,7 +1700,7 @@ mptctl_replace_fw (unsigned long arg) ...@@ -1708,7 +1700,7 @@ mptctl_replace_fw (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1794,7 +1786,7 @@ mptctl_mpt_command (unsigned long arg) ...@@ -1794,7 +1786,7 @@ mptctl_mpt_command (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1842,7 +1834,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -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) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
...@@ -1926,6 +1918,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -1926,6 +1918,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
int target = (int) pScsiReq->TargetID; int target = (int) pScsiReq->TargetID;
int dataSize; 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(); pScsiReq->MsgFlags = mpt_msg_flags();
/* verify that app has not requested /* verify that app has not requested
...@@ -2049,9 +2049,37 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -2049,9 +2049,37 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
} }
break; 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: default:
/* /*
* MPI_FUNCTION_IOC_INIT
* MPI_FUNCTION_PORT_ENABLE * MPI_FUNCTION_PORT_ENABLE
* MPI_FUNCTION_TARGET_CMD_BUFFER_POST * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
* MPI_FUNCTION_TARGET_ASSIST * MPI_FUNCTION_TARGET_ASSIST
...@@ -2357,131 +2385,85 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) ...@@ -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. * Outputs: None.
* Return: 0 if successful * Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable * -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. * -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
* -ENODEV if no such device/adapter * -ENODEV if no such device/adapter
* -ETIME if timer expires * -ETIME if timer expires
* -ENOMEM if memory allocation error
*/ */
static int static int
mptctl_cpq_getpciinfo(unsigned long arg) mptctl_hp_hostinfo(unsigned long arg)
{ {
cpqfc_pci_info_struct *uarg = (cpqfc_pci_info_struct *) arg; hp_host_info_t *uarg = (hp_host_info_t *) arg;
cpqfc_pci_info_struct karg;
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
struct pci_dev *pdev; struct pci_dev *pdev;
char *pbuf;
dma_addr_t buf_dma;
hp_host_info_t karg;
CONFIGPARMS cfg; CONFIGPARMS cfg;
ConfigPageHeader_t hdr; ConfigPageHeader_t hdr;
int iocnum = 0, iocnumX = 0; int iocnum;
dma_addr_t buf_dma; int rc;
u8 *pbuf = NULL;
int failed;
dctlprintk((": mptctl_cpq_pciinfo called.\n")); dctlprintk((": mptctl_hp_hostinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(cpqfc_pci_info_struct))) { if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - " printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
"Unable to read in cpqfc_pci_info_struct @ %p\n", "Unable to read in hp_host_info struct @ %p\n",
__FILE__, __LINE__, (void*)uarg); __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)) { (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)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
/* Fill in the data and return the structure to the calling
* program
*/
pdev = (struct pci_dev *) ioc->pcidev; pdev = (struct pci_dev *) ioc->pcidev;
/* Populate the structure. */ karg.vendor = pdev->vendor;
karg.bus = pdev->bus->number; karg.device = pdev->device;
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;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
karg.sub_vendor_id = pdev->subsystem_vendor; karg.subsystem_id = pdev->subsystem_device;
karg.sub_device_id = pdev->subsystem_device; karg.subsystem_vendor = pdev->subsystem_vendor;
#endif #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 /* Issue a config request to get the device serial number
*/ */
...@@ -2496,8 +2478,7 @@ mptctl_cpq_getpciinfo(unsigned long arg) ...@@ -2496,8 +2478,7 @@ mptctl_cpq_getpciinfo(unsigned long arg)
cfg.dir = 0; /* read */ cfg.dir = 0; /* read */
cfg.timeout = 10; cfg.timeout = 10;
failed = 1; strncpy(karg.serial_number, " ", 24);
if (mpt_config(ioc, &cfg) == 0) { if (mpt_config(ioc, &cfg) == 0) {
if (cfg.hdr->PageLength > 0) { if (cfg.hdr->PageLength > 0) {
/* Issue the second config page request */ /* Issue the second config page request */
...@@ -2508,242 +2489,207 @@ mptctl_cpq_getpciinfo(unsigned long arg) ...@@ -2508,242 +2489,207 @@ mptctl_cpq_getpciinfo(unsigned long arg)
cfg.physAddr = buf_dma; cfg.physAddr = buf_dma;
if (mpt_config(ioc, &cfg) == 0) { if (mpt_config(ioc, &cfg) == 0) {
ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf; ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
strncpy(karg.serial_number, pdata->BoardTracerNumber, 17); if (strlen(pdata->BoardTracerNumber) > 1)
failed = 0; strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
} }
pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
pbuf = NULL; pbuf = NULL;
} }
} }
} }
if (failed) rc = mpt_GetIocState(ioc, 1);
strncpy(karg.serial_number, " ", 17); switch (rc) {
case MPI_IOC_STATE_OPERATIONAL:
/* Copy the data from kernel memory to user memory karg.ioc_status = HP_STATUS_OK;
*/ break;
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;
}
return 0; case MPI_IOC_STATE_FAULT:
} karg.ioc_status = HP_STATUS_FAILED;
break;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ case MPI_IOC_STATE_RESET:
/* mptctl_cpq_getdriver - Get Driver Version in format desired by Compaq case MPI_IOC_STATE_READY:
* default:
* Outputs: None. karg.ioc_status = HP_STATUS_OTHER;
* Return: 0 if successful break;
* -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;
} }
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) || karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_getdriver() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
strncpy(version, MPT_LINUX_VERSION_COMMON, 8); if ((int)ioc->chip_type <= (int) FC929)
karg.bus_phys_width = HP_BUS_WIDTH_UNK;
karg = 0; else
vptr = version; karg.bus_phys_width = HP_BUS_WIDTH_16;
ii = 3;
while (ii > 0) { karg.hard_resets = 0;
pptr = strchr(vptr, '.'); karg.soft_resets = 0;
if (pptr) { karg.timeouts = 0;
*pptr = '\0'; if (ioc->sh != NULL) {
val = 0; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
for (jj=0; vptr[jj]>='0' && vptr[jj]<='9'; jj++)
val = 10 * val + (vptr[jj] - '0'); if (hd) {
karg |= (val << (8*ii)); karg.hard_resets = hd->hard_resets;
pptr++; karg.soft_resets = hd->soft_resets;
vptr = pptr; karg.timeouts = hd->timeouts;
} else }
break;
ii--;
} }
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char *)arg, &karg, if (copy_to_user((char *)arg, &karg,
sizeof(int))) { sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - " printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
"Unable to write out stuct @ %p\n", "Unable to write out hp_host_info @ %p\n",
__FILE__, __LINE__, (void*)uarg); __FILE__, __LINE__, (void*)uarg);
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_cpq_ctlr_status - Get controller status in format desired by Compaq /* Prototype Routine for the HP TARGET INFO command.
* *
* Outputs: None. * Outputs: None.
* Return: 0 if successful * Return: 0 if successful
* -EFAULT if data unavailable * -EFAULT if data unavailable
* -EBUSY if previous command timout and IOC reset is not complete.
* -ENODEV if no such device/adapter * -ENODEV if no such device/adapter
* -ETIME if timer expires
* -ENOMEM if memory allocation error
*/ */
static int static int
mptctl_cpq_ctlr_status(unsigned long arg) mptctl_hp_targetinfo(unsigned long arg)
{ {
cpqfc_ctlr_status *uarg = (cpqfc_ctlr_status *) arg; hp_target_info_t *uarg = (hp_target_info_t *) arg;
cpqfc_ctlr_status karg; SCSIDevicePage0_t *pg0_alloc;
SCSIDevicePage3_t *pg3_alloc;
MPT_ADAPTER *ioc; 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")); dctlprintk((": mptctl_hp_targetinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(cpqfc_ctlr_status))) { if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - " printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
"Unable to read in cpqfc_ctlr_status @ %p\n", "Unable to read in hp_host_targetinfo struct @ %p\n",
__FILE__, __LINE__, (void*)uarg); __FILE__, __LINE__, (void*)uarg);
return -EFAULT; return -EFAULT;
} }
if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_ctlr_status() @%d - ioc%d not found!\n", dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum)); __FILE__, __LINE__, iocnum));
return -ENODEV; return -ENODEV;
} }
karg.status = ioc->last_state; /* There is nothing to do for FCP parts.
karg.offline_reason = 0;
/* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char *)arg, &karg, if ((int) ioc->chip_type <= (int) FC929)
sizeof(cpqfc_ctlr_status))) { return 0;
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 ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
/* mptctl_cpq_target_address - Get WWN Information in format desired by Compaq return 0;
*
* 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 (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) || if (ioc->sh->host_no != karg.hdr.host)
(ioc == NULL)) {
dtmprintk((KERN_ERR "%s::mptctl_cpq_target_address() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV; 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.PageVersion = 0;
hdr.PageLength = 0; hdr.PageLength = 0;
hdr.PageNumber = 0; hdr.PageNumber = 3;
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &hdr; cfg.hdr = &hdr;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0; /* read */ cfg.dir = 0;
cfg.timeout = 10; cfg.timeout = 0;
cfg.physAddr = -1;
failed = 1; if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
/* Issue the second config page request */
if (mpt_config(ioc, &cfg) == 0) { cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
if (cfg.hdr->PageLength > 0) { data_sz = (int) cfg.hdr->PageLength * 4;
/* Issue the second config page request */ pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; ioc->pcidev, data_sz, &page_dma);
if (pg3_alloc) {
pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma); cfg.physAddr = page_dma;
if (pbuf) { cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
cfg.physAddr = buf_dma; if ((rc = mpt_config(ioc, &cfg)) == 0) {
if (mpt_config(ioc, &cfg) == 0) { karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
ppp0 = (FCPortPage0_t *) pbuf; karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
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;
} }
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
} }
} }
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
if (failed) { if (hd != NULL)
for (ii = 7; ii >= 0; ii--) karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
karg.host_wwn[ii] = 0;
}
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char *)arg, &karg, if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
sizeof(Scsi_FCTargAddress))) { printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
"Unable to write out Scsi_FCTargAddress @ %p\n",
__FILE__, __LINE__, (void*)uarg); __FILE__, __LINE__, (void*)uarg);
return -EFAULT; return -EFAULT;
} }
...@@ -2751,161 +2697,6 @@ mptctl_cpq_target_address(unsigned long arg) ...@@ -2751,161 +2697,6 @@ mptctl_cpq_target_address(unsigned long arg)
return 0; 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) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
...@@ -2971,7 +2762,7 @@ sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, ...@@ -2971,7 +2762,7 @@ sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
iocnumX = kfw32.iocnum & 0xFF; iocnumX = kfw32.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (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)); __LINE__, iocnumX));
return -ENODEV; return -ENODEV;
} }
...@@ -3011,7 +2802,7 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd, ...@@ -3011,7 +2802,7 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd,
iocnumX = karg32.hdr.iocnum & 0xFF; iocnumX = karg32.hdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (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)); __LINE__, iocnumX));
return -ENODEV; return -ENODEV;
} }
...@@ -3044,70 +2835,6 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd, ...@@ -3044,70 +2835,6 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd,
return ret; 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 /*} linux >= 2.3.x */
#endif /*} sparc */ #endif /*} sparc */
...@@ -3176,15 +2903,9 @@ int __init mptctl_init(void) ...@@ -3176,15 +2903,9 @@ int __init mptctl_init(void)
err = register_ioctl32_conversion(MPTFWDOWNLOAD32, err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
sparc32_mptfwxfer_ioctl); sparc32_mptfwxfer_ioctl);
if (++where && err) goto out_fail; if (++where && err) goto out_fail;
err = register_ioctl32_conversion(CPQFCTS_GETPCIINFO, NULL); err = register_ioctl32_conversion(HP_GETHOSTINFO, 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);
if (++where && err) goto out_fail; 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; if (++where && err) goto out_fail;
#endif /*} linux >= 2.3.x */ #endif /*} linux >= 2.3.x */
#endif /*} sparc */ #endif /*} sparc */
...@@ -3233,11 +2954,8 @@ int __init mptctl_init(void) ...@@ -3233,11 +2954,8 @@ int __init mptctl_init(void)
unregister_ioctl32_conversion(MPTHARDRESET); unregister_ioctl32_conversion(MPTHARDRESET);
unregister_ioctl32_conversion(MPTCOMMAND32); unregister_ioctl32_conversion(MPTCOMMAND32);
unregister_ioctl32_conversion(MPTFWDOWNLOAD32); unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
unregister_ioctl32_conversion(CPQFCTS_GETPCIINFO); unregister_ioctl32_conversion(HP_GETHOSTINFO);
unregister_ioctl32_conversion(CPQFCTS_GETDRIVVER); unregister_ioctl32_conversion(HP_GETTARGETINFO);
unregister_ioctl32_conversion(CPQFCTS_CTLR_STATUS);
unregister_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS);
unregister_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32);
#endif /*} linux >= 2.3.x */ #endif /*} linux >= 2.3.x */
#endif /*} sparc */ #endif /*} sparc */
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* (mailto:sjralston1@netscape.net) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com) * (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 { ...@@ -310,95 +310,91 @@ struct mpt_ioctl_command32 {
#endif /*}*/ #endif /*}*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* COMPAQ Specific IOCTL Defines and Structures * HP Specific IOCTL Defines and Structures
*/ */
#define CPQFCTS_IOC_MAGIC 'Z' #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) /* All HP IOCTLs must include this header
#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.
*/ */
#define MPT_COMPAQ_READ 0x26 typedef struct _hp_header {
#define MPT_COMPAQ_WRITE 0x27 unsigned int iocnum;
unsigned int host;
typedef struct { unsigned int channel;
int lc; /* controller number */ unsigned int id;
int node; /* node number */ unsigned int lun;
int ld; /* target logical id */ } hp_header_t;
u32 nexus;
void *argp; /*
} VENDOR_IOCTL_REQ; * Header:
* iocnum required (input)
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/ * host ignored
typedef struct { * channe ignored
int lc; /* controller number */ * id ignored
int node; /* node number */ * lun ignored
int ld; /* target logical id */ */
u32 nexus; typedef struct _hp_host_info {
u32 argp; hp_header_t hdr;
} VENDOR_IOCTL_REQ32; u16 vendor;
#endif u16 device;
u16 subsystem_vendor;
typedef struct { u16 subsystem_id;
char cdb[16]; /* cdb */ u8 devfn;
unsigned short bus; /* bus number */ u8 bus;
unsigned short pdrive; /* physical drive */ ushort host_no; /* SCSI Host number, if scsi driver not loaded*/
int len; /* data area size */ u8 fw_version[16]; /* string */
int sense_len; /* sense size */ u8 serial_number[24]; /* string */
char sense_data[40]; /* sense buffer */ u32 ioc_status;
void *bufp; /* data buffer pointer */ u32 bus_phys_width;
char rw_flag; u32 base_io_addr;
} cpqfc_passthru_t; u32 rsvd;
unsigned long hard_resets; /* driver initiated resets */
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/ unsigned long soft_resets; /* ioc, external resets */
typedef struct { unsigned long timeouts; /* num timeouts */
char cdb[16]; /* cdb */ } hp_host_info_t;
unsigned short bus; /* bus number */
unsigned short pdrive; /* physical drive */ /*
int len; /* data area size */ * Header:
int sense_len; /* sense size */ * iocnum required (input)
char sense_data[40]; /* sense buffer */ * host required
u32 bufp; /* data buffer pointer */ * channel required (bus number)
char rw_flag; * id required
} cpqfc_passthru32_t; * lun ignored
#endif *
* 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 @@ ...@@ -26,7 +26,7 @@
* Copyright (c) 2000-2002 LSI Logic Corporation * Copyright (c) 2000-2002 LSI Logic Corporation
* Originally By: Noah Romer * 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 @@ ...@@ -8,7 +8,6 @@
#include <linux/module.h> #include <linux/module.h>
#endif #endif
#include <linux/version.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/errno.h> #include <linux/errno.h>
// #include <linux/etherdevice.h> // #include <linux/etherdevice.h>
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* (mailto:sjralston1@netscape.net) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com) * (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 @@ ...@@ -78,6 +78,9 @@
#include <linux/reboot.h> /* notifier code */ #include <linux/reboot.h> /* notifier code */
#include "../../scsi/scsi.h" #include "../../scsi/scsi.h"
#include "../../scsi/hosts.h" #include "../../scsi/hosts.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
#include "../../scsi/sd.h"
#endif
#include "mptbase.h" #include "mptbase.h"
#include "mptscsih.h" #include "mptscsih.h"
...@@ -198,7 +201,7 @@ static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); ...@@ -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 int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd); static void mptscsih_domainValidation(void *hd);
static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); 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 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_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width); static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
...@@ -399,6 +402,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -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 */ case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
/* Spoof to SCSI Selection Timeout! */ /* Spoof to SCSI Selection Timeout! */
sc->result = DID_NO_CONNECT << 16; sc->result = DID_NO_CONNECT << 16;
if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
hd->sel_timeout[pScsiReq->TargetID]++;
break; break;
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
...@@ -1289,11 +1295,17 @@ mptscsih_detect(Scsi_Host_Template *tpnt) ...@@ -1289,11 +1295,17 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
sh->max_sectors = MPT_SCSI_MAX_SECTORS; sh->max_sectors = MPT_SCSI_MAX_SECTORS;
#endif #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; sh->highmem_io = 1;
#endif #endif
sh->this_id = this->pfacts[portnum].PortSCSIID; 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. /* Required entry.
*/ */
sh->unique_id = this->id; sh->unique_id = this->id;
...@@ -2546,14 +2558,13 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ...@@ -2546,14 +2558,13 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
/* Isse the Task Mgmt request. /* Isse the Task Mgmt request.
*/ */
if (hd->hard_resets < -1)
hd->hard_resets++;
rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag); rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag);
if (rc) { 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); printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
} else { } 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 #ifdef DROP_TEST
...@@ -2681,7 +2692,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2681,7 +2692,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
unsigned long flags;
u32 ctx2abort; u32 ctx2abort;
int scpnt_idx; int scpnt_idx;
...@@ -2696,10 +2706,11 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2696,10 +2706,11 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED; return FAILED;
} }
printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n", printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, atomic_read(&queue_depth)); if (hd->timeouts < -1)
hd->timeouts++;
/* Find this command /* Find this command
*/ */
...@@ -2753,11 +2764,9 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2753,11 +2764,9 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext; ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
hd->abortSCpnt = SCpnt; hd->abortSCpnt = SCpnt;
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->target, SCpnt->lun, ctx2abort, CAN_SLEEP) SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP)
< 0 < 0) {
|| hd->tmState == TM_STATE_ERROR) {
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
* Fatal error case. * Fatal error case.
...@@ -2765,14 +2774,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2765,14 +2774,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n", printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
hd->ioc->name, SCpnt); 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. /* We must clear our pending flag before clearing our state.
*/ */
hd->tmPending = 0; hd->tmPending = 0;
...@@ -2780,34 +2781,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt) ...@@ -2780,34 +2781,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED; 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 ...@@ -2823,7 +2798,6 @@ int
mptscsih_dev_reset(Scsi_Cmnd * SCpnt) mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
unsigned long flags;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
...@@ -2834,10 +2808,13 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt) ...@@ -2834,10 +2808,13 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
return FAILED; return FAILED;
} }
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n", printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, 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. /* 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 * If we time out, then we return a FAILED status to the caller. This
...@@ -2853,7 +2830,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt) ...@@ -2853,7 +2830,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
} }
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->target, 0, 0, CAN_SLEEP) SCpnt->target, 0, 0, NO_SLEEP)
< 0){ < 0){
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
* Fatal error case. * Fatal error case.
...@@ -2864,34 +2841,8 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt) ...@@ -2864,34 +2841,8 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
hd->tmState = TM_STATE_NONE; hd->tmState = TM_STATE_NONE;
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_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; return SUCCESS;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -2907,7 +2858,6 @@ int ...@@ -2907,7 +2858,6 @@ int
mptscsih_bus_reset(Scsi_Cmnd * SCpnt) mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
unsigned long flags;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
...@@ -2918,10 +2868,11 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt) ...@@ -2918,10 +2868,11 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED; return FAILED;
} }
printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n", printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, atomic_read(&queue_depth)); if (hd->timeouts < -1)
hd->timeouts++;
/* Wait a fixed amount of time for the TM pending flag to be cleared. /* 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 * If we time out, then we return a FAILED status to the caller. This
...@@ -2932,13 +2883,13 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt) ...@@ -2932,13 +2883,13 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: " nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
"Timed out waiting for previous TM to complete! " "Timed out waiting for previous TM to complete! "
"(sc = %p)\n", "(sc = %p)\n",
hd->ioc->name, SCpnt ) ); hd->ioc->name, SCpnt));
return FAILED; return FAILED;
} }
/* We are now ready to execute the task management request. */ /* We are now ready to execute the task management request. */
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
0, 0, 0, CAN_SLEEP) 0, 0, 0, NO_SLEEP)
< 0){ < 0){
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
...@@ -2952,32 +2903,6 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt) ...@@ -2952,32 +2903,6 @@ mptscsih_bus_reset(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_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; return SUCCESS;
} }
...@@ -3013,7 +2938,7 @@ mptscsih_host_reset(Scsi_Cmnd *SCpnt) ...@@ -3013,7 +2938,7 @@ mptscsih_host_reset(Scsi_Cmnd *SCpnt)
/* If our attempts to reset the host failed, then return a failed /* 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. * 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; status = FAILED;
} else { } else {
/* Make sure TM pending is cleared and TM state is set to /* Make sure TM pending is cleared and TM state is set to
...@@ -3056,9 +2981,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) ...@@ -3056,9 +2981,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
break; break;
} }
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
set_current_state(TASK_INTERRUPTIBLE); mdelay(250);
schedule_timeout(HZ/4);
} while (--loop_count); } while (--loop_count);
return status; return status;
...@@ -3093,6 +3016,9 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt) ...@@ -3093,6 +3016,9 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt)
return SCSI_ABORT_NOT_RUNNING; return SCSI_ABORT_NOT_RUNNING;
} }
if (hd->timeouts < -1)
hd->timeouts++;
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
/* Cmd not found in ScsiLookup. /* Cmd not found in ScsiLookup.
* If found in doneQ, delete from Q. * If found in doneQ, delete from Q.
...@@ -3166,7 +3092,7 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt) ...@@ -3166,7 +3092,7 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt)
SCpnt->host_scribble = (u8 *) MPT_INDEX_2_MFPTR (hd->ioc, scpnt_idx); SCpnt->host_scribble = (u8 *) MPT_INDEX_2_MFPTR (hd->ioc, scpnt_idx);
/* For the time being, force bus reset on any abort /* 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) if (hd->is_spi)
mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS; mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
...@@ -3226,6 +3152,9 @@ mptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags) ...@@ -3226,6 +3152,9 @@ mptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
return SCSI_RESET_SUCCESS; return SCSI_RESET_SUCCESS;
} }
if (hd->timeouts < -1)
hd->timeouts++;
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
/* Cmd not found in ScsiLookup. /* Cmd not found in ScsiLookup.
* If found in doneQ, delete from Q. * 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 ...@@ -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 { } else {
dtmprintk((KERN_INFO " SCSI TaskMgmt SUCCESS!\n")); 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 ...@@ -3629,6 +3555,9 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
spin_lock_irqsave(&ioc->FreeQlock, flags); spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmPending = 0; hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_NONE;
#endif
return 1; return 1;
} }
...@@ -3638,14 +3567,18 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m ...@@ -3638,14 +3567,18 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
* This is anyones guess quite frankly. * This is anyones guess quite frankly.
*/ */
int 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, mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
sector_t capacity, int *ip) 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 #else
mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip) mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
{ {
sector_t capacity = disk->capacity; unsigned capacity = disk->capacity;
#endif #endif
int size; int size;
...@@ -3666,20 +3599,63 @@ mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip) ...@@ -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 * 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. * member to 1 if a device does not support Q tags.
*/ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
int int
mptscsih_slave_attach(Scsi_Device *device) mptscsih_slave_attach(Scsi_Device *device)
{ {
struct Scsi_Host *host = device->host;
VirtDevice *pTarget; VirtDevice *pTarget;
pTarget = device->hostdata; MPT_SCSI_HOST *hd;
if (!device->tagged_supported ||
!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) { hd = (MPT_SCSI_HOST *)host->hostdata;
scsi_adjust_queue_depth(device, 0, 1); if (hd && (hd->Targets != NULL)) {
} else { pTarget = hd->Targets[device->id];
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, if (pTarget) {
device->host->can_queue >> 1); 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; 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) ...@@ -4126,6 +4102,9 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd->resetPending = 0; hd->resetPending = 0;
hd->numTMrequests = 0; hd->numTMrequests = 0;
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_NONE;
#endif
/* 6. If there was an internal command, /* 6. If there was an internal command,
* wake this process up. * wake this process up.
...@@ -4167,10 +4146,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -4167,10 +4146,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/* FIXME! */ /* FIXME! */
break; break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */ case MPI_EVENT_IOC_BUS_RESET: /* 04 */
/* FIXME! */
break;
case MPI_EVENT_EXT_BUS_RESET: /* 05 */ 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; break;
case MPI_EVENT_LOGOUT: /* 09 */ case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */ /* FIXME! */
...@@ -4804,9 +4786,10 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * ...@@ -4804,9 +4786,10 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
} }
if (vdev) { if (vdev) {
if (hd->ioc->spi_data.isRaid & (1 << target_id)) if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
vdev->raidVolume = 1; vdev->raidVolume = 1;
else ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
} else
vdev->raidVolume = 0; vdev->raidVolume = 0;
} }
...@@ -4868,6 +4851,8 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4868,6 +4851,8 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
u8 version, nfactor; u8 version, nfactor;
u8 noQas = 1; u8 noQas = 1;
ddvtprintk((KERN_INFO "set Target: (id %d) byte56 0x%x\n", id, byte56));
/* Set flags based on Inquiry data /* Set flags based on Inquiry data
*/ */
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
...@@ -4886,12 +4871,18 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4886,12 +4871,18 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
*/ */
if ((byte56 & 0x04) == 0) if ((byte56 & 0x04) == 0)
factor = MPT_ULTRA2; factor = MPT_ULTRA2;
else if ((byte56 & 0x03) == 0)
factor = MPT_ULTRA160;
else else
factor = MPT_ULTRA320; 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; noQas = 0;
offset = pspi_data->maxSyncOffset; offset = pspi_data->maxSyncOffset;
...@@ -4976,6 +4967,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt ...@@ -4976,6 +4967,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
VirtDevice *vdev; VirtDevice *vdev;
int ii; int ii;
ddvtprintk((KERN_INFO "Disabling QAS!\n"));
pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS; pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS;
for (ii = 0; ii < id; ii++) { for (ii = 0; ii < id; ii++) {
vdev = hd->Targets[id]; vdev = hd->Targets[id];
...@@ -5204,6 +5196,17 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -5204,6 +5196,17 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
//negoFlags = MPT_TARGET_NO_NEGO_SYNC; //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 /* If id is not a raid volume, get the updated
* transmission settings from the target structure. * transmission settings from the target structure.
*/ */
...@@ -5313,13 +5316,6 @@ static void mptscsih_taskmgmt_timeout(unsigned long data) ...@@ -5313,13 +5316,6 @@ static void mptscsih_taskmgmt_timeout(unsigned long data)
*/ */
del_timer(&hd->TMtimer); 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 /* Call the reset handler. Already had a TM request
* timeout - so issue a diagnostic reset * timeout - so issue a diagnostic reset
*/ */
...@@ -5853,6 +5849,12 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) ...@@ -5853,6 +5849,12 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
else else
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED); 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++) for (ii=0; ii < 16; ii++)
pScsiReq->CDB[ii] = CDB[ii]; pScsiReq->CDB[ii] = CDB[ii];
...@@ -6184,7 +6186,7 @@ mptscsih_domainValidation(void *arg) ...@@ -6184,7 +6186,7 @@ mptscsih_domainValidation(void *arg)
post_pendingQ_commands(hd); post_pendingQ_commands(hd);
if (hd->ioc->spi_data.noQas) 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) ...@@ -6218,7 +6220,7 @@ static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
/* Write SDP1 if no QAS has been enabled /* 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; VirtDevice *pTarget = NULL;
int ii; int ii;
...@@ -6227,6 +6229,9 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd) ...@@ -6227,6 +6229,9 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd)
return; return;
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 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) if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
continue; continue;
...@@ -6510,6 +6515,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id) ...@@ -6510,6 +6515,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
rc = hd->pLocal->completion; rc = hd->pLocal->completion;
if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) { if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
dv.max.width = 0; dv.max.width = 0;
doFallback = 0;
} else } else
goto target_done; goto target_done;
} }
...@@ -7059,6 +7065,10 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id) ...@@ -7059,6 +7065,10 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
dv.cmd = MPT_SAVE; dv.cmd = MPT_SAVE;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 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 /* Save the final negotiated settings to
* SCSI device page 1. * SCSI device page 1.
*/ */
...@@ -7067,13 +7077,14 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id) ...@@ -7067,13 +7077,14 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1; cfg.dir = 1;
mpt_config(hd->ioc, &cfg); mpt_config(hd->ioc, &cfg);
#endif
} }
/* If this is a RAID Passthrough, enable internal IOs /* If this is a RAID Passthrough, enable internal IOs
*/ */
if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) { if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0) 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 /* Done with the DV scan of the current target
...@@ -7227,8 +7238,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) ...@@ -7227,8 +7238,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
pPage1->Configuration = le32_to_cpu(configuration); pPage1->Configuration = le32_to_cpu(configuration);
} }
ddvprintk(("width %d, factor %x, offset %x request %x config %x\n", ddvprintk(("width %d, factor %x, offset %x request %x config %x\n",
dv->now.width, dv->now.factor, width, factor, offset, val, configuration));
dv->now.offset, val, configuration));
break; break;
case MPT_FALLBACK: case MPT_FALLBACK:
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* (mailto:netscape.net) * (mailto:netscape.net)
* (mailto:Pam.Delaney@lsil.com) * (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 ...@@ -206,12 +206,15 @@ struct mptscsih_driver_setup
#define x_scsi_dev_reset mptscsih_dev_reset #define x_scsi_dev_reset mptscsih_dev_reset
#define x_scsi_host_reset mptscsih_host_reset #define x_scsi_host_reset mptscsih_host_reset
#define x_scsi_bios_param mptscsih_bios_param #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_taskmgmt_bh mptscsih_taskmgmt_bh
#define x_scsi_old_abort mptscsih_old_abort #define x_scsi_old_abort mptscsih_old_abort
#define x_scsi_old_reset mptscsih_old_reset #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 #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 *); ...@@ -231,13 +234,19 @@ extern int x_scsi_old_abort(Scsi_Cmnd *);
extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int); extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
#endif #endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) #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 #else
extern int x_scsi_bios_param(Disk *, kdev_t, int *); extern int x_scsi_bios_param(Disk *, kdev_t, int *);
#endif #endif
extern int x_scsi_slave_attach(Scsi_Device *);
extern void x_scsi_taskmgmt_bh(void *); extern void x_scsi_taskmgmt_bh(void *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
extern int x_scsi_slave_attach(Scsi_Device *); 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) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
#define PROC_SCSI_DECL #define PROC_SCSI_DECL
...@@ -247,7 +256,7 @@ extern int x_scsi_slave_attach(Scsi_Device *); ...@@ -247,7 +256,7 @@ extern int x_scsi_slave_attach(Scsi_Device *);
#ifdef MPT_SCSI_USE_NEW_EH #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 { \ #define MPT_SCSIHOST { \
PROC_SCSI_DECL \ PROC_SCSI_DECL \
...@@ -255,8 +264,35 @@ extern int x_scsi_slave_attach(Scsi_Device *); ...@@ -255,8 +264,35 @@ extern int x_scsi_slave_attach(Scsi_Device *);
.detect = x_scsi_detect, \ .detect = x_scsi_detect, \
.release = x_scsi_release, \ .release = x_scsi_release, \
.info = x_scsi_info, \ .info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \ .queuecommand = x_scsi_queuecommand, \
.slave_attach = x_scsi_slave_attach, \ .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_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \ .eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \ .eh_bus_reset_handler = x_scsi_bus_reset, \
...@@ -267,27 +303,32 @@ extern int x_scsi_slave_attach(Scsi_Device *); ...@@ -267,27 +303,32 @@ extern int x_scsi_slave_attach(Scsi_Device *);
.sg_tablesize = MPT_SCSI_SG_DEPTH, \ .sg_tablesize = MPT_SCSI_SG_DEPTH, \
.max_sectors = MPT_SCSI_MAX_SECTORS, \ .max_sectors = MPT_SCSI_MAX_SECTORS, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \ .cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \ .use_clustering = ENABLE_CLUSTERING, \
.slave_attach x_scsi_slave_attach, \
} }
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */ #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */
#define MPT_SCSIHOST { \ #define MPT_SCSIHOST { \
.next = NULL, \
PROC_SCSI_DECL \ PROC_SCSI_DECL \
.name = "MPT SCSI Host", \ .name = "MPT SCSI Host", \
.detect = x_scsi_detect, \ .detect = x_scsi_detect, \
.release = x_scsi_release, \ .release = x_scsi_release, \
.info = x_scsi_info, \ .info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \ .queuecommand = x_scsi_queuecommand, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = x_scsi_abort, \ .eh_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \ .eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \ .eh_bus_reset_handler = x_scsi_bus_reset, \
.eh_host_reset_handler = NULL, \
.bios_param = x_scsi_bios_param, \ .bios_param = x_scsi_bios_param, \
.can_queue = MPT_SCSI_CAN_QUEUE, \ .can_queue = MPT_SCSI_CAN_QUEUE, \
.this_id = -1, \ .this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \ .sg_tablesize = MPT_SCSI_SG_DEPTH, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \ .cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \ .use_clustering = ENABLE_CLUSTERING, \
.use_new_eh_code = 1 \ .use_new_eh_code = 1 \
} }
...@@ -297,11 +338,13 @@ extern int x_scsi_slave_attach(Scsi_Device *); ...@@ -297,11 +338,13 @@ extern int x_scsi_slave_attach(Scsi_Device *);
#else /* MPT_SCSI_USE_NEW_EH */ #else /* MPT_SCSI_USE_NEW_EH */
#define MPT_SCSIHOST { \ #define MPT_SCSIHOST { \
.next = NULL, \
PROC_SCSI_DECL \ PROC_SCSI_DECL \
.name = "MPT SCSI Host", \ .name = "MPT SCSI Host", \
.detect = x_scsi_detect, \ .detect = x_scsi_detect, \
.release = x_scsi_release, \ .release = x_scsi_release, \
.info = x_scsi_info, \ .info = x_scsi_info, \
.command = NULL, \
.queuecommand = x_scsi_queuecommand, \ .queuecommand = x_scsi_queuecommand, \
.abort = x_scsi_old_abort, \ .abort = x_scsi_old_abort, \
.reset = x_scsi_old_reset, \ .reset = x_scsi_old_reset, \
...@@ -310,6 +353,7 @@ extern int x_scsi_slave_attach(Scsi_Device *); ...@@ -310,6 +353,7 @@ extern int x_scsi_slave_attach(Scsi_Device *);
.this_id = -1, \ .this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \ .sg_tablesize = MPT_SCSI_SG_DEPTH, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \ .cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING \ .use_clustering = ENABLE_CLUSTERING \
} }
#endif /* MPT_SCSI_USE_NEW_EH */ #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