aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c24
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c87
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c404
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c36
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
10 files changed, 233 insertions, 359 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index adf9732..4894dc8 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -428,6 +428,19 @@ qla2x00_sysfs_read_sfp(struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2)
return 0;
+ if (ha->sfp_data)
+ goto do_read;
+
+ ha->sfp_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->sfp_data_dma);
+ if (!ha->sfp_data) {
+ qla_printk(KERN_WARNING, ha,
+ "Unable to allocate memory for SFP read-data.\n");
+ return 0;
+ }
+
+do_read:
+ memset(ha->sfp_data, 0, SFP_BLOCK_SIZE);
addr = 0xa0;
for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE;
iter++, offset += SFP_BLOCK_SIZE) {
@@ -835,7 +848,7 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost)
static void
qla2x00_get_host_speed(struct Scsi_Host *shost)
{
- scsi_qla_host_t *ha = shost_priv(shost);
+ scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
uint32_t speed = 0;
switch (ha->link_data_rate) {
@@ -848,6 +861,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
case PORT_SPEED_4GB:
speed = 4;
break;
+ case PORT_SPEED_8GB:
+ speed = 8;
+ break;
}
fc_host_speed(shost) = speed;
}
@@ -855,7 +871,7 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
static void
qla2x00_get_host_port_type(struct Scsi_Host *shost)
{
- scsi_qla_host_t *ha = shost_priv(shost);
+ scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
uint32_t port_type = FC_PORTTYPE_UNKNOWN;
switch (ha->current_topology) {
@@ -965,7 +981,7 @@ qla2x00_issue_lip(struct Scsi_Host *shost)
static struct fc_host_statistics *
qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
{
- scsi_qla_host_t *ha = shost_priv(shost);
+ scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
int rval;
struct link_statistics *stats;
dma_addr_t stats_dma;
@@ -1049,7 +1065,7 @@ qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
static void
qla2x00_get_host_port_state(struct Scsi_Host *shost)
{
- scsi_qla_host_t *ha = shost_priv(shost);
+ scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
if (!ha->flags.online)
fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index b72c7f1..3750319 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2041,8 +2041,6 @@ typedef struct vport_params {
#define VP_RET_CODE_NO_MEM 5
#define VP_RET_CODE_NOT_FOUND 6
-#define to_qla_parent(x) (((x)->parent) ? (x)->parent : (x))
-
/*
* ISP operations
*/
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ba35fc2..193f688 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -66,6 +66,7 @@ extern int ql2xqfullrampup;
extern int num_hosts;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
+extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
/*
* Global Functions in qla_mid.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index d0633ca..d5c7853 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -925,6 +925,16 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
{
int rval;
uint32_t srisc_address = 0;
+ struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+ unsigned long flags;
+
+ if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
+ /* Disable SRAM, Instruction RAM and GP RAM parity. */
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
+ RD_REG_WORD(&reg->hccr);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
/* Load firmware sequences */
rval = ha->isp_ops->load_risc(ha, &srisc_address);
@@ -968,6 +978,19 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
}
}
+ if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
+ /* Enable proper parity. */
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ if (IS_QLA2300(ha))
+ /* SRAM parity */
+ WRT_REG_WORD(&reg->hccr, HCCR_ENABLE_PARITY + 0x1);
+ else
+ /* SRAM, Instruction RAM and GP RAM parity */
+ WRT_REG_WORD(&reg->hccr, HCCR_ENABLE_PARITY + 0x7);
+ RD_REG_WORD(&reg->hccr);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+
if (rval) {
DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n",
ha->host_no));
@@ -3213,9 +3236,6 @@ int
qla2x00_abort_isp(scsi_qla_host_t *ha)
{
int rval;
- unsigned long flags = 0;
- uint16_t cnt;
- srb_t *sp;
uint8_t status = 0;
if (ha->flags.online) {
@@ -3236,19 +3256,8 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
LOOP_DOWN_TIME);
}
- spin_lock_irqsave(&ha->hardware_lock, flags);
/* Requeue all commands in outstanding command list. */
- for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
- sp = ha->outstanding_cmds[cnt];
- if (sp) {
- ha->outstanding_cmds[cnt] = NULL;
- sp->flags = 0;
- sp->cmd->result = DID_RESET << 16;
- sp->cmd->host_scribble = (unsigned char *)NULL;
- qla2x00_sp_compl(ha, sp);
- }
- }
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ qla2x00_abort_all_cmds(ha, DID_RESET << 16);
ha->isp_ops->get_flash_version(ha, ha->request_ring);
@@ -3273,6 +3282,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
if (ha->eft) {
+ memset(ha->eft, 0, EFT_SIZE);
rval = qla2x00_enable_eft_trace(ha,
ha->eft_dma, EFT_NUM_BUFFERS);
if (rval) {
@@ -3357,60 +3367,15 @@ static int
qla2x00_restart_isp(scsi_qla_host_t *ha)
{
uint8_t status = 0;
- struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
- unsigned long flags = 0;
uint32_t wait_time;
/* If firmware needs to be loaded */
if (qla2x00_isp_firmware(ha)) {
ha->flags.online = 0;
- if (!(status = ha->isp_ops->chip_diag(ha))) {
- if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
- status = qla2x00_setup_chip(ha);
- goto done;
- }
-
- spin_lock_irqsave(&ha->hardware_lock, flags);
-
- if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha) &&
- !IS_QLA25XX(ha)) {
- /*
- * Disable SRAM, Instruction RAM and GP RAM
- * parity.
- */
- WRT_REG_WORD(&reg->hccr,
- (HCCR_ENABLE_PARITY + 0x0));
- RD_REG_WORD(&reg->hccr);
- }
-
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
+ if (!(status = ha->isp_ops->chip_diag(ha)))
status = qla2x00_setup_chip(ha);
-
- spin_lock_irqsave(&ha->hardware_lock, flags);
-
- if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha) &&
- !IS_QLA25XX(ha)) {
- /* Enable proper parity */
- if (IS_QLA2300(ha))
- /* SRAM parity */
- WRT_REG_WORD(&reg->hccr,
- (HCCR_ENABLE_PARITY + 0x1));
- else
- /*
- * SRAM, Instruction RAM and GP RAM
- * parity.
- */
- WRT_REG_WORD(&reg->hccr,
- (HCCR_ENABLE_PARITY + 0x7));
- RD_REG_WORD(&reg->hccr);
- }
-
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- }
}
- done:
if (!status && !(status = qla2x00_init_rings(ha))) {
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
if (!(status = qla2x00_fw_ready(ha))) {
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 8e3b044..5d1a3f7 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -119,6 +119,13 @@ static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha)
qla2x00_get_firmware_state(ha, &fw_state);
}
+static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *);
+static __inline__ scsi_qla_host_t *
+to_qla_parent(scsi_qla_host_t *ha)
+{
+ return ha->parent ? ha->parent : ha;
+}
+
/**
* qla2x00_issue_marker() - Issue a Marker IOCB if necessary.
* @ha: HA context
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 642a0c3..14e6f22 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1815,6 +1815,8 @@ int
qla2x00_request_irqs(scsi_qla_host_t *ha)
{
int ret;
+ device_reg_t __iomem *reg = ha->iobase;
+ unsigned long flags;
/* If possible, enable MSI-X. */
if (!IS_QLA2432(ha) && !IS_QLA2532(ha))
@@ -1846,7 +1848,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
DEBUG2(qla_printk(KERN_INFO, ha,
"MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision,
ha->fw_attributes));
- return ret;
+ goto clear_risc_ints;
}
qla_printk(KERN_WARNING, ha,
"MSI-X: Falling back-to INTa mode -- %d.\n", ret);
@@ -1864,15 +1866,30 @@ skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
- if (!ret) {
- ha->flags.inta_enabled = 1;
- ha->host->irq = ha->pdev->irq;
- } else {
+ if (ret) {
qla_printk(KERN_WARNING, ha,
"Failed to reserve interrupt %d already in use.\n",
ha->pdev->irq);
+ goto fail;
+ }
+ ha->flags.inta_enabled = 1;
+ ha->host->irq = ha->pdev->irq;
+clear_risc_ints:
+
+ ha->isp_ops->disable_intrs(ha);
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ if (IS_FWI2_CAPABLE(ha)) {
+ WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
+ WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
+ } else {
+ WRT_REG_WORD(&reg->isp.semaphore, 0);
+ WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
+ WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
}
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ ha->isp_ops->enable_intrs(ha);
+fail:
return ret;
}
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 0c10c0b..99d29ff 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -980,7 +980,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
ha->host_no));
- if (ha->fw_attributes & BIT_2)
+ if (ha->flags.npiv_supported)
mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
else
mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 8f69caf..3c1b433 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -204,10 +204,8 @@ static int qla2x00_do_dpc(void *data);
static void qla2x00_rst_aen(scsi_qla_host_t *);
-static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);
+static int qla2x00_mem_alloc(scsi_qla_host_t *);
static void qla2x00_mem_free(scsi_qla_host_t *ha);
-static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
-static void qla2x00_free_sp_pool(scsi_qla_host_t *ha);
static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
/* -------------------------------------------------------------------------- */
@@ -1117,6 +1115,27 @@ qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
return ha->isp_ops->abort_target(reset_fcport);
}
+void
+qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
+{
+ int cnt;
+ unsigned long flags;
+ srb_t *sp;
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+ sp = ha->outstanding_cmds[cnt];
+ if (sp) {
+ ha->outstanding_cmds[cnt] = NULL;
+ sp->flags = 0;
+ sp->cmd->result = res;
+ sp->cmd->host_scribble = (unsigned char *)NULL;
+ qla2x00_sp_compl(ha, sp);
+ }
+ }
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
static int
qla2xxx_slave_alloc(struct scsi_device *sdev)
{
@@ -1557,10 +1576,8 @@ static int __devinit
qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
int ret = -ENODEV;
- device_reg_t __iomem *reg;
struct Scsi_Host *host;
scsi_qla_host_t *ha;
- unsigned long flags = 0;
char pci_info[30];
char fw_str[30];
struct scsi_host_template *sht;
@@ -1608,6 +1625,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->parent = NULL;
ha->bars = bars;
ha->mem_only = mem_only;
+ spin_lock_init(&ha->hardware_lock);
/* Set ISP-type information. */
qla2x00_set_isp_flags(ha);
@@ -1621,8 +1639,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
ha->iobase);
- spin_lock_init(&ha->hardware_lock);
-
ha->prev_topology = 0;
ha->init_cb_size = sizeof(init_cb_t);
ha->mgmt_svr_loop_id = MANAGEMENT_SERVER + ha->vp_idx;
@@ -1751,34 +1767,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
ha->host_no, ha));
- ha->isp_ops->disable_intrs(ha);
-
- spin_lock_irqsave(&ha->hardware_lock, flags);
- reg = ha->iobase;
- if (IS_FWI2_CAPABLE(ha)) {
- WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
- WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
- } else {
- WRT_REG_WORD(&reg->isp.semaphore, 0);
- WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
- WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
-
- /* Enable proper parity */
- if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) {
- if (IS_QLA2300(ha))
- /* SRAM parity */
- WRT_REG_WORD(&reg->isp.hccr,
- (HCCR_ENABLE_PARITY + 0x1));
- else
- /* SRAM, Instruction RAM and GP RAM parity */
- WRT_REG_WORD(&reg->isp.hccr,
- (HCCR_ENABLE_PARITY + 0x7));
- }
- }
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
- ha->isp_ops->enable_intrs(ha);
-
pci_set_drvdata(pdev, ha);
ha->flags.init_done = 1;
@@ -1848,10 +1836,14 @@ qla2x00_remove_one(struct pci_dev *pdev)
static void
qla2x00_free_device(scsi_qla_host_t *ha)
{
+ qla2x00_abort_all_cmds(ha, DID_NO_CONNECT << 16);
+
/* Disable timer */
if (ha->timer_active)
qla2x00_stop_timer(ha);
+ ha->flags.online = 0;
+
/* Kill the kernel thread for this host */
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
@@ -1870,8 +1862,6 @@ qla2x00_free_device(scsi_qla_host_t *ha)
if (ha->eft)
qla2x00_disable_eft_trace(ha);
- ha->flags.online = 0;
-
/* Stop currently executing firmware. */
qla2x00_try_to_stop_firmware(ha);
@@ -2010,196 +2000,109 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
*
* Returns:
* 0 = success.
-* 1 = failure.
+* !0 = failure.
*/
-static uint8_t
+static int
qla2x00_mem_alloc(scsi_qla_host_t *ha)
{
char name[16];
- uint8_t status = 1;
- int retry= 10;
-
- do {
- /*
- * This will loop only once if everything goes well, else some
- * number of retries will be performed to get around a kernel
- * bug where available mem is not allocated until after a
- * little delay and a retry.
- */
- ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,
- (ha->request_q_length + 1) * sizeof(request_t),
- &ha->request_dma, GFP_KERNEL);
- if (ha->request_ring == NULL) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - request_ring\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
-
- ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,
- (ha->response_q_length + 1) * sizeof(response_t),
- &ha->response_dma, GFP_KERNEL);
- if (ha->response_ring == NULL) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - response_ring\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
-
- ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
- &ha->gid_list_dma, GFP_KERNEL);
- if (ha->gid_list == NULL) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - gid_list\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
-
- /* get consistent memory allocated for init control block */
- ha->init_cb = dma_alloc_coherent(&ha->pdev->dev,
- ha->init_cb_size, &ha->init_cb_dma, GFP_KERNEL);
- if (ha->init_cb == NULL) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - init_cb\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
- memset(ha->init_cb, 0, ha->init_cb_size);
-
- snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
- ha->host_no);
- ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
- DMA_POOL_SIZE, 8, 0);
- if (ha->s_dma_pool == NULL) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - s_dma_pool\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
-
- if (qla2x00_allocate_sp_pool(ha)) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - "
- "qla2x00_allocate_sp_pool()\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
-
- /* Allocate memory for SNS commands */
- if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
- /* Get consistent memory allocated for SNS commands */
- ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
- sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma,
- GFP_KERNEL);
- if (ha->sns_cmd == NULL) {
- /* error */
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - sns_cmd\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
- memset(ha->sns_cmd, 0, sizeof(struct sns_cmd_pkt));
- } else {
- /* Get consistent memory allocated for MS IOCB */
- ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
- &ha->ms_iocb_dma);
- if (ha->ms_iocb == NULL) {
- /* error */
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - ms_iocb\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
- memset(ha->ms_iocb, 0, sizeof(ms_iocb_entry_t));
-
- /*
- * Get consistent memory allocated for CT SNS
- * commands
- */
- ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
- sizeof(struct ct_sns_pkt), &ha->ct_sns_dma,
- GFP_KERNEL);
- if (ha->ct_sns == NULL) {
- /* error */
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - ct_sns\n");
- qla2x00_mem_free(ha);
- msleep(100);
+ ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,
+ (ha->request_q_length + 1) * sizeof(request_t), &ha->request_dma,
+ GFP_KERNEL);
+ if (!ha->request_ring)
+ goto fail;
+
+ ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,
+ (ha->response_q_length + 1) * sizeof(response_t),
+ &ha->response_dma, GFP_KERNEL);
+ if (!ha->response_ring)
+ goto fail_free_request_ring;
+
+ ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
+ &ha->gid_list_dma, GFP_KERNEL);
+ if (!ha->gid_list)
+ goto fail_free_response_ring;
+
+ ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
+ &ha->init_cb_dma, GFP_KERNEL);
+ if (!ha->init_cb)
+ goto fail_free_gid_list;
+
+ snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
+ ha->host_no);
+ ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
+ DMA_POOL_SIZE, 8, 0);
+ if (!ha->s_dma_pool)
+ goto fail_free_init_cb;
- continue;
- }
- memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
-
- if (IS_FWI2_CAPABLE(ha)) {
- /*
- * Get consistent memory allocated for SFP
- * block.
- */
- ha->sfp_data = dma_pool_alloc(ha->s_dma_pool,
- GFP_KERNEL, &ha->sfp_data_dma);
- if (ha->sfp_data == NULL) {
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - "
- "sfp_data\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
- memset(ha->sfp_data, 0, SFP_BLOCK_SIZE);
- }
- }
-
- /* Get memory for cached NVRAM */
- ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
- if (ha->nvram == NULL) {
- /* error */
- qla_printk(KERN_WARNING, ha,
- "Memory Allocation failed - nvram cache\n");
-
- qla2x00_mem_free(ha);
- msleep(100);
-
- continue;
- }
-
- /* Done all allocations without any error. */
- status = 0;
-
- } while (retry-- && status != 0);
+ ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
+ if (!ha->srb_mempool)
+ goto fail_free_s_dma_pool;
+
+ /* Get memory for cached NVRAM */
+ ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
+ if (!ha->nvram)
+ goto fail_free_srb_mempool;
+
+ /* Allocate memory for SNS commands */
+ if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
+ /* Get consistent memory allocated for SNS commands */
+ ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
+ sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL);
+ if (!ha->sns_cmd)
+ goto fail_free_nvram;
+ } else {
+ /* Get consistent memory allocated for MS IOCB */
+ ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->ms_iocb_dma);
+ if (!ha->ms_iocb)
+ goto fail_free_nvram;
- if (status) {
- printk(KERN_WARNING
- "%s(): **** FAILED ****\n", __func__);
+ /* Get consistent memory allocated for CT SNS commands */
+ ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
+ sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
+ if (!ha->ct_sns)
+ goto fail_free_ms_iocb;
}
- return(status);
+ return 0;
+
+fail_free_ms_iocb:
+ dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
+ ha->ms_iocb = NULL;
+ ha->ms_iocb_dma = 0;
+fail_free_nvram:
+ kfree(ha->nvram);
+ ha->nvram = NULL;
+fail_free_srb_mempool:
+ mempool_destroy(ha->srb_mempool);
+ ha->srb_mempool = NULL;
+fail_free_s_dma_pool:
+ dma_pool_destroy(ha->s_dma_pool);
+ ha->s_dma_pool = NULL;
+fail_free_init_cb:
+ dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb,
+ ha->init_cb_dma);
+ ha->init_cb = NULL;
+ ha->init_cb_dma = 0;
+fail_free_gid_list:
+ dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
+ ha->gid_list_dma);
+ ha->gid_list = NULL;
+ ha->gid_list_dma = 0;
+fail_free_response_ring:
+ dma_free_coherent(&ha->pdev->dev, (ha->response_q_length + 1) *
+ sizeof(response_t), ha->response_ring, ha->response_dma);
+ ha->response_ring = NULL;
+ ha->response_dma = 0;
+fail_free_request_ring:
+ dma_free_coherent(&ha->pdev->dev, (ha->request_q_length + 1) *
+ sizeof(request_t), ha->request_ring, ha->request_dma);
+ ha->request_ring = NULL;
+ ha->request_dma = 0;
+fail:
+ return -ENOMEM;
}
/*
@@ -2215,14 +2118,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
struct list_head *fcpl, *fcptemp;
fc_port_t *fcport;
- if (ha == NULL) {
- /* error */
- DEBUG2(printk("%s(): ERROR invalid ha pointer.\n", __func__));
- return;
- }
-
- /* free sp pool */
- qla2x00_free_sp_pool(ha);
+ if (ha->srb_mempool)
+ mempool_destroy(ha->srb_mempool);
if (ha->fce)
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
@@ -2270,6 +2167,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
(ha->request_q_length + 1) * sizeof(request_t),
ha->request_ring, ha->request_dma);
+ ha->srb_mempool = NULL;
ha->eft = NULL;
ha->eft_dma = 0;
ha->sns_cmd = NULL;
@@ -2308,44 +2206,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
kfree(ha->nvram);
}
-/*
- * qla2x00_allocate_sp_pool
- * This routine is called during initialization to allocate
- * memory for local srb_t.
- *
- * Input:
- * ha = adapter block pointer.
- *
- * Context:
- * Kernel context.
- */
-static int
-qla2x00_allocate_sp_pool(scsi_qla_host_t *ha)
-{
- int rval;
-
- rval = QLA_SUCCESS;
- ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
- if (ha->srb_mempool == NULL) {
- qla_printk(KERN_INFO, ha, "Unable to allocate SRB mempool.\n");
- rval = QLA_FUNCTION_FAILED;
- }
- return (rval);
-}
-
-/*
- * This routine frees all adapter allocated memory.
- *
- */
-static void
-qla2x00_free_sp_pool( scsi_qla_host_t *ha)
-{
- if (ha->srb_mempool) {
- mempool_destroy(ha->srb_mempool);
- ha->srb_mempool = NULL;
- }
-}
-
/**************************************************************************
* qla2x00_do_dpc
* This kernel thread is a task that is schedule by the interrupt handler
@@ -2367,6 +2227,9 @@ qla2x00_do_dpc(void *data)
fc_port_t *fcport;
uint8_t status;
uint16_t next_loopid;
+ struct scsi_qla_host *vha;
+ int i;
+
ha = (scsi_qla_host_t *)data;
@@ -2409,6 +2272,18 @@ qla2x00_do_dpc(void *data)
}
clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
}
+
+ for_each_mapped_vp_idx(ha, i) {
+ list_for_each_entry(vha, &ha->vp_list,
+ vp_list) {
+ if (i == vha->vp_idx) {
+ set_bit(ISP_ABORT_NEEDED,
+ &vha->dpc_flags);
+ break;
+ }
+ }
+ }
+
DEBUG(printk("scsi(%ld): dpc: qla2x00_abort_isp end\n",
ha->host_no));
}
@@ -3029,3 +2904,4 @@ MODULE_FIRMWARE(FW_FILE_ISP22XX);
MODULE_FIRMWARE(FW_FILE_ISP2300);
MODULE_FIRMWARE(FW_FILE_ISP2322);
MODULE_FIRMWARE(FW_FILE_ISP24XX);
+MODULE_FIRMWARE(FW_FILE_ISP25XX);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index b68fb73..26822c8 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -893,6 +893,8 @@ qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags)
}
}
+#define PIO_REG(h, r) ((h)->pio_address + offsetof(struct device_reg_2xxx, r))
+
void
qla2x00_beacon_blink(struct scsi_qla_host *ha)
{
@@ -902,15 +904,12 @@ qla2x00_beacon_blink(struct scsi_qla_host *ha)
unsigned long flags;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
- if (ha->pio_address)
- reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
-
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Save the Original GPIOE. */
if (ha->pio_address) {
- gpio_enable = RD_REG_WORD_PIO(&reg->gpioe);
- gpio_data = RD_REG_WORD_PIO(&reg->gpiod);
+ gpio_enable = RD_REG_WORD_PIO(PIO_REG(ha, gpioe));
+ gpio_data = RD_REG_WORD_PIO(PIO_REG(ha, gpiod));
} else {
gpio_enable = RD_REG_WORD(&reg->gpioe);
gpio_data = RD_REG_WORD(&reg->gpiod);
@@ -920,7 +919,7 @@ qla2x00_beacon_blink(struct scsi_qla_host *ha)
gpio_enable |= GPIO_LED_MASK;
if (ha->pio_address) {
- WRT_REG_WORD_PIO(&reg->gpioe, gpio_enable);
+ WRT_REG_WORD_PIO(PIO_REG(ha, gpioe), gpio_enable);
} else {
WRT_REG_WORD(&reg->gpioe, gpio_enable);
RD_REG_WORD(&reg->gpioe);
@@ -936,7 +935,7 @@ qla2x00_beacon_blink(struct scsi_qla_host *ha)
/* Set the modified gpio_data values */
if (ha->pio_address) {
- WRT_REG_WORD_PIO(&reg->gpiod, gpio_data);
+ WRT_REG_WORD_PIO(PIO_REG(ha, gpiod), gpio_data);
} else {
WRT_REG_WORD(&reg->gpiod, gpio_data);
RD_REG_WORD(&reg->gpiod);
@@ -962,14 +961,11 @@ qla2x00_beacon_on(struct scsi_qla_host *ha)
return QLA_FUNCTION_FAILED;
}
- if (ha->pio_address)
- reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
-
/* Turn off LEDs. */
spin_lock_irqsave(&ha->hardware_lock, flags);
if (ha->pio_address) {
- gpio_enable = RD_REG_WORD_PIO(&reg->gpioe);
- gpio_data = RD_REG_WORD_PIO(&reg->gpiod);
+ gpio_enable = RD_REG_WORD_PIO(PIO_REG(ha, gpioe));
+ gpio_data = RD_REG_WORD_PIO(PIO_REG(ha, gpiod));
} else {
gpio_enable = RD_REG_WORD(&reg->gpioe);
gpio_data = RD_REG_WORD(&reg->gpiod);
@@ -978,7 +974,7 @@ qla2x00_beacon_on(struct scsi_qla_host *ha)
/* Set the modified gpio_enable values. */
if (ha->pio_address) {
- WRT_REG_WORD_PIO(&reg->gpioe, gpio_enable);
+ WRT_REG_WORD_PIO(PIO_REG(ha, gpioe), gpio_enable);
} else {
WRT_REG_WORD(&reg->gpioe, gpio_enable);
RD_REG_WORD(&reg->gpioe);
@@ -987,7 +983,7 @@ qla2x00_beacon_on(struct scsi_qla_host *ha)
/* Clear out previously set LED colour. */
gpio_data &= ~GPIO_LED_MASK;
if (ha->pio_address) {
- WRT_REG_WORD_PIO(&reg->gpiod, gpio_data);
+ WRT_REG_WORD_PIO(PIO_REG(ha, gpiod), gpio_data);
} else {
WRT_REG_WORD(&reg->gpiod, gpio_data);
RD_REG_WORD(&reg->gpiod);
@@ -1244,13 +1240,12 @@ qla2x00_read_flash_byte(scsi_qla_host_t *ha, uint32_t addr)
if (ha->pio_address) {
uint16_t data2;
- reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
- WRT_REG_WORD_PIO(&reg->flash_address, (uint16_t)addr);
+ WRT_REG_WORD_PIO(PIO_REG(ha, flash_address), (uint16_t)addr);
do {
- data = RD_REG_WORD_PIO(&reg->flash_data);
+ data = RD_REG_WORD_PIO(PIO_REG(ha, flash_data));
barrier();
cpu_relax();
- data2 = RD_REG_WORD_PIO(&reg->flash_data);
+ data2 = RD_REG_WORD_PIO(PIO_REG(ha, flash_data));
} while (data != data2);
} else {
WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
@@ -1304,9 +1299,8 @@ qla2x00_write_flash_byte(scsi_qla_host_t *ha, uint32_t addr, uint8_t data)
/* Always perform IO mapped accesses to the FLASH registers. */
if (ha->pio_address) {
- reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
- WRT_REG_WORD_PIO(&reg->flash_address, (uint16_t)addr);
- WRT_REG_WORD_PIO(&reg->flash_data, (uint16_t)data);
+ WRT_REG_WORD_PIO(PIO_REG(ha, flash_address), (uint16_t)addr);
+ WRT_REG_WORD_PIO(PIO_REG(ha, flash_data), (uint16_t)data);
} else {
WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 2c2f6b4..c5742cc 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.02.00-k7"
+#define QLA2XXX_VERSION "8.02.00-k8"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 2