diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b79fca7..4166935 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -11,6 +11,7 @@ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/mutex.h> +#include <linux/kobject.h> #include <scsi/scsi_tcq.h> #include <scsi/scsicam.h> @@ -137,7 +138,7 @@ static int qla2xxx_eh_target_reset(struct scsi_cmnd *); static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); static int qla2xxx_eh_host_reset(struct scsi_cmnd *); -static int qla2x00_change_queue_depth(struct scsi_device *, int); +static int qla2x00_change_queue_depth(struct scsi_device *, int, int); static int qla2x00_change_queue_type(struct scsi_device *, int); struct scsi_host_template qla2xxx_driver_template = { @@ -727,23 +728,6 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport) spin_unlock_irqrestore(&ha->hardware_lock, flags); } -static void -qla2x00_block_error_handler(struct scsi_cmnd *cmnd) -{ - struct Scsi_Host *shost = cmnd->device->host; - struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); - unsigned long flags; - - spin_lock_irqsave(shost->host_lock, flags); - while (rport->port_state == FC_PORTSTATE_BLOCKED) { - spin_unlock_irqrestore(shost->host_lock, flags); - msleep(1000); - spin_lock_irqsave(shost->host_lock, flags); - } - spin_unlock_irqrestore(shost->host_lock, flags); - return; -} - /************************************************************************** * qla2xxx_eh_abort * @@ -773,7 +757,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) struct req_que *req = vha->req; srb_t *spt; - qla2x00_block_error_handler(cmd); + fc_block_scsi_eh(cmd); if (!CMD_SP(cmd)) return SUCCESS; @@ -904,7 +888,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int err; - qla2x00_block_error_handler(cmd); + fc_block_scsi_eh(cmd); if (!fcport) return FAILED; @@ -984,7 +968,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) unsigned long serial; srb_t *sp = (srb_t *) CMD_SP(cmd); - qla2x00_block_error_handler(cmd); + fc_block_scsi_eh(cmd); id = cmd->device->id; lun = cmd->device->lun; @@ -1047,7 +1031,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) srb_t *sp = (srb_t *) CMD_SP(cmd); scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); - qla2x00_block_error_handler(cmd); + fc_block_scsi_eh(cmd); id = cmd->device->id; lun = cmd->device->lun; @@ -1234,8 +1218,11 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) } static int -qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth) +qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { + if (reason != SCSI_QDEPTH_DEFAULT) + return -EOPNOTSUPP; + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); return sdev->queue_depth; } @@ -2653,6 +2640,37 @@ qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE); qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); +int +qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code) +{ + struct qla_work_evt *e; + + e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT); + if (!e) + return QLA_FUNCTION_FAILED; + + e->u.uevent.code = code; + return qla2x00_post_work(vha, e); +} + +static void +qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code) +{ + char event_string[40]; + char *envp[] = { event_string, NULL }; + + switch (code) { + case QLA_UEVENT_CODE_FW_DUMP: + snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", + vha->host_no); + break; + default: + /* do nothing */ + break; + } + kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp); +} + void qla2x00_do_work(struct scsi_qla_host *vha) { @@ -2690,6 +2708,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) qla2x00_async_logout_done(vha, e->u.logio.fcport, e->u.logio.data); break; + case QLA_EVT_UEVENT: + qla2x00_uevent_emit(vha, e->u.uevent.code); + break; } if (e->flags & QLA_EVT_FLAG_FREE) kfree(e); |