mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 13:13:57 +08:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: [SCSI] psi240i.c: fix an array overrun [SCSI] gdth: Fix && typos [SCSI] iscsi class: update version [SCSI] iscsi_tcp: fix xmittask oops [SCSI] iscsi: add newlines to debug messages [SCSI] iscsi: always release crypto [SCSI] sg: fix incorrect last scatg length [SCSI] 3ware 9000 add support for 9650SE [SCSI] aic94xx SCSI timeout fix: SMP retry fix. [SCSI] aic94xx SCSI timeout fix
This commit is contained in:
commit
d0cac32fa5
@ -66,6 +66,9 @@
|
|||||||
2.26.02.006 - Fix 9550SX pchip reset timeout.
|
2.26.02.006 - Fix 9550SX pchip reset timeout.
|
||||||
Add big endian support.
|
Add big endian support.
|
||||||
2.26.02.007 - Disable local interrupts during kmap/unmap_atomic().
|
2.26.02.007 - Disable local interrupts during kmap/unmap_atomic().
|
||||||
|
2.26.02.008 - Free irq handler in __twa_shutdown().
|
||||||
|
Serialize reset code.
|
||||||
|
Add support for 9650SE controllers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -89,7 +92,7 @@
|
|||||||
#include "3w-9xxx.h"
|
#include "3w-9xxx.h"
|
||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
#define TW_DRIVER_VERSION "2.26.02.007"
|
#define TW_DRIVER_VERSION "2.26.02.008"
|
||||||
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
|
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
|
||||||
static unsigned int twa_device_extension_count;
|
static unsigned int twa_device_extension_count;
|
||||||
static int twa_major = -1;
|
static int twa_major = -1;
|
||||||
@ -566,9 +569,9 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
tw_dev->working_srl = fw_on_ctlr_srl;
|
tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl;
|
||||||
tw_dev->working_branch = fw_on_ctlr_branch;
|
tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch;
|
||||||
tw_dev->working_build = fw_on_ctlr_build;
|
tw_dev->tw_compat_info.working_build = fw_on_ctlr_build;
|
||||||
|
|
||||||
/* Try base mode compatibility */
|
/* Try base mode compatibility */
|
||||||
if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
|
if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
|
||||||
@ -590,10 +593,23 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
|
|||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tw_dev->working_srl = TW_BASE_FW_SRL;
|
tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL;
|
||||||
tw_dev->working_branch = TW_BASE_FW_BRANCH;
|
tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH;
|
||||||
tw_dev->working_build = TW_BASE_FW_BUILD;
|
tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load rest of compatibility struct */
|
||||||
|
strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
|
||||||
|
tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
|
||||||
|
tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
|
||||||
|
tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
|
||||||
|
tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
|
||||||
|
tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
|
||||||
|
tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
|
||||||
|
tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
|
||||||
|
tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
|
||||||
|
tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
out:
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
@ -631,7 +647,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
|
|||||||
goto out2;
|
goto out2;
|
||||||
|
|
||||||
/* Check data buffer size */
|
/* Check data buffer size */
|
||||||
if (driver_command.buffer_length > TW_MAX_SECTORS * 512) {
|
if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
|
||||||
retval = TW_IOCTL_ERROR_OS_EINVAL;
|
retval = TW_IOCTL_ERROR_OS_EINVAL;
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
@ -680,13 +696,6 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
|
|||||||
/* Now wait for command to complete */
|
/* Now wait for command to complete */
|
||||||
timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
|
timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
|
||||||
|
|
||||||
/* See if we reset while waiting for the ioctl to complete */
|
|
||||||
if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
|
|
||||||
clear_bit(TW_IN_RESET, &tw_dev->flags);
|
|
||||||
retval = TW_IOCTL_ERROR_OS_ERESTARTSYS;
|
|
||||||
goto out3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We timed out, and didn't get an interrupt */
|
/* We timed out, and didn't get an interrupt */
|
||||||
if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
|
if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
|
||||||
/* Now we need to reset the board */
|
/* Now we need to reset the board */
|
||||||
@ -694,11 +703,6 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
|
|||||||
tw_dev->host->host_no, TW_DRIVER, 0xc,
|
tw_dev->host->host_no, TW_DRIVER, 0xc,
|
||||||
cmd);
|
cmd);
|
||||||
retval = TW_IOCTL_ERROR_OS_EIO;
|
retval = TW_IOCTL_ERROR_OS_EIO;
|
||||||
spin_lock_irqsave(tw_dev->host->host_lock, flags);
|
|
||||||
tw_dev->state[request_id] = TW_S_COMPLETED;
|
|
||||||
twa_free_request_id(tw_dev, request_id);
|
|
||||||
tw_dev->posted_request_count--;
|
|
||||||
spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
|
|
||||||
twa_reset_device_extension(tw_dev, 1);
|
twa_reset_device_extension(tw_dev, 1);
|
||||||
goto out3;
|
goto out3;
|
||||||
}
|
}
|
||||||
@ -717,16 +721,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
|
|||||||
tw_ioctl->driver_command.status = 0;
|
tw_ioctl->driver_command.status = 0;
|
||||||
/* Copy compatiblity struct into ioctl data buffer */
|
/* Copy compatiblity struct into ioctl data buffer */
|
||||||
tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
|
tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
|
||||||
strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
|
memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
|
||||||
tw_compat_info->working_srl = tw_dev->working_srl;
|
|
||||||
tw_compat_info->working_branch = tw_dev->working_branch;
|
|
||||||
tw_compat_info->working_build = tw_dev->working_build;
|
|
||||||
tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL;
|
|
||||||
tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
|
|
||||||
tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD;
|
|
||||||
tw_compat_info->driver_srl_low = TW_BASE_FW_SRL;
|
|
||||||
tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH;
|
|
||||||
tw_compat_info->driver_build_low = TW_BASE_FW_BUILD;
|
|
||||||
break;
|
break;
|
||||||
case TW_IOCTL_GET_LAST_EVENT:
|
case TW_IOCTL_GET_LAST_EVENT:
|
||||||
if (tw_dev->event_queue_wrapped) {
|
if (tw_dev->event_queue_wrapped) {
|
||||||
@ -895,7 +890,8 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
|
if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
|
if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags)))
|
||||||
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
|
||||||
writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
|
writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,10 +935,12 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
|
|||||||
unsigned long before;
|
unsigned long before;
|
||||||
int retval = 1;
|
int retval = 1;
|
||||||
|
|
||||||
if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) {
|
if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) ||
|
||||||
|
(tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) {
|
||||||
before = jiffies;
|
before = jiffies;
|
||||||
while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
|
while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
|
||||||
response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
|
response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
|
||||||
|
msleep(1);
|
||||||
if (time_after(jiffies, before + HZ * 30))
|
if (time_after(jiffies, before + HZ * 30))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1214,6 +1212,10 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
|
|||||||
|
|
||||||
handled = 1;
|
handled = 1;
|
||||||
|
|
||||||
|
/* If we are resetting, bail */
|
||||||
|
if (test_bit(TW_IN_RESET, &tw_dev->flags))
|
||||||
|
goto twa_interrupt_bail;
|
||||||
|
|
||||||
/* Check controller for errors */
|
/* Check controller for errors */
|
||||||
if (twa_check_bits(status_reg_value)) {
|
if (twa_check_bits(status_reg_value)) {
|
||||||
if (twa_decode_bits(tw_dev, status_reg_value)) {
|
if (twa_decode_bits(tw_dev, status_reg_value)) {
|
||||||
@ -1355,8 +1357,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d
|
|||||||
|
|
||||||
if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
|
if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
|
||||||
newcommand = &full_command_packet->command.newcommand;
|
newcommand = &full_command_packet->command.newcommand;
|
||||||
newcommand->request_id__lunl =
|
newcommand->request_id__lunl =
|
||||||
TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id);
|
cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
|
||||||
newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
|
newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
|
||||||
newcommand->sg_list[0].length = cpu_to_le32(length);
|
newcommand->sg_list[0].length = cpu_to_le32(length);
|
||||||
newcommand->sgl_entries__lunh =
|
newcommand->sgl_entries__lunh =
|
||||||
@ -1531,6 +1533,13 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id,
|
|||||||
int retval = 1;
|
int retval = 1;
|
||||||
|
|
||||||
command_que_value = tw_dev->command_packet_phys[request_id];
|
command_que_value = tw_dev->command_packet_phys[request_id];
|
||||||
|
|
||||||
|
/* For 9650SE write low 4 bytes first */
|
||||||
|
if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
|
||||||
|
command_que_value += TW_COMMAND_OFFSET;
|
||||||
|
writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev));
|
||||||
|
}
|
||||||
|
|
||||||
status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
|
status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
|
||||||
|
|
||||||
if (twa_check_bits(status_reg_value))
|
if (twa_check_bits(status_reg_value))
|
||||||
@ -1557,13 +1566,17 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id,
|
|||||||
TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
|
TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
/* We successfully posted the command packet */
|
if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
|
||||||
if (sizeof(dma_addr_t) > 4) {
|
/* Now write upper 4 bytes */
|
||||||
command_que_value += TW_COMMAND_OFFSET;
|
writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4);
|
||||||
writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
|
|
||||||
writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4);
|
|
||||||
} else {
|
} else {
|
||||||
writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
|
if (sizeof(dma_addr_t) > 4) {
|
||||||
|
command_que_value += TW_COMMAND_OFFSET;
|
||||||
|
writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
|
||||||
|
writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4);
|
||||||
|
} else {
|
||||||
|
writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tw_dev->state[request_id] = TW_S_POSTED;
|
tw_dev->state[request_id] = TW_S_POSTED;
|
||||||
tw_dev->posted_request_count++;
|
tw_dev->posted_request_count++;
|
||||||
@ -1620,14 +1633,9 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
|
TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
|
||||||
|
clear_bit(TW_IN_RESET, &tw_dev->flags);
|
||||||
|
tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
|
||||||
|
|
||||||
/* Wake up any ioctl that was pending before the reset */
|
|
||||||
if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) {
|
|
||||||
clear_bit(TW_IN_RESET, &tw_dev->flags);
|
|
||||||
} else {
|
|
||||||
tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
|
|
||||||
wake_up(&tw_dev->ioctl_wqueue);
|
|
||||||
}
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
out:
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
@ -1736,6 +1744,9 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
|||||||
"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
|
"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
|
||||||
TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
|
TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
|
||||||
|
|
||||||
|
/* Make sure we are not issuing an ioctl or resetting from ioctl */
|
||||||
|
mutex_lock(&tw_dev->ioctl_lock);
|
||||||
|
|
||||||
/* Now reset the card and some of the device extension data */
|
/* Now reset the card and some of the device extension data */
|
||||||
if (twa_reset_device_extension(tw_dev, 0)) {
|
if (twa_reset_device_extension(tw_dev, 0)) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
|
||||||
@ -1744,6 +1755,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
|||||||
|
|
||||||
retval = SUCCESS;
|
retval = SUCCESS;
|
||||||
out:
|
out:
|
||||||
|
mutex_unlock(&tw_dev->ioctl_lock);
|
||||||
return retval;
|
return retval;
|
||||||
} /* End twa_scsi_eh_reset() */
|
} /* End twa_scsi_eh_reset() */
|
||||||
|
|
||||||
@ -1753,8 +1765,14 @@ static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
|
|||||||
int request_id, retval;
|
int request_id, retval;
|
||||||
TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
|
TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
|
||||||
|
|
||||||
|
/* If we are resetting due to timed out ioctl, report as busy */
|
||||||
|
if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
|
||||||
|
retval = SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if this FW supports luns */
|
/* Check if this FW supports luns */
|
||||||
if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) {
|
if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) {
|
||||||
SCpnt->result = (DID_BAD_TARGET << 16);
|
SCpnt->result = (DID_BAD_TARGET << 16);
|
||||||
done(SCpnt);
|
done(SCpnt);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -1960,6 +1978,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev)
|
|||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
TW_DISABLE_INTERRUPTS(tw_dev);
|
TW_DISABLE_INTERRUPTS(tw_dev);
|
||||||
|
|
||||||
|
/* Free up the IRQ */
|
||||||
|
free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
|
||||||
|
|
||||||
printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
|
printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
|
||||||
|
|
||||||
/* Tell the card we are shutting down */
|
/* Tell the card we are shutting down */
|
||||||
@ -2091,21 +2112,25 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
|
|||||||
|
|
||||||
/* Initialize the card */
|
/* Initialize the card */
|
||||||
if (twa_reset_sequence(tw_dev, 0))
|
if (twa_reset_sequence(tw_dev, 0))
|
||||||
goto out_release_mem_region;
|
goto out_iounmap;
|
||||||
|
|
||||||
/* Set host specific parameters */
|
/* Set host specific parameters */
|
||||||
host->max_id = TW_MAX_UNITS;
|
if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE)
|
||||||
|
host->max_id = TW_MAX_UNITS_9650SE;
|
||||||
|
else
|
||||||
|
host->max_id = TW_MAX_UNITS;
|
||||||
|
|
||||||
host->max_cmd_len = TW_MAX_CDB_LEN;
|
host->max_cmd_len = TW_MAX_CDB_LEN;
|
||||||
|
|
||||||
/* Channels aren't supported by adapter */
|
/* Channels aren't supported by adapter */
|
||||||
host->max_lun = TW_MAX_LUNS(tw_dev->working_srl);
|
host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl);
|
||||||
host->max_channel = 0;
|
host->max_channel = 0;
|
||||||
|
|
||||||
/* Register the card with the kernel SCSI layer */
|
/* Register the card with the kernel SCSI layer */
|
||||||
retval = scsi_add_host(host, &pdev->dev);
|
retval = scsi_add_host(host, &pdev->dev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
|
||||||
goto out_release_mem_region;
|
goto out_iounmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_set_drvdata(pdev, host);
|
pci_set_drvdata(pdev, host);
|
||||||
@ -2145,6 +2170,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
|
|||||||
|
|
||||||
out_remove_host:
|
out_remove_host:
|
||||||
scsi_remove_host(host);
|
scsi_remove_host(host);
|
||||||
|
out_iounmap:
|
||||||
|
iounmap(tw_dev->base_addr);
|
||||||
out_release_mem_region:
|
out_release_mem_region:
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
out_free_device_extension:
|
out_free_device_extension:
|
||||||
@ -2170,12 +2197,12 @@ static void twa_remove(struct pci_dev *pdev)
|
|||||||
twa_major = -1;
|
twa_major = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free up the IRQ */
|
|
||||||
free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
|
|
||||||
|
|
||||||
/* Shutdown the card */
|
/* Shutdown the card */
|
||||||
__twa_shutdown(tw_dev);
|
__twa_shutdown(tw_dev);
|
||||||
|
|
||||||
|
/* Free IO remapping */
|
||||||
|
iounmap(tw_dev->base_addr);
|
||||||
|
|
||||||
/* Free up the mem region */
|
/* Free up the mem region */
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
|
||||||
@ -2193,6 +2220,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = {
|
|||||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||||
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX,
|
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX,
|
||||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||||
|
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
|
||||||
|
@ -289,7 +289,6 @@ static twa_message_type twa_error_table[] = {
|
|||||||
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
|
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
|
||||||
|
|
||||||
/* PCI related defines */
|
/* PCI related defines */
|
||||||
#define TW_NUMDEVICES 1
|
|
||||||
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
|
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
|
||||||
#define TW_PCI_CLEAR_PCI_ABORT 0x2000
|
#define TW_PCI_CLEAR_PCI_ABORT 0x2000
|
||||||
|
|
||||||
@ -335,6 +334,7 @@ static twa_message_type twa_error_table[] = {
|
|||||||
#define TW_ALIGNMENT_9000 4 /* 4 bytes */
|
#define TW_ALIGNMENT_9000 4 /* 4 bytes */
|
||||||
#define TW_ALIGNMENT_9000_SGL 0x3
|
#define TW_ALIGNMENT_9000_SGL 0x3
|
||||||
#define TW_MAX_UNITS 16
|
#define TW_MAX_UNITS 16
|
||||||
|
#define TW_MAX_UNITS_9650SE 32
|
||||||
#define TW_INIT_MESSAGE_CREDITS 0x100
|
#define TW_INIT_MESSAGE_CREDITS 0x100
|
||||||
#define TW_INIT_COMMAND_PACKET_SIZE 0x3
|
#define TW_INIT_COMMAND_PACKET_SIZE 0x3
|
||||||
#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6
|
#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6
|
||||||
@ -354,7 +354,6 @@ static twa_message_type twa_error_table[] = {
|
|||||||
#define TW_MAX_RESPONSE_DRAIN 256
|
#define TW_MAX_RESPONSE_DRAIN 256
|
||||||
#define TW_MAX_AEN_DRAIN 40
|
#define TW_MAX_AEN_DRAIN 40
|
||||||
#define TW_IN_RESET 2
|
#define TW_IN_RESET 2
|
||||||
#define TW_IN_CHRDEV_IOCTL 3
|
|
||||||
#define TW_IN_ATTENTION_LOOP 4
|
#define TW_IN_ATTENTION_LOOP 4
|
||||||
#define TW_MAX_SECTORS 256
|
#define TW_MAX_SECTORS 256
|
||||||
#define TW_AEN_WAIT_TIME 1000
|
#define TW_AEN_WAIT_TIME 1000
|
||||||
@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = {
|
|||||||
#ifndef PCI_DEVICE_ID_3WARE_9550SX
|
#ifndef PCI_DEVICE_ID_3WARE_9550SX
|
||||||
#define PCI_DEVICE_ID_3WARE_9550SX 0x1003
|
#define PCI_DEVICE_ID_3WARE_9550SX 0x1003
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef PCI_DEVICE_ID_3WARE_9650SE
|
||||||
|
#define PCI_DEVICE_ID_3WARE_9650SE 0x1004
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Bitmask macros to eliminate bitfields */
|
/* Bitmask macros to eliminate bitfields */
|
||||||
|
|
||||||
@ -442,6 +444,7 @@ static twa_message_type twa_error_table[] = {
|
|||||||
#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
|
#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
|
||||||
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
|
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
|
||||||
#define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
|
#define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
|
||||||
|
#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20)
|
||||||
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
|
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
|
||||||
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
|
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
|
||||||
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||||
@ -626,6 +629,9 @@ typedef struct TAG_TW_Compatibility_Info
|
|||||||
unsigned short driver_srl_low;
|
unsigned short driver_srl_low;
|
||||||
unsigned short driver_branch_low;
|
unsigned short driver_branch_low;
|
||||||
unsigned short driver_build_low;
|
unsigned short driver_build_low;
|
||||||
|
unsigned short fw_on_ctlr_srl;
|
||||||
|
unsigned short fw_on_ctlr_branch;
|
||||||
|
unsigned short fw_on_ctlr_build;
|
||||||
} TW_Compatibility_Info;
|
} TW_Compatibility_Info;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
@ -668,9 +674,7 @@ typedef struct TAG_TW_Device_Extension {
|
|||||||
wait_queue_head_t ioctl_wqueue;
|
wait_queue_head_t ioctl_wqueue;
|
||||||
struct mutex ioctl_lock;
|
struct mutex ioctl_lock;
|
||||||
char aen_clobber;
|
char aen_clobber;
|
||||||
unsigned short working_srl;
|
TW_Compatibility_Info tw_compat_info;
|
||||||
unsigned short working_branch;
|
|
||||||
unsigned short working_build;
|
|
||||||
} TW_Device_Extension;
|
} TW_Device_Extension;
|
||||||
|
|
||||||
#endif /* _3W_9XXX_H */
|
#endif /* _3W_9XXX_H */
|
||||||
|
@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *phy)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asd_init_ports(struct asd_ha_struct *asd_ha)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
spin_lock_init(&asd_ha->asd_ports_lock);
|
||||||
|
for (i = 0; i < ASD_MAX_PHYS; i++) {
|
||||||
|
struct asd_port *asd_port = &asd_ha->asd_ports[i];
|
||||||
|
|
||||||
|
memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE);
|
||||||
|
memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE);
|
||||||
|
asd_port->phy_mask = 0;
|
||||||
|
asd_port->num_phys = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int asd_init_phys(struct asd_ha_struct *asd_ha)
|
static int asd_init_phys(struct asd_ha_struct *asd_ha)
|
||||||
{
|
{
|
||||||
u8 i;
|
u8 i;
|
||||||
@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha)
|
|||||||
struct asd_phy *phy = &asd_ha->phys[i];
|
struct asd_phy *phy = &asd_ha->phys[i];
|
||||||
|
|
||||||
phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
|
phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
|
||||||
|
phy->asd_port = NULL;
|
||||||
|
|
||||||
phy->sas_phy.enabled = 0;
|
phy->sas_phy.enabled = 0;
|
||||||
phy->sas_phy.id = i;
|
phy->sas_phy.id = i;
|
||||||
@ -658,6 +674,8 @@ int asd_init_hw(struct asd_ha_struct *asd_ha)
|
|||||||
goto Out;
|
goto Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asd_init_ports(asd_ha);
|
||||||
|
|
||||||
err = asd_init_scbs(asd_ha);
|
err = asd_init_scbs(asd_ha);
|
||||||
if (err) {
|
if (err) {
|
||||||
asd_printk("couldn't initialize scbs for %s\n",
|
asd_printk("couldn't initialize scbs for %s\n",
|
||||||
|
@ -193,6 +193,16 @@ struct asd_seq_data {
|
|||||||
struct asd_ascb **escb_arr; /* array of pointers to escbs */
|
struct asd_ascb **escb_arr; /* array of pointers to escbs */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This is an internal port structure. These are used to get accurate
|
||||||
|
* phy_mask for updating DDB 0.
|
||||||
|
*/
|
||||||
|
struct asd_port {
|
||||||
|
u8 sas_addr[SAS_ADDR_SIZE];
|
||||||
|
u8 attached_sas_addr[SAS_ADDR_SIZE];
|
||||||
|
u32 phy_mask;
|
||||||
|
int num_phys;
|
||||||
|
};
|
||||||
|
|
||||||
/* This is the Host Adapter structure. It describes the hardware
|
/* This is the Host Adapter structure. It describes the hardware
|
||||||
* SAS adapter.
|
* SAS adapter.
|
||||||
*/
|
*/
|
||||||
@ -211,6 +221,8 @@ struct asd_ha_struct {
|
|||||||
struct hw_profile hw_prof;
|
struct hw_profile hw_prof;
|
||||||
|
|
||||||
struct asd_phy phys[ASD_MAX_PHYS];
|
struct asd_phy phys[ASD_MAX_PHYS];
|
||||||
|
spinlock_t asd_ports_lock;
|
||||||
|
struct asd_port asd_ports[ASD_MAX_PHYS];
|
||||||
struct asd_sas_port ports[ASD_MAX_PHYS];
|
struct asd_sas_port ports[ASD_MAX_PHYS];
|
||||||
|
|
||||||
struct dma_pool *scb_pool;
|
struct dma_pool *scb_pool;
|
||||||
|
@ -786,8 +786,6 @@ static void asd_remove_driver_attrs(struct device_driver *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct sas_domain_function_template aic94xx_transport_functions = {
|
static struct sas_domain_function_template aic94xx_transport_functions = {
|
||||||
.lldd_port_formed = asd_update_port_links,
|
|
||||||
|
|
||||||
.lldd_dev_found = asd_dev_found,
|
.lldd_dev_found = asd_dev_found,
|
||||||
.lldd_dev_gone = asd_dev_gone,
|
.lldd_dev_gone = asd_dev_gone,
|
||||||
|
|
||||||
|
@ -733,6 +733,7 @@ struct asd_phy {
|
|||||||
|
|
||||||
struct sas_identify_frame *identify_frame;
|
struct sas_identify_frame *identify_frame;
|
||||||
struct asd_dma_tok *id_frm_tok;
|
struct asd_dma_tok *id_frm_tok;
|
||||||
|
struct asd_port *asd_port;
|
||||||
|
|
||||||
u8 frame_rcvd[ASD_EDB_SIZE];
|
u8 frame_rcvd[ASD_EDB_SIZE];
|
||||||
};
|
};
|
||||||
|
@ -168,6 +168,70 @@ static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct asd_port *free_port = NULL;
|
||||||
|
struct asd_port *port;
|
||||||
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
|
||||||
|
if (!phy->asd_port) {
|
||||||
|
for (i = 0; i < ASD_MAX_PHYS; i++) {
|
||||||
|
port = &asd_ha->asd_ports[i];
|
||||||
|
|
||||||
|
/* Check for wide port */
|
||||||
|
if (port->num_phys > 0 &&
|
||||||
|
memcmp(port->sas_addr, sas_phy->sas_addr,
|
||||||
|
SAS_ADDR_SIZE) == 0 &&
|
||||||
|
memcmp(port->attached_sas_addr,
|
||||||
|
sas_phy->attached_sas_addr,
|
||||||
|
SAS_ADDR_SIZE) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find a free port */
|
||||||
|
if (port->num_phys == 0 && free_port == NULL) {
|
||||||
|
free_port = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use a free port if this doesn't form a wide port */
|
||||||
|
if (i >= ASD_MAX_PHYS) {
|
||||||
|
port = free_port;
|
||||||
|
BUG_ON(!port);
|
||||||
|
memcpy(port->sas_addr, sas_phy->sas_addr,
|
||||||
|
SAS_ADDR_SIZE);
|
||||||
|
memcpy(port->attached_sas_addr,
|
||||||
|
sas_phy->attached_sas_addr,
|
||||||
|
SAS_ADDR_SIZE);
|
||||||
|
}
|
||||||
|
port->num_phys++;
|
||||||
|
port->phy_mask |= (1U << sas_phy->id);
|
||||||
|
phy->asd_port = port;
|
||||||
|
}
|
||||||
|
ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n",
|
||||||
|
__FUNCTION__, phy->asd_port->phy_mask, sas_phy->id);
|
||||||
|
asd_update_port_links(asd_ha, phy);
|
||||||
|
spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
|
||||||
|
{
|
||||||
|
struct asd_port *port = phy->asd_port;
|
||||||
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
|
||||||
|
if (port) {
|
||||||
|
port->num_phys--;
|
||||||
|
port->phy_mask &= ~(1U << sas_phy->id);
|
||||||
|
phy->asd_port = NULL;
|
||||||
|
}
|
||||||
|
spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
||||||
struct done_list_struct *dl,
|
struct done_list_struct *dl,
|
||||||
int edb_id, int phy_id)
|
int edb_id, int phy_id)
|
||||||
@ -187,6 +251,7 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
|||||||
asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
|
asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
|
||||||
spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
|
spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||||
asd_dump_frame_rcvd(phy, dl);
|
asd_dump_frame_rcvd(phy, dl);
|
||||||
|
asd_form_port(ascb->ha, phy);
|
||||||
sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
|
sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +262,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
|
|||||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||||
struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
|
struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
|
||||||
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
|
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
|
||||||
|
struct asd_phy *phy = &asd_ha->phys[phy_id];
|
||||||
u8 lr_error = dl->status_block[1];
|
u8 lr_error = dl->status_block[1];
|
||||||
u8 retries_left = dl->status_block[2];
|
u8 retries_left = dl->status_block[2];
|
||||||
|
|
||||||
@ -221,6 +287,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
|
|||||||
|
|
||||||
asd_turn_led(asd_ha, phy_id, 0);
|
asd_turn_led(asd_ha, phy_id, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
|
asd_deform_port(asd_ha, phy);
|
||||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||||
|
|
||||||
if (retries_left == 0) {
|
if (retries_left == 0) {
|
||||||
@ -248,6 +315,8 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
|
struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
|
||||||
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
|
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
|
||||||
|
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||||
|
struct asd_phy *phy = &asd_ha->phys[phy_id];
|
||||||
u8 reg = dl->status_block[1];
|
u8 reg = dl->status_block[1];
|
||||||
u32 cont = dl->status_block[2] << ((reg & 3)*8);
|
u32 cont = dl->status_block[2] << ((reg & 3)*8);
|
||||||
|
|
||||||
@ -284,6 +353,7 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
|||||||
phy_id);
|
phy_id);
|
||||||
/* The sequencer disables all phys on that port.
|
/* The sequencer disables all phys on that port.
|
||||||
* We have to re-enable the phys ourselves. */
|
* We have to re-enable the phys ourselves. */
|
||||||
|
asd_deform_port(asd_ha, phy);
|
||||||
sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
|
sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -351,6 +421,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
|||||||
u8 sb_opcode = dl->status_block[0];
|
u8 sb_opcode = dl->status_block[0];
|
||||||
int phy_id = sb_opcode & DL_PHY_MASK;
|
int phy_id = sb_opcode & DL_PHY_MASK;
|
||||||
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
|
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
|
||||||
|
struct asd_phy *phy = &asd_ha->phys[phy_id];
|
||||||
|
|
||||||
if (edb > 6 || edb < 0) {
|
if (edb > 6 || edb < 0) {
|
||||||
ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
|
ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
|
||||||
@ -395,6 +466,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
|||||||
asd_turn_led(asd_ha, phy_id, 0);
|
asd_turn_led(asd_ha, phy_id, 0);
|
||||||
/* the device is gone */
|
/* the device is gone */
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
|
asd_deform_port(asd_ha, phy);
|
||||||
sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
|
sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
|
||||||
break;
|
break;
|
||||||
case REQ_TASK_ABORT:
|
case REQ_TASK_ABORT:
|
||||||
|
@ -1369,10 +1369,9 @@ int asd_start_seqs(struct asd_ha_struct *asd_ha)
|
|||||||
* port_map_by_links is also used as the conn_mask byte in the
|
* port_map_by_links is also used as the conn_mask byte in the
|
||||||
* initiator/target port DDB.
|
* initiator/target port DDB.
|
||||||
*/
|
*/
|
||||||
void asd_update_port_links(struct asd_sas_phy *sas_phy)
|
void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
|
||||||
{
|
{
|
||||||
struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha;
|
const u8 phy_mask = (u8) phy->asd_port->phy_mask;
|
||||||
const u8 phy_mask = (u8) sas_phy->port->phy_mask;
|
|
||||||
u8 phy_is_up;
|
u8 phy_is_up;
|
||||||
u8 mask;
|
u8 mask;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
@ -64,7 +64,7 @@ int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
|
|||||||
int asd_init_seqs(struct asd_ha_struct *asd_ha);
|
int asd_init_seqs(struct asd_ha_struct *asd_ha);
|
||||||
int asd_start_seqs(struct asd_ha_struct *asd_ha);
|
int asd_start_seqs(struct asd_ha_struct *asd_ha);
|
||||||
|
|
||||||
void asd_update_port_links(struct asd_sas_phy *phy);
|
void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3531,7 +3531,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id)
|
|||||||
IStatus &= ~0x80;
|
IStatus &= ~0x80;
|
||||||
#ifdef INT_COAL
|
#ifdef INT_COAL
|
||||||
if (coalesced)
|
if (coalesced)
|
||||||
ha->status = pcs->ext_status && 0xffff;
|
ha->status = pcs->ext_status & 0xffff;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
ha->status = gdth_readw(&dp6m_ptr->i960r.status);
|
ha->status = gdth_readw(&dp6m_ptr->i960r.status);
|
||||||
@ -3543,7 +3543,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id)
|
|||||||
if (coalesced) {
|
if (coalesced) {
|
||||||
ha->info = pcs->info0;
|
ha->info = pcs->info0;
|
||||||
ha->info2 = pcs->info1;
|
ha->info2 = pcs->info1;
|
||||||
ha->service = (pcs->ext_status >> 16) && 0xffff;
|
ha->service = (pcs->ext_status >> 16) & 0xffff;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
iscsi_solicit_data_init(conn, ctask, r2t);
|
iscsi_solicit_data_init(conn, ctask, r2t);
|
||||||
|
|
||||||
tcp_ctask->exp_r2tsn = r2tsn + 1;
|
tcp_ctask->exp_r2tsn = r2tsn + 1;
|
||||||
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
|
|
||||||
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
|
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
|
||||||
|
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
|
||||||
list_move_tail(&ctask->running, &conn->xmitqueue);
|
list_move_tail(&ctask->running, &conn->xmitqueue);
|
||||||
|
|
||||||
scsi_queue_work(session->host, &conn->xmitwork);
|
scsi_queue_work(session->host, &conn->xmitwork);
|
||||||
@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
|
|||||||
if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
|
if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
|
||||||
tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
|
tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
|
||||||
tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
|
tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
|
||||||
if (!tcp_ctask->r2t)
|
if (!tcp_ctask->r2t) {
|
||||||
|
spin_lock_bh(&session->lock);
|
||||||
__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
|
__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
|
||||||
sizeof(void*));
|
sizeof(void*));
|
||||||
|
spin_unlock_bh(&session->lock);
|
||||||
|
}
|
||||||
send_hdr:
|
send_hdr:
|
||||||
r2t = tcp_ctask->r2t;
|
r2t = tcp_ctask->r2t;
|
||||||
dtask = &r2t->dtask;
|
dtask = &r2t->dtask;
|
||||||
@ -1816,21 +1819,14 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
|
|||||||
{
|
{
|
||||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||||
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
|
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
|
||||||
int digest = 0;
|
|
||||||
|
|
||||||
if (conn->hdrdgst_en || conn->datadgst_en)
|
|
||||||
digest = 1;
|
|
||||||
|
|
||||||
iscsi_tcp_release_conn(conn);
|
iscsi_tcp_release_conn(conn);
|
||||||
iscsi_conn_teardown(cls_conn);
|
iscsi_conn_teardown(cls_conn);
|
||||||
|
|
||||||
/* now free tcp_conn */
|
if (tcp_conn->tx_hash.tfm)
|
||||||
if (digest) {
|
crypto_free_hash(tcp_conn->tx_hash.tfm);
|
||||||
if (tcp_conn->tx_hash.tfm)
|
if (tcp_conn->rx_hash.tfm)
|
||||||
crypto_free_hash(tcp_conn->tx_hash.tfm);
|
crypto_free_hash(tcp_conn->rx_hash.tfm);
|
||||||
if (tcp_conn->rx_hash.tfm)
|
|
||||||
crypto_free_hash(tcp_conn->rx_hash.tfm);
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(tcp_conn);
|
kfree(tcp_conn);
|
||||||
}
|
}
|
||||||
|
@ -975,13 +975,13 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
|
|||||||
if (session->state == ISCSI_STATE_TERMINATE) {
|
if (session->state == ISCSI_STATE_TERMINATE) {
|
||||||
failed:
|
failed:
|
||||||
debug_scsi("failing host reset: session terminated "
|
debug_scsi("failing host reset: session terminated "
|
||||||
"[CID %d age %d]", conn->id, session->age);
|
"[CID %d age %d]\n", conn->id, session->age);
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->SCp.phase == session->age) {
|
if (sc->SCp.phase == session->age) {
|
||||||
debug_scsi("failing connection CID %d due to SCSI host reset",
|
debug_scsi("failing connection CID %d due to SCSI host reset\n",
|
||||||
conn->id);
|
conn->id);
|
||||||
fail_session = 1;
|
fail_session = 1;
|
||||||
}
|
}
|
||||||
@ -1054,7 +1054,8 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
|
|||||||
NULL, 0);
|
NULL, 0);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
|
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
|
||||||
debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc);
|
debug_scsi("abort sent failure [itt 0x%x] %d\n", ctask->itt,
|
||||||
|
rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,7 +1072,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
|
|||||||
conn->tmabort_timer.function = iscsi_tmabort_timedout;
|
conn->tmabort_timer.function = iscsi_tmabort_timedout;
|
||||||
conn->tmabort_timer.data = (unsigned long)ctask;
|
conn->tmabort_timer.data = (unsigned long)ctask;
|
||||||
add_timer(&conn->tmabort_timer);
|
add_timer(&conn->tmabort_timer);
|
||||||
debug_scsi("abort set timeout [itt 0x%x]", ctask->itt);
|
debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt);
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
mutex_unlock(&conn->xmitmutex);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
|
@ -71,55 +71,65 @@ static void smp_task_done(struct sas_task *task)
|
|||||||
static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
|
static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
|
||||||
void *resp, int resp_size)
|
void *resp, int resp_size)
|
||||||
{
|
{
|
||||||
int res;
|
int res, retry;
|
||||||
struct sas_task *task = sas_alloc_task(GFP_KERNEL);
|
struct sas_task *task = NULL;
|
||||||
struct sas_internal *i =
|
struct sas_internal *i =
|
||||||
to_sas_internal(dev->port->ha->core.shost->transportt);
|
to_sas_internal(dev->port->ha->core.shost->transportt);
|
||||||
|
|
||||||
if (!task)
|
for (retry = 0; retry < 3; retry++) {
|
||||||
return -ENOMEM;
|
task = sas_alloc_task(GFP_KERNEL);
|
||||||
|
if (!task)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
task->dev = dev;
|
task->dev = dev;
|
||||||
task->task_proto = dev->tproto;
|
task->task_proto = dev->tproto;
|
||||||
sg_init_one(&task->smp_task.smp_req, req, req_size);
|
sg_init_one(&task->smp_task.smp_req, req, req_size);
|
||||||
sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
|
sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
|
||||||
|
|
||||||
task->task_done = smp_task_done;
|
task->task_done = smp_task_done;
|
||||||
|
|
||||||
task->timer.data = (unsigned long) task;
|
task->timer.data = (unsigned long) task;
|
||||||
task->timer.function = smp_task_timedout;
|
task->timer.function = smp_task_timedout;
|
||||||
task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
|
task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
|
||||||
add_timer(&task->timer);
|
add_timer(&task->timer);
|
||||||
|
|
||||||
res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
|
res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
del_timer(&task->timer);
|
del_timer(&task->timer);
|
||||||
SAS_DPRINTK("executing SMP task failed:%d\n", res);
|
SAS_DPRINTK("executing SMP task failed:%d\n", res);
|
||||||
goto ex_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_completion(&task->completion);
|
|
||||||
res = -ETASK;
|
|
||||||
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
|
|
||||||
SAS_DPRINTK("smp task timed out or aborted\n");
|
|
||||||
i->dft->lldd_abort_task(task);
|
|
||||||
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
|
|
||||||
SAS_DPRINTK("SMP task aborted and not done\n");
|
|
||||||
goto ex_err;
|
goto ex_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait_for_completion(&task->completion);
|
||||||
|
res = -ETASK;
|
||||||
|
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
|
||||||
|
SAS_DPRINTK("smp task timed out or aborted\n");
|
||||||
|
i->dft->lldd_abort_task(task);
|
||||||
|
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
|
||||||
|
SAS_DPRINTK("SMP task aborted and not done\n");
|
||||||
|
goto ex_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (task->task_status.resp == SAS_TASK_COMPLETE &&
|
||||||
|
task->task_status.stat == SAM_GOOD) {
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
|
||||||
|
"status 0x%x\n", __FUNCTION__,
|
||||||
|
SAS_ADDR(dev->sas_addr),
|
||||||
|
task->task_status.resp,
|
||||||
|
task->task_status.stat);
|
||||||
|
sas_free_task(task);
|
||||||
|
task = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (task->task_status.resp == SAS_TASK_COMPLETE &&
|
|
||||||
task->task_status.stat == SAM_GOOD)
|
|
||||||
res = 0;
|
|
||||||
else
|
|
||||||
SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
|
|
||||||
"status 0x%x\n", __FUNCTION__,
|
|
||||||
SAS_ADDR(dev->sas_addr),
|
|
||||||
task->task_status.resp,
|
|
||||||
task->task_status.stat);
|
|
||||||
ex_err:
|
ex_err:
|
||||||
sas_free_task(task);
|
BUG_ON(retry == 3 && task != NULL);
|
||||||
|
if (task != NULL) {
|
||||||
|
sas_free_task(task);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ static void Irq_Handler (int irq, void *dev_id)
|
|||||||
pinquiryData->AdditionalLength = 35 - 4;
|
pinquiryData->AdditionalLength = 35 - 4;
|
||||||
|
|
||||||
// Fill in vendor identification fields.
|
// Fill in vendor identification fields.
|
||||||
for ( z = 0; z < 20; z += 2 )
|
for ( z = 0; z < 8; z += 2 )
|
||||||
{
|
{
|
||||||
pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1];
|
pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1];
|
||||||
pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z];
|
pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z];
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#define ISCSI_SESSION_ATTRS 11
|
#define ISCSI_SESSION_ATTRS 11
|
||||||
#define ISCSI_CONN_ATTRS 11
|
#define ISCSI_CONN_ATTRS 11
|
||||||
#define ISCSI_HOST_ATTRS 0
|
#define ISCSI_HOST_ATTRS 0
|
||||||
#define ISCSI_TRANSPORT_VERSION "2.0-685"
|
#define ISCSI_TRANSPORT_VERSION "2.0-724"
|
||||||
|
|
||||||
struct iscsi_internal {
|
struct iscsi_internal {
|
||||||
int daemon_pid;
|
int daemon_pid;
|
||||||
|
@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
|
|||||||
|
|
||||||
#ifdef CONFIG_SCSI_PROC_FS
|
#ifdef CONFIG_SCSI_PROC_FS
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
static char *sg_version_date = "20060920";
|
static char *sg_version_date = "20061027";
|
||||||
|
|
||||||
static int sg_proc_init(void);
|
static int sg_proc_init(void);
|
||||||
static void sg_proc_cleanup(void);
|
static void sg_proc_cleanup(void);
|
||||||
@ -710,12 +710,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
|
|||||||
(int) cmnd[0], (int) hp->cmd_len));
|
(int) cmnd[0], (int) hp->cmd_len));
|
||||||
|
|
||||||
if ((k = sg_start_req(srp))) {
|
if ((k = sg_start_req(srp))) {
|
||||||
SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k));
|
SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k));
|
||||||
sg_finish_rem_req(srp);
|
sg_finish_rem_req(srp);
|
||||||
return k; /* probably out of space --> ENOMEM */
|
return k; /* probably out of space --> ENOMEM */
|
||||||
}
|
}
|
||||||
if ((k = sg_write_xfer(srp))) {
|
if ((k = sg_write_xfer(srp))) {
|
||||||
SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n"));
|
SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n"));
|
||||||
sg_finish_rem_req(srp);
|
sg_finish_rem_req(srp);
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
@ -746,7 +746,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
|
|||||||
hp->dxfer_len, srp->data.k_use_sg, timeout,
|
hp->dxfer_len, srp->data.k_use_sg, timeout,
|
||||||
SG_DEFAULT_RETRIES, srp, sg_cmd_done,
|
SG_DEFAULT_RETRIES, srp, sg_cmd_done,
|
||||||
GFP_ATOMIC)) {
|
GFP_ATOMIC)) {
|
||||||
SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n"));
|
SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n"));
|
||||||
/*
|
/*
|
||||||
* most likely out of mem, but could also be a bad map
|
* most likely out of mem, but could also be a bad map
|
||||||
*/
|
*/
|
||||||
@ -1283,7 +1283,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid)
|
|||||||
sg_finish_rem_req(srp);
|
sg_finish_rem_req(srp);
|
||||||
srp = NULL;
|
srp = NULL;
|
||||||
if (NULL == sfp->headrp) {
|
if (NULL == sfp->headrp) {
|
||||||
SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n"));
|
SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n"));
|
||||||
if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */
|
if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */
|
||||||
scsi_device_put(sdp->device);
|
scsi_device_put(sdp->device);
|
||||||
}
|
}
|
||||||
@ -1512,12 +1512,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
|
|||||||
POLL_HUP);
|
POLL_HUP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k));
|
SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k));
|
||||||
if (NULL == sdp->headfp) {
|
if (NULL == sdp->headfp) {
|
||||||
sg_dev_arr[k] = NULL;
|
sg_dev_arr[k] = NULL;
|
||||||
}
|
}
|
||||||
} else { /* nothing active, simple case */
|
} else { /* nothing active, simple case */
|
||||||
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));
|
SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k));
|
||||||
sg_dev_arr[k] = NULL;
|
sg_dev_arr[k] = NULL;
|
||||||
}
|
}
|
||||||
sg_nr_dev--;
|
sg_nr_dev--;
|
||||||
@ -1876,14 +1876,15 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sg->page = p;
|
sg->page = p;
|
||||||
sg->length = ret_sz;
|
sg->length = (ret_sz > num) ? num : ret_sz;
|
||||||
|
|
||||||
SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
|
SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
|
||||||
k, p, ret_sz));
|
"ret_sz=%d\n", k, num, ret_sz));
|
||||||
} /* end of for loop */
|
} /* end of for loop */
|
||||||
|
|
||||||
schp->k_use_sg = k;
|
schp->k_use_sg = k;
|
||||||
SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
|
SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, "
|
||||||
|
"rem_sz=%d\n", k, rem_sz));
|
||||||
|
|
||||||
schp->bufflen = blk_size;
|
schp->bufflen = blk_size;
|
||||||
if (rem_sz > 0) /* must have failed */
|
if (rem_sz > 0) /* must have failed */
|
||||||
@ -2014,7 +2015,7 @@ sg_remove_scat(Sg_scatter_hold * schp)
|
|||||||
for (k = 0; (k < schp->k_use_sg) && sg->page;
|
for (k = 0; (k < schp->k_use_sg) && sg->page;
|
||||||
++k, ++sg) {
|
++k, ++sg) {
|
||||||
SCSI_LOG_TIMEOUT(5, printk(
|
SCSI_LOG_TIMEOUT(5, printk(
|
||||||
"sg_remove_scat: k=%d, a=0x%p, len=%d\n",
|
"sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
|
||||||
k, sg->page, sg->length));
|
k, sg->page, sg->length));
|
||||||
sg_page_free(sg->page, sg->length);
|
sg_page_free(sg->page, sg->length);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user