mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
Merge patch series "smartpqi: fixes and updates for 2.1.42-011"
David Strahan <david.strahan@microchip.com> says: These patches are based on Martin Petersen's 7.2/scsi-queue tree https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git 7.2/scsi-queue This patch series includes four patches, with two main functional changes: 1. smartpqi-Fix-AIO-retry-marker-cleared-by-SCSI-core-between-dispatches On recent Linux kernels the driver can enter a retry loop on the AIO fast path when a request is retried, looping until timeout, and a diagnostic path that takes a physical drive offline on AIO-bypass failure is never entered. Registers a per-command initialization callback with the SCSI core so its presence causes the core to skip the per-dispatch clear of the retry marker, letting it survive the requeue so the AIO-to-RAID fallback proceeds as intended. 2. smartpqi-add-support-for-CCISS_BIG_PASSTHRU-ioctl Adds pqi_big_passthru_ioctl() to handle CCISS_BIG_PASSTHRU ioctl requests. The existing passthru ioctl uses a 16-bit integer for the I/O buffer size, limiting transfers to 64KB. The big passthru ioctl uses BIG_IOCTL_Command_struct, which stores the buffer size as a 32-bit integer, allowing the larger transfers required by some management utilities. The other two patches: 3. smartpqi-add-new-pci-device-ids Adds PCI IDs for new Hurray Data, ZTE, and Ramaxel controllers. No functional changes. 4. smartpqi-update-driver-version-to-2.1.42-011 Updates the driver version string. No functional changes. Link: https://patch.msgid.link/20260722220401.6357-1-david.strahan@microchip.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
@@ -34,11 +34,11 @@
|
||||
#define BUILD_TIMESTAMP
|
||||
#endif
|
||||
|
||||
#define DRIVER_VERSION "2.1.36-026"
|
||||
#define DRIVER_VERSION "2.1.42-011"
|
||||
#define DRIVER_MAJOR 2
|
||||
#define DRIVER_MINOR 1
|
||||
#define DRIVER_RELEASE 36
|
||||
#define DRIVER_REVISION 26
|
||||
#define DRIVER_RELEASE 42
|
||||
#define DRIVER_REVISION 11
|
||||
|
||||
#define DRIVER_NAME "Microchip SmartPQI Driver (v" \
|
||||
DRIVER_VERSION BUILD_TIMESTAMP ")"
|
||||
@@ -66,6 +66,12 @@ static struct pqi_cmd_priv *pqi_cmd_priv(struct scsi_cmnd *cmd)
|
||||
return scsi_cmd_priv(cmd);
|
||||
}
|
||||
|
||||
static int pqi_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
|
||||
{
|
||||
memset(pqi_cmd_priv(cmd), 0, sizeof(struct pqi_cmd_priv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pqi_verify_structures(void);
|
||||
static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info,
|
||||
enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason);
|
||||
@@ -5958,6 +5964,17 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd)
|
||||
struct pqi_scsi_dev *device;
|
||||
struct completion *wait;
|
||||
|
||||
/*
|
||||
* Clear the AIO-retry marker on final completion so the tag
|
||||
* starts clean on its next dispatch. On DID_IMM_RETRY leave
|
||||
* it intact: pqi_aio_io_complete() sets DID_IMM_RETRY and
|
||||
* bumps the marker to steer the requeue onto the RAID path,
|
||||
* and pqi_process_raid_io_error() consumes the non-zero
|
||||
* marker to offline a misbehaving drive.
|
||||
*/
|
||||
if (host_byte(scmd->result) != DID_IMM_RETRY)
|
||||
pqi_cmd_priv(scmd)->this_residual = 0;
|
||||
|
||||
if (!scmd->device) {
|
||||
set_host_byte(scmd, DID_NO_CONNECT);
|
||||
return;
|
||||
@@ -6918,6 +6935,144 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pqi_big_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg)
|
||||
{
|
||||
int rc;
|
||||
char *kernel_buffer = NULL;
|
||||
u16 iu_length;
|
||||
size_t sense_data_length;
|
||||
BIG_IOCTL_Command_struct iocommand;
|
||||
struct pqi_raid_path_request request;
|
||||
struct pqi_raid_error_info pqi_error_info;
|
||||
struct ciss_error_info ciss_error_info;
|
||||
|
||||
if (pqi_ctrl_offline(ctrl_info))
|
||||
return -ENXIO;
|
||||
if (pqi_ofa_in_progress(ctrl_info) && pqi_ctrl_blocked(ctrl_info))
|
||||
return -EBUSY;
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
if (copy_from_user(&iocommand, arg, sizeof(iocommand)))
|
||||
return -EFAULT;
|
||||
if (iocommand.buf_size < 1 &&
|
||||
iocommand.Request.Type.Direction != XFER_NONE)
|
||||
return -EINVAL;
|
||||
if (iocommand.Request.CDBLen > sizeof(request.cdb))
|
||||
return -EINVAL;
|
||||
if (iocommand.Request.Type.Type != TYPE_CMD)
|
||||
return -EINVAL;
|
||||
|
||||
switch (iocommand.Request.Type.Direction) {
|
||||
case XFER_NONE:
|
||||
case XFER_WRITE:
|
||||
case XFER_READ:
|
||||
case XFER_READ | XFER_WRITE:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (iocommand.buf_size > 0) {
|
||||
kernel_buffer = kmalloc(iocommand.buf_size, GFP_KERNEL);
|
||||
if (!kernel_buffer)
|
||||
return -ENOMEM;
|
||||
if (iocommand.Request.Type.Direction & XFER_WRITE) {
|
||||
if (copy_from_user(kernel_buffer, iocommand.buf,
|
||||
iocommand.buf_size)) {
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
memset(kernel_buffer, 0, iocommand.buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
request.header.iu_type = PQI_REQUEST_IU_RAID_PATH_IO;
|
||||
iu_length = offsetof(struct pqi_raid_path_request, sg_descriptors) -
|
||||
PQI_REQUEST_HEADER_LENGTH;
|
||||
memcpy(request.lun_number, iocommand.LUN_info.LunAddrBytes, sizeof(request.lun_number));
|
||||
memcpy(request.cdb, iocommand.Request.CDB, iocommand.Request.CDBLen);
|
||||
request.additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_0;
|
||||
|
||||
switch (iocommand.Request.Type.Direction) {
|
||||
case XFER_NONE:
|
||||
request.data_direction = SOP_NO_DIRECTION_FLAG;
|
||||
break;
|
||||
case XFER_WRITE:
|
||||
request.data_direction = SOP_WRITE_FLAG;
|
||||
break;
|
||||
case XFER_READ:
|
||||
request.data_direction = SOP_READ_FLAG;
|
||||
break;
|
||||
case XFER_READ | XFER_WRITE:
|
||||
request.data_direction = SOP_BIDIRECTIONAL;
|
||||
break;
|
||||
}
|
||||
|
||||
request.task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE;
|
||||
|
||||
if (iocommand.buf_size > 0) {
|
||||
put_unaligned_le32(iocommand.buf_size, &request.buffer_length);
|
||||
|
||||
rc = pqi_map_single(ctrl_info->pci_dev,
|
||||
&request.sg_descriptors[0], kernel_buffer,
|
||||
iocommand.buf_size, DMA_BIDIRECTIONAL);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
iu_length += sizeof(request.sg_descriptors[0]);
|
||||
}
|
||||
|
||||
put_unaligned_le16(iu_length, &request.header.iu_length);
|
||||
|
||||
if (ctrl_info->raid_iu_timeout_supported)
|
||||
put_unaligned_le32(iocommand.Request.Timeout, &request.timeout);
|
||||
|
||||
rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
|
||||
PQI_SYNC_FLAGS_INTERRUPTABLE, &pqi_error_info);
|
||||
|
||||
if (iocommand.buf_size > 0)
|
||||
pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, DMA_BIDIRECTIONAL);
|
||||
|
||||
memset(&iocommand.error_info, 0, sizeof(iocommand.error_info));
|
||||
|
||||
if (rc == 0) {
|
||||
pqi_error_info_to_ciss(&pqi_error_info, &ciss_error_info);
|
||||
iocommand.error_info.ScsiStatus = ciss_error_info.scsi_status;
|
||||
iocommand.error_info.CommandStatus = ciss_error_info.command_status;
|
||||
sense_data_length = ciss_error_info.sense_data_length;
|
||||
if (sense_data_length) {
|
||||
if (sense_data_length > sizeof(iocommand.error_info.SenseInfo))
|
||||
sense_data_length = sizeof(iocommand.error_info.SenseInfo);
|
||||
memcpy(iocommand.error_info.SenseInfo,
|
||||
pqi_error_info.data, sense_data_length);
|
||||
iocommand.error_info.SenseLen = sense_data_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user(arg, &iocommand, sizeof(iocommand))) {
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rc == 0 && iocommand.buf_size > 0 &&
|
||||
(iocommand.Request.Type.Direction & XFER_READ)) {
|
||||
if (copy_to_user(iocommand.buf, kernel_buffer,
|
||||
iocommand.buf_size)) {
|
||||
rc = -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(kernel_buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd,
|
||||
void __user *arg)
|
||||
{
|
||||
@@ -6941,6 +7096,12 @@ static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd,
|
||||
case CCISS_PASSTHRU:
|
||||
rc = pqi_passthru_ioctl(ctrl_info, arg);
|
||||
break;
|
||||
case CCISS_BIG_PASSTHRU:
|
||||
rc = pqi_big_passthru_ioctl(ctrl_info, arg);
|
||||
break;
|
||||
case CCISS_BIG_PASSTHRU_SUPPORTED:
|
||||
rc = 0;
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
@@ -7612,6 +7773,7 @@ static const struct scsi_host_template pqi_driver_template = {
|
||||
.sdev_groups = pqi_sdev_groups,
|
||||
.shost_groups = pqi_shost_groups,
|
||||
.cmd_size = sizeof(struct pqi_cmd_priv),
|
||||
.init_cmd_priv = pqi_init_cmd_priv,
|
||||
};
|
||||
|
||||
static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info)
|
||||
@@ -10152,10 +10314,30 @@ static const struct pci_device_id pqi_pci_id_table[] = {
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4240)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4246)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4256)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4356)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4840)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4940)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x207d, 0x4a46)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x8312)
|
||||
@@ -10340,6 +10522,18 @@ static const struct pci_device_id pqi_pci_id_table[] = {
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1cf2, 0x544f)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1cf2, 0x5451)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1cf2, 0x5452)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1cf2, 0x5453)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1cf2, 0x54da)
|
||||
@@ -10380,6 +10574,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1f3f, 0x0610)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
0x1f3f, 0x0670)
|
||||
},
|
||||
{
|
||||
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
|
||||
PCI_VENDOR_ID_LENOVO, 0x0220)
|
||||
|
||||
@@ -85,5 +85,6 @@ typedef struct _LogvolInfo_struct{
|
||||
#define CCISS_RESCANDISK _IO(CCISS_IOC_MAGIC, 16)
|
||||
#define CCISS_GETLUNINFO _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
|
||||
#define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
|
||||
#define CCISS_BIG_PASSTHRU_SUPPORTED _IO(CCISS_IOC_MAGIC, 19)
|
||||
|
||||
#endif /* _UAPICCISS_IOCTLH */
|
||||
|
||||
Reference in New Issue
Block a user