/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2008 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
module_param(ql2xmaxqueues, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xmaxqueues,
"Enables MQ settings "
- "Default is 1 for single queue. Set it to number \
- of queues in MQ mode.");
+ "Default is 1 for single queue. Set it to number "
+ "of queues in MQ mode.");
int ql2xmultique_tag;
module_param(ql2xmultique_tag, int, S_IRUGO|S_IRUSR);
"Enables firmware ETS burst."
"Default is 0 - skip ETS enablement.");
-int ql2xdbwr;
+int ql2xdbwr = 1;
module_param(ql2xdbwr, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xdbwr,
"Option to specify scheme for request queue posting\n"
* Success (Adapter is online/no flash ops) : 0
* Failed (Adapter is offline/disabled/flash ops in progress) : 1
*/
-int
+static int
qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha)
{
int return_status;
return ret;
}
-enum nexus_wait_type {
- WAIT_HOST = 0,
- WAIT_TARGET,
- WAIT_LUN,
-};
-
-static int
+int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
- unsigned int l, srb_t *sp, enum nexus_wait_type type)
+ unsigned int l, enum nexus_wait_type type)
{
int cnt, match, status;
unsigned long flags;
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
+ srb_t *sp;
status = QLA_SUCCESS;
- if (!sp)
- return status;
spin_lock_irqsave(&ha->hardware_lock, flags);
req = vha->req;
return status;
}
-void qla82xx_wait_for_pending_commands(scsi_qla_host_t *vha)
-{
- int cnt;
- srb_t *sp;
- struct req_que *req = vha->req;
-
- DEBUG2(qla_printk(KERN_INFO, vha->hw,
- "Waiting for pending commands\n"));
- for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
- sp = req->outstanding_cmds[cnt];
- if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
- sp, WAIT_HOST) == QLA_SUCCESS) {
- DEBUG2(qla_printk(KERN_INFO, vha->hw,
- "Done wait for pending commands\n"));
- }
- }
-}
-
static char *reset_errors[] = {
"HBA not online",
"HBA not ready",
goto eh_reset_failed;
err = 3;
if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
- cmd->device->lun, (srb_t *) CMD_SP(cmd), type) != QLA_SUCCESS)
+ cmd->device->lun, type) != QLA_SUCCESS)
goto eh_reset_failed;
qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
return SUCCESS;
- eh_reset_failed:
+eh_reset_failed:
qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n"
, vha->host_no, cmd->device->id, cmd->device->lun, name,
reset_errors[err]);
int ret = FAILED;
unsigned int id, lun;
unsigned long serial;
- srb_t *sp = (srb_t *) CMD_SP(cmd);
fc_block_scsi_eh(cmd);
goto eh_bus_reset_done;
/* Flush outstanding commands. */
- if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) !=
+ if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) !=
QLA_SUCCESS)
ret = FAILED;
int ret = FAILED;
unsigned int id, lun;
unsigned long serial;
- srb_t *sp = (srb_t *) CMD_SP(cmd);
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
fc_block_scsi_eh(cmd);
}
/* Waiting for command to be returned to OS.*/
- if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) ==
+ if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) ==
QLA_SUCCESS)
ret = SUCCESS;
.read_optrom = qla25xx_read_optrom_data,
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
- .start_scsi = qla24xx_start_scsi,
+ .start_scsi = qla24xx_dif_start_scsi,
.abort_isp = qla2x00_abort_isp,
};
host->this_id = 255;
host->cmd_per_lun = 3;
host->unique_id = host->host_no;
- host->max_cmd_len = MAX_CMDSZ;
+ if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif)
+ host->max_cmd_len = 32;
+ else
+ host->max_cmd_len = MAX_CMDSZ;
host->max_channel = MAX_BUSES - 1;
host->max_lun = MAX_LUNS;
host->transportt = qla2xxx_transport_template;
DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
base_vha->host_no, ha));
- if (IS_QLA25XX(ha) && ql2xenabledif) {
+ if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4) {
base_vha->flags.difdix_supported = 1;
DEBUG18(qla_printk(KERN_INFO, ha,
" protection.\n"));
scsi_host_set_prot(host,
SHOST_DIF_TYPE1_PROTECTION
+ | SHOST_DIF_TYPE2_PROTECTION
| SHOST_DIF_TYPE3_PROTECTION
| SHOST_DIX_TYPE1_PROTECTION
+ | SHOST_DIX_TYPE2_PROTECTION
| SHOST_DIX_TYPE3_PROTECTION);
scsi_host_set_guard(host, SHOST_DIX_GUARD_CRC);
} else
qla2x00_free_irqs(vha);
+ qla2x00_free_fcports(vha);
+
qla2x00_mem_free(ha);
qla2x00_free_queues(ha);
}
+void qla2x00_free_fcports(struct scsi_qla_host *vha)
+{
+ fc_port_t *fcport, *tfcport;
+
+ list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) {
+ list_del(&fcport->list);
+ kfree(fcport);
+ fcport = NULL;
+ }
+}
+
static inline void
qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
int defer)
CMD_SP(cmd) = NULL;
}
-void
+static void
qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
{
struct scsi_cmnd *cmd = sp->cmd;