Skip to content
Snippets Groups Projects
Commit 7b867cf7 authored by Anirban Chakraborty's avatar Anirban Chakraborty Committed by James Bottomley
Browse files

[SCSI] qla2xxx: Refactor qla data structures


Following changes have been made to the qla2xxx FC driver in
preparation for the multi- queue and future SR IOV hardware.

1. scsi_qla_host structure has been changed to contain scsi host
   specific data only.

2. A new structure, qla_hw_data is created to contain HBA specific
   hardware data.

3. Request and response IO specific data strucures are created.

4. The global list of fcports for the hba is not maintained anymore,
   instead a fcport list is construted on per scsi_qla_host.

Signed-of-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent a9b589d9
No related merge requests found
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/delay.h> #include <linux/delay.h>
static inline void static inline void
qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump) qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
{ {
fw_dump->fw_major_version = htonl(ha->fw_major_version); fw_dump->fw_major_version = htonl(ha->fw_major_version);
fw_dump->fw_minor_version = htonl(ha->fw_minor_version); fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
...@@ -23,22 +23,25 @@ qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump) ...@@ -23,22 +23,25 @@ qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump)
} }
static inline void * static inline void *
qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) qla2xxx_copy_queues(scsi_qla_host_t *vha, void *ptr)
{ {
struct req_que *req = vha->hw->req;
struct rsp_que *rsp = vha->hw->rsp;
/* Request queue. */ /* Request queue. */
memcpy(ptr, ha->request_ring, ha->request_q_length * memcpy(ptr, req->ring, req->length *
sizeof(request_t)); sizeof(request_t));
/* Response queue. */ /* Response queue. */
ptr += ha->request_q_length * sizeof(request_t); ptr += req->length * sizeof(request_t);
memcpy(ptr, ha->response_ring, ha->response_q_length * memcpy(ptr, rsp->ring, rsp->length *
sizeof(response_t)); sizeof(response_t));
return ptr + (ha->response_q_length * sizeof(response_t)); return ptr + (rsp->length * sizeof(response_t));
} }
static int static int
qla24xx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint32_t *ram, qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
uint32_t ram_dwords, void **nxt) uint32_t ram_dwords, void **nxt)
{ {
int rval; int rval;
...@@ -112,7 +115,7 @@ qla24xx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint32_t *ram, ...@@ -112,7 +115,7 @@ qla24xx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint32_t *ram,
} }
static int static int
qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram,
uint32_t cram_size, void **nxt) uint32_t cram_size, void **nxt)
{ {
int rval; int rval;
...@@ -163,7 +166,7 @@ qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) ...@@ -163,7 +166,7 @@ qla24xx_pause_risc(struct device_reg_24xx __iomem *reg)
} }
static int static int
qla24xx_soft_reset(scsi_qla_host_t *ha) qla24xx_soft_reset(struct qla_hw_data *ha)
{ {
int rval = QLA_SUCCESS; int rval = QLA_SUCCESS;
uint32_t cnt; uint32_t cnt;
...@@ -215,8 +218,8 @@ qla24xx_soft_reset(scsi_qla_host_t *ha) ...@@ -215,8 +218,8 @@ qla24xx_soft_reset(scsi_qla_host_t *ha)
} }
static int static int
qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
uint32_t ram_words, void **nxt) uint16_t ram_words, void **nxt)
{ {
int rval; int rval;
uint32_t cnt, stat, timer, words, idx; uint32_t cnt, stat, timer, words, idx;
...@@ -314,11 +317,11 @@ qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, ...@@ -314,11 +317,11 @@ qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
* @hardware_locked: Called with the hardware_lock * @hardware_locked: Called with the hardware_lock
*/ */
void void
qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
{ {
int rval; int rval;
uint32_t cnt; uint32_t cnt;
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
uint16_t __iomem *dmp_reg; uint16_t __iomem *dmp_reg;
unsigned long flags; unsigned long flags;
...@@ -458,7 +461,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -458,7 +461,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
ha->fw_memory_size - 0x11000 + 1, &nxt); ha->fw_memory_size - 0x11000 + 1, &nxt);
if (rval == QLA_SUCCESS) if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, nxt); qla2xxx_copy_queues(vha, nxt);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
...@@ -468,7 +471,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -468,7 +471,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump); vha->host_no, ha->fw_dump);
ha->fw_dumped = 1; ha->fw_dumped = 1;
} }
...@@ -483,12 +486,13 @@ qla2300_fw_dump_failed: ...@@ -483,12 +486,13 @@ qla2300_fw_dump_failed:
* @hardware_locked: Called with the hardware_lock * @hardware_locked: Called with the hardware_lock
*/ */
void void
qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
{ {
int rval; int rval;
uint32_t cnt, timer; uint32_t cnt, timer;
uint16_t risc_address; uint16_t risc_address;
uint16_t mb0, mb2; uint16_t mb0, mb2;
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
uint16_t __iomem *dmp_reg; uint16_t __iomem *dmp_reg;
unsigned long flags; unsigned long flags;
...@@ -663,7 +667,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -663,7 +667,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
} }
if (rval == QLA_SUCCESS) if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); qla2xxx_copy_queues(vha, &fw->risc_ram[cnt]);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
...@@ -673,7 +677,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -673,7 +677,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump); vha->host_no, ha->fw_dump);
ha->fw_dumped = 1; ha->fw_dumped = 1;
} }
...@@ -683,12 +687,12 @@ qla2100_fw_dump_failed: ...@@ -683,12 +687,12 @@ qla2100_fw_dump_failed:
} }
void void
qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
{ {
int rval; int rval;
uint32_t cnt; uint32_t cnt;
uint32_t risc_address; uint32_t risc_address;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
uint32_t __iomem *dmp_reg; uint32_t __iomem *dmp_reg;
uint32_t *iter_reg; uint32_t *iter_reg;
...@@ -906,7 +910,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -906,7 +910,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
goto qla24xx_fw_dump_failed_0; goto qla24xx_fw_dump_failed_0;
nxt = qla2xxx_copy_queues(ha, nxt); nxt = qla2xxx_copy_queues(vha, nxt);
if (ha->eft) if (ha->eft)
memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size));
...@@ -919,7 +923,7 @@ qla24xx_fw_dump_failed_0: ...@@ -919,7 +923,7 @@ qla24xx_fw_dump_failed_0:
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump); vha->host_no, ha->fw_dump);
ha->fw_dumped = 1; ha->fw_dumped = 1;
} }
...@@ -929,12 +933,12 @@ qla24xx_fw_dump_failed: ...@@ -929,12 +933,12 @@ qla24xx_fw_dump_failed:
} }
void void
qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
{ {
int rval; int rval;
uint32_t cnt; uint32_t cnt;
uint32_t risc_address; uint32_t risc_address;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
uint32_t __iomem *dmp_reg; uint32_t __iomem *dmp_reg;
uint32_t *iter_reg; uint32_t *iter_reg;
...@@ -1215,7 +1219,7 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -1215,7 +1219,7 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
goto qla25xx_fw_dump_failed_0; goto qla25xx_fw_dump_failed_0;
/* Fibre Channel Trace Buffer. */ /* Fibre Channel Trace Buffer. */
nxt = qla2xxx_copy_queues(ha, nxt); nxt = qla2xxx_copy_queues(vha, nxt);
if (ha->eft) if (ha->eft)
memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size));
...@@ -1248,7 +1252,7 @@ qla25xx_fw_dump_failed_0: ...@@ -1248,7 +1252,7 @@ qla25xx_fw_dump_failed_0:
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump); vha->host_no, ha->fw_dump);
ha->fw_dumped = 1; ha->fw_dumped = 1;
} }
...@@ -1262,9 +1266,10 @@ qla25xx_fw_dump_failed: ...@@ -1262,9 +1266,10 @@ qla25xx_fw_dump_failed:
/****************************************************************************/ /****************************************************************************/
void void
qla2x00_dump_regs(scsi_qla_host_t *ha) qla2x00_dump_regs(scsi_qla_host_t *vha)
{ {
int i; int i;
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
uint16_t __iomem *mbx_reg; uint16_t __iomem *mbx_reg;
...@@ -1274,7 +1279,7 @@ qla2x00_dump_regs(scsi_qla_host_t *ha) ...@@ -1274,7 +1279,7 @@ qla2x00_dump_regs(scsi_qla_host_t *ha)
printk("Mailbox registers:\n"); printk("Mailbox registers:\n");
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
printk("scsi(%ld): mbox %d 0x%04x \n", ha->host_no, i, printk("scsi(%ld): mbox %d 0x%04x \n", vha->host_no, i,
RD_REG_WORD(mbx_reg++)); RD_REG_WORD(mbx_reg++));
} }
......
This diff is collapsed.
...@@ -15,10 +15,11 @@ static atomic_t qla2x00_dfs_root_count; ...@@ -15,10 +15,11 @@ static atomic_t qla2x00_dfs_root_count;
static int static int
qla2x00_dfs_fce_show(struct seq_file *s, void *unused) qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
{ {
scsi_qla_host_t *ha = s->private; scsi_qla_host_t *vha = s->private;
uint32_t cnt; uint32_t cnt;
uint32_t *fce; uint32_t *fce;
uint64_t fce_start; uint64_t fce_start;
struct qla_hw_data *ha = vha->hw;
mutex_lock(&ha->fce_mutex); mutex_lock(&ha->fce_mutex);
...@@ -51,7 +52,8 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused) ...@@ -51,7 +52,8 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
static int static int
qla2x00_dfs_fce_open(struct inode *inode, struct file *file) qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
{ {
scsi_qla_host_t *ha = inode->i_private; scsi_qla_host_t *vha = inode->i_private;
struct qla_hw_data *ha = vha->hw;
int rval; int rval;
if (!ha->flags.fce_enabled) if (!ha->flags.fce_enabled)
...@@ -60,7 +62,7 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file) ...@@ -60,7 +62,7 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
mutex_lock(&ha->fce_mutex); mutex_lock(&ha->fce_mutex);
/* Pause tracing to flush FCE buffers. */ /* Pause tracing to flush FCE buffers. */
rval = qla2x00_disable_fce_trace(ha, &ha->fce_wr, &ha->fce_rd); rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd);
if (rval) if (rval)
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"DebugFS: Unable to disable FCE (%d).\n", rval); "DebugFS: Unable to disable FCE (%d).\n", rval);
...@@ -75,7 +77,8 @@ out: ...@@ -75,7 +77,8 @@ out:
static int static int
qla2x00_dfs_fce_release(struct inode *inode, struct file *file) qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
{ {
scsi_qla_host_t *ha = inode->i_private; scsi_qla_host_t *vha = inode->i_private;
struct qla_hw_data *ha = vha->hw;
int rval; int rval;
if (ha->flags.fce_enabled) if (ha->flags.fce_enabled)
...@@ -86,7 +89,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) ...@@ -86,7 +89,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
/* Re-enable FCE tracing. */ /* Re-enable FCE tracing. */
ha->flags.fce_enabled = 1; ha->flags.fce_enabled = 1;
memset(ha->fce, 0, fce_calc_size(ha->fce_bufs)); memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
rval = qla2x00_enable_fce_trace(ha, ha->fce_dma, ha->fce_bufs, rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs,
ha->fce_mb, &ha->fce_bufs); ha->fce_mb, &ha->fce_bufs);
if (rval) { if (rval) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
...@@ -107,8 +110,9 @@ static const struct file_operations dfs_fce_ops = { ...@@ -107,8 +110,9 @@ static const struct file_operations dfs_fce_ops = {
}; };
int int
qla2x00_dfs_setup(scsi_qla_host_t *ha) qla2x00_dfs_setup(scsi_qla_host_t *vha)
{ {
struct qla_hw_data *ha = vha->hw;
if (!IS_QLA25XX(ha)) if (!IS_QLA25XX(ha))
goto out; goto out;
if (!ha->fce) if (!ha->fce)
...@@ -130,7 +134,7 @@ create_dir: ...@@ -130,7 +134,7 @@ create_dir:
goto create_nodes; goto create_nodes;
mutex_init(&ha->fce_mutex); mutex_init(&ha->fce_mutex);
ha->dfs_dir = debugfs_create_dir(ha->host_str, qla2x00_dfs_root); ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
if (!ha->dfs_dir) { if (!ha->dfs_dir) {
qla_printk(KERN_NOTICE, ha, qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to create ha directory.\n"); "DebugFS: Unable to create ha directory.\n");
...@@ -152,8 +156,9 @@ out: ...@@ -152,8 +156,9 @@ out:
} }
int int
qla2x00_dfs_remove(scsi_qla_host_t *ha) qla2x00_dfs_remove(scsi_qla_host_t *vha)
{ {
struct qla_hw_data *ha = vha->hw;
if (ha->dfs_fce) { if (ha->dfs_fce) {
debugfs_remove(ha->dfs_fce); debugfs_remove(ha->dfs_fce);
ha->dfs_fce = NULL; ha->dfs_fce = NULL;
......
...@@ -72,7 +72,10 @@ extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, ...@@ -72,7 +72,10 @@ extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
uint16_t, uint16_t); uint16_t, uint16_t);
extern void qla2x00_abort_fcport_cmds(fc_port_t *); extern void qla2x00_abort_fcport_cmds(fc_port_t *);
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
struct qla_hw_data *);
extern void qla2x00_free_host(struct scsi_qla_host *);
extern void qla2x00_relogin(struct scsi_qla_host *);
/* /*
* Global Functions in qla_mid.c source file. * Global Functions in qla_mid.c source file.
*/ */
...@@ -105,10 +108,10 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); ...@@ -105,10 +108,10 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(scsi_qla_host_t *); extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
extern void qla2x00_alert_all_vps(scsi_qla_host_t *, uint16_t *); extern void qla2x00_alert_all_vps(struct qla_hw_data *, uint16_t *);
extern void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); extern void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
extern void qla2x00_vp_abort_isp(scsi_qla_host_t *); extern int qla2x00_vp_abort_isp(scsi_qla_host_t *);
/* /*
* Global Function Prototypes in qla_iocb.c source file. * Global Function Prototypes in qla_iocb.c source file.
...@@ -267,7 +270,7 @@ extern irqreturn_t qla24xx_intr_handler(int, void *); ...@@ -267,7 +270,7 @@ extern irqreturn_t qla24xx_intr_handler(int, void *);
extern void qla2x00_process_response_queue(struct scsi_qla_host *); extern void qla2x00_process_response_queue(struct scsi_qla_host *);
extern void qla24xx_process_response_queue(struct scsi_qla_host *); extern void qla24xx_process_response_queue(struct scsi_qla_host *);
extern int qla2x00_request_irqs(scsi_qla_host_t *); extern int qla2x00_request_irqs(struct qla_hw_data *);
extern void qla2x00_free_irqs(scsi_qla_host_t *); extern void qla2x00_free_irqs(scsi_qla_host_t *);
/* /*
......
This diff is collapsed.
This diff is collapsed.
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* See LICENSE.qla2xxx for copyright and licensing details. * See LICENSE.qla2xxx for copyright and licensing details.
*/ */
#include "qla_def.h" #include "qla_def.h"
#include "qla_gbl.h"
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
...@@ -18,7 +19,7 @@ ...@@ -18,7 +19,7 @@
void void
qla2x00_vp_stop_timer(scsi_qla_host_t *vha) qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
{ {
if (vha->parent && vha->timer_active) { if (vha->vp_idx && vha->timer_active) {
del_timer_sync(&vha->timer); del_timer_sync(&vha->timer);
vha->timer_active = 0; vha->timer_active = 0;
} }
...@@ -28,7 +29,7 @@ static uint32_t ...@@ -28,7 +29,7 @@ static uint32_t
qla24xx_allocate_vp_id(scsi_qla_host_t *vha) qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
{ {
uint32_t vp_id; uint32_t vp_id;
scsi_qla_host_t *ha = vha->parent; struct qla_hw_data *ha = vha->hw;
/* Find an empty slot and assign an vp_id */ /* Find an empty slot and assign an vp_id */
mutex_lock(&ha->vport_lock); mutex_lock(&ha->vport_lock);
...@@ -44,7 +45,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) ...@@ -44,7 +45,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
ha->num_vhosts++; ha->num_vhosts++;
ha->cur_vport_count++; ha->cur_vport_count++;
vha->vp_idx = vp_id; vha->vp_idx = vp_id;
list_add_tail(&vha->vp_list, &ha->vp_list); list_add_tail(&vha->list, &ha->vp_list);
mutex_unlock(&ha->vport_lock); mutex_unlock(&ha->vport_lock);
return vp_id; return vp_id;
} }
...@@ -53,24 +54,24 @@ void ...@@ -53,24 +54,24 @@ void
qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
{ {
uint16_t vp_id; uint16_t vp_id;
scsi_qla_host_t *ha = vha->parent; struct qla_hw_data *ha = vha->hw;
mutex_lock(&ha->vport_lock); mutex_lock(&ha->vport_lock);
vp_id = vha->vp_idx; vp_id = vha->vp_idx;
ha->num_vhosts--; ha->num_vhosts--;
ha->cur_vport_count--; ha->cur_vport_count--;
clear_bit(vp_id, ha->vp_idx_map); clear_bit(vp_id, ha->vp_idx_map);
list_del(&vha->vp_list); list_del(&vha->list);
mutex_unlock(&ha->vport_lock); mutex_unlock(&ha->vport_lock);
} }
static scsi_qla_host_t * static scsi_qla_host_t *
qla24xx_find_vhost_by_name(scsi_qla_host_t *ha, uint8_t *port_name) qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name)
{ {
scsi_qla_host_t *vha; scsi_qla_host_t *vha;
/* Locate matching device in database. */ /* Locate matching device in database. */
list_for_each_entry(vha, &ha->vp_list, vp_list) { list_for_each_entry(vha, &ha->vp_list, list) {
if (!memcmp(port_name, vha->port_name, WWN_SIZE)) if (!memcmp(port_name, vha->port_name, WWN_SIZE))
return vha; return vha;
} }
...@@ -94,12 +95,8 @@ static void ...@@ -94,12 +95,8 @@ static void
qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
{ {
fc_port_t *fcport; fc_port_t *fcport;
scsi_qla_host_t *pha = to_qla_parent(vha);
list_for_each_entry(fcport, &pha->fcports, list) {
if (fcport->vp_idx != vha->vp_idx)
continue;
list_for_each_entry(fcport, &vha->vp_fcports, list) {
DEBUG15(printk("scsi(%ld): Marking port dead, " DEBUG15(printk("scsi(%ld): Marking port dead, "
"loop_id=0x%04x :%x\n", "loop_id=0x%04x :%x\n",
vha->host_no, fcport->loop_id, fcport->vp_idx)); vha->host_no, fcport->loop_id, fcport->vp_idx));
...@@ -118,7 +115,6 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) ...@@ -118,7 +115,6 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_state, LOOP_DOWN);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
/* Delete all vp's fcports from parent's list */
qla2x00_mark_vp_devices_dead(vha); qla2x00_mark_vp_devices_dead(vha);
atomic_set(&vha->vp_state, VP_FAILED); atomic_set(&vha->vp_state, VP_FAILED);
vha->flags.management_server_logged_in = 0; vha->flags.management_server_logged_in = 0;
...@@ -135,11 +131,12 @@ int ...@@ -135,11 +131,12 @@ int
qla24xx_enable_vp(scsi_qla_host_t *vha) qla24xx_enable_vp(scsi_qla_host_t *vha)
{ {
int ret; int ret;
scsi_qla_host_t *ha = vha->parent; struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
/* Check if physical ha port is Up */ /* Check if physical ha port is Up */
if (atomic_read(&ha->loop_state) == LOOP_DOWN || if (atomic_read(&base_vha->loop_state) == LOOP_DOWN ||
atomic_read(&ha->loop_state) == LOOP_DEAD ) { atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
vha->vp_err_state = VP_ERR_PORTDWN; vha->vp_err_state = VP_ERR_PORTDWN;
fc_vport_set_state(vha->fc_vport, FC_VPORT_LINKDOWN); fc_vport_set_state(vha->fc_vport, FC_VPORT_LINKDOWN);
goto enable_failed; goto enable_failed;
...@@ -177,8 +174,8 @@ qla24xx_configure_vp(scsi_qla_host_t *vha) ...@@ -177,8 +174,8 @@ qla24xx_configure_vp(scsi_qla_host_t *vha)
vha->host_no, __func__)); vha->host_no, __func__));
ret = qla2x00_send_change_request(vha, 0x3, vha->vp_idx); ret = qla2x00_send_change_request(vha, 0x3, vha->vp_idx);
if (ret != QLA_SUCCESS) { if (ret != QLA_SUCCESS) {
DEBUG15(qla_printk(KERN_ERR, vha, "Failed to enable receiving" DEBUG15(qla_printk(KERN_ERR, vha->hw, "Failed to enable "
" of RSCN requests: 0x%x\n", ret)); "receiving of RSCN requests: 0x%x\n", ret));
return; return;
} else { } else {
/* Corresponds to SCR enabled */ /* Corresponds to SCR enabled */
...@@ -194,25 +191,13 @@ qla24xx_configure_vp(scsi_qla_host_t *vha) ...@@ -194,25 +191,13 @@ qla24xx_configure_vp(scsi_qla_host_t *vha)
} }
void void
qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb) qla2x00_alert_all_vps(struct qla_hw_data *ha, uint16_t *mb)
{ {
int i, vp_idx_matched;
scsi_qla_host_t *vha; scsi_qla_host_t *vha;
int i = 0;
if (ha->parent) list_for_each_entry(vha, &ha->vp_list, list) {
return; if (vha->vp_idx) {
for_each_mapped_vp_idx(ha, i) {
vp_idx_matched = 0;
list_for_each_entry(vha, &ha->vp_list, vp_list) {
if (i == vha->vp_idx) {
vp_idx_matched = 1;
break;
}
}
if (vp_idx_matched) {
switch (mb[0]) { switch (mb[0]) {
case MBA_LIP_OCCURRED: case MBA_LIP_OCCURRED:
case MBA_LOOP_UP: case MBA_LOOP_UP:
...@@ -223,16 +208,17 @@ qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb) ...@@ -223,16 +208,17 @@ qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb)
case MBA_PORT_UPDATE: case MBA_PORT_UPDATE:
case MBA_RSCN_UPDATE: case MBA_RSCN_UPDATE:
DEBUG15(printk("scsi(%ld)%s: Async_event for" DEBUG15(printk("scsi(%ld)%s: Async_event for"
" VP[%d], mb = 0x%x, vha=%p\n", " VP[%d], mb = 0x%x, vha=%p\n",
vha->host_no, __func__,i, *mb, vha)); vha->host_no, __func__, i, *mb, vha));
qla2x00_async_event(vha, mb); qla2x00_async_event(vha, mb);
break; break;
} }
} }
i++;
} }
} }
void int
qla2x00_vp_abort_isp(scsi_qla_host_t *vha) qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
{ {
/* /*
...@@ -247,30 +233,49 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) ...@@ -247,30 +233,49 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
} }
/* To exclusively reset vport, we need to log it out first.*/
if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
DEBUG15(printk("scsi(%ld): Scheduling enable of Vport %d...\n", DEBUG15(printk("scsi(%ld): Scheduling enable of Vport %d...\n",
vha->host_no, vha->vp_idx)); vha->host_no, vha->vp_idx));
qla24xx_enable_vp(vha); return qla24xx_enable_vp(vha);
} }
static int static int
qla2x00_do_dpc_vp(scsi_qla_host_t *vha) qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
{ {
scsi_qla_host_t *ha = vha->parent; struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
/* VP acquired. complete port configuration */ /* VP acquired. complete port configuration */
if (atomic_read(&ha->loop_state) == LOOP_READY) { if (atomic_read(&base_vha->loop_state) == LOOP_READY) {
qla24xx_configure_vp(vha); qla24xx_configure_vp(vha);
} else { } else {
set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
set_bit(VP_DPC_NEEDED, &ha->dpc_flags); set_bit(VP_DPC_NEEDED, &base_vha->dpc_flags);
} }
return 0; return 0;
} }
if (test_and_clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) if (test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) {
qla2x00_vp_abort_isp(vha); qla2x00_update_fcports(vha);
clear_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags);
}
if ((test_and_clear_bit(RELOGIN_NEEDED, &vha->dpc_flags)) &&
!test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
atomic_read(&vha->loop_state) != LOOP_DOWN) {
DEBUG(printk("scsi(%ld): qla2x00_port_login()\n",
vha->host_no));
qla2x00_relogin(vha);
DEBUG(printk("scsi(%ld): qla2x00_port_login - end\n",
vha->host_no));
}
if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) && if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&
(!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) { (!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) {
...@@ -289,38 +294,30 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) ...@@ -289,38 +294,30 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
} }
void void
qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha) qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
{ {
int ret; int ret;
int i, vp_idx_matched; struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *vha; scsi_qla_host_t *vp;
if (ha->parent) if (vha->vp_idx)
return; return;
if (list_empty(&ha->vp_list)) if (list_empty(&ha->vp_list))
return; return;
clear_bit(VP_DPC_NEEDED, &ha->dpc_flags); clear_bit(VP_DPC_NEEDED, &vha->dpc_flags);
for_each_mapped_vp_idx(ha, i) {
vp_idx_matched = 0;
list_for_each_entry(vha, &ha->vp_list, vp_list) {
if (i == vha->vp_idx) {
vp_idx_matched = 1;
break;
}
}
if (vp_idx_matched) list_for_each_entry(vp, &ha->vp_list, list) {
ret = qla2x00_do_dpc_vp(vha); if (vp->vp_idx)
ret = qla2x00_do_dpc_vp(vp);
} }
} }
int int
qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
{ {
scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
struct qla_hw_data *ha = base_vha->hw;
scsi_qla_host_t *vha; scsi_qla_host_t *vha;
uint8_t port_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE];
...@@ -337,7 +334,7 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) ...@@ -337,7 +334,7 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
/* Check up unique WWPN */ /* Check up unique WWPN */
u64_to_wwn(fc_vport->port_name, port_name); u64_to_wwn(fc_vport->port_name, port_name);
if (!memcmp(port_name, ha->port_name, WWN_SIZE)) if (!memcmp(port_name, base_vha->port_name, WWN_SIZE))
return VPCERR_BAD_WWN; return VPCERR_BAD_WWN;
vha = qla24xx_find_vhost_by_name(ha, port_name); vha = qla24xx_find_vhost_by_name(ha, port_name);
if (vha) if (vha)
...@@ -346,7 +343,7 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) ...@@ -346,7 +343,7 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
/* Check up max-npiv-supports */ /* Check up max-npiv-supports */
if (ha->num_vhosts > ha->max_npiv_vports) { if (ha->num_vhosts > ha->max_npiv_vports) {
DEBUG15(printk("scsi(%ld): num_vhosts %ud is bigger than " DEBUG15(printk("scsi(%ld): num_vhosts %ud is bigger than "
"max_npv_vports %ud.\n", ha->host_no, "max_npv_vports %ud.\n", base_vha->host_no,
ha->num_vhosts, ha->max_npiv_vports)); ha->num_vhosts, ha->max_npiv_vports));
return VPCERR_UNSUPPORTED; return VPCERR_UNSUPPORTED;
} }
...@@ -356,59 +353,35 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) ...@@ -356,59 +353,35 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
scsi_qla_host_t * scsi_qla_host_t *
qla24xx_create_vhost(struct fc_vport *fc_vport) qla24xx_create_vhost(struct fc_vport *fc_vport)
{ {
scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
struct qla_hw_data *ha = base_vha->hw;
scsi_qla_host_t *vha; scsi_qla_host_t *vha;
struct scsi_host_template *sht = &qla24xx_driver_template;
struct Scsi_Host *host; struct Scsi_Host *host;
host = scsi_host_alloc(&qla24xx_driver_template, vha = qla2x00_create_host(sht, ha);
sizeof(scsi_qla_host_t)); if (!vha) {
if (!host) { DEBUG(printk("qla2xxx: scsi_host_alloc() failed for vport\n"));
printk(KERN_WARNING
"qla2xxx: scsi_host_alloc() failed for vport\n");
return(NULL); return(NULL);
} }
vha = shost_priv(host); host = vha->host;
/* clone the parent hba */
memcpy(vha, ha, sizeof (scsi_qla_host_t));
fc_vport->dd_data = vha; fc_vport->dd_data = vha;
vha->node_name = kmalloc(WWN_SIZE * sizeof(char), GFP_KERNEL);
if (!vha->node_name)
goto create_vhost_failed_1;
vha->port_name = kmalloc(WWN_SIZE * sizeof(char), GFP_KERNEL);
if (!vha->port_name)
goto create_vhost_failed_2;
/* New host info */ /* New host info */
u64_to_wwn(fc_vport->node_name, vha->node_name); u64_to_wwn(fc_vport->node_name, vha->node_name);
u64_to_wwn(fc_vport->port_name, vha->port_name); u64_to_wwn(fc_vport->port_name, vha->port_name);
vha->host = host;
vha->host_no = host->host_no;
vha->parent = ha;
vha->fc_vport = fc_vport; vha->fc_vport = fc_vport;
vha->device_flags = 0; vha->device_flags = 0;
vha->vp_idx = qla24xx_allocate_vp_id(vha); vha->vp_idx = qla24xx_allocate_vp_id(vha);
if (vha->vp_idx > ha->max_npiv_vports) { if (vha->vp_idx > ha->max_npiv_vports) {
DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n", DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n",
vha->host_no)); vha->host_no));
goto create_vhost_failed_3; goto create_vhost_failed;
} }
vha->mgmt_svr_loop_id = 10 + vha->vp_idx; vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
init_completion(&vha->mbx_cmd_comp);
complete(&vha->mbx_cmd_comp);
init_completion(&vha->mbx_intr_comp);
INIT_LIST_HEAD(&vha->list);
INIT_LIST_HEAD(&vha->fcports);
INIT_LIST_HEAD(&vha->vp_fcports);
INIT_LIST_HEAD(&vha->work_list);
vha->dpc_flags = 0L; vha->dpc_flags = 0L;
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
...@@ -423,7 +396,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) ...@@ -423,7 +396,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL); qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
host->can_queue = vha->request_q_length + 128; host->can_queue = ha->req->length + 128;
host->this_id = 255; host->this_id = 255;
host->cmd_per_lun = 3; host->cmd_per_lun = 3;
host->max_cmd_len = MAX_CMDSZ; host->max_cmd_len = MAX_CMDSZ;
...@@ -440,12 +413,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) ...@@ -440,12 +413,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
return vha; return vha;
create_vhost_failed_3: create_vhost_failed:
kfree(vha->port_name);
create_vhost_failed_2:
kfree(vha->node_name);
create_vhost_failed_1:
return NULL; return NULL;
} }
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment