// SPDX-License-Identifier: GPL-2.0-or-later /* * Basic HP/COMPAQ MSA 1000 support. This is only needed if your HW cannot be * upgraded. * * Copyright (C) 2006 Red Hat, Inc. All rights reserved. * Copyright (C) 2006 Mike Christie * Copyright (C) 2008 Hannes Reinecke <hare@suse.de>
*/
/* * tur_done - Handle TEST UNIT READY return status * @sdev: sdev the command has been sent to * @errors: blk error code * * Returns SCSI_DH_DEV_OFFLINED if the sdev is on the passive path
*/ staticint tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h, struct scsi_sense_hdr *sshdr)
{ int ret = SCSI_DH_IO;
switch (sshdr->sense_key) { case NOT_READY: if (sshdr->asc == 0x04 && sshdr->ascq == 2) { /* * LUN not ready - Initialization command required * * This is the passive path
*/
h->path_state = HP_SW_PATH_PASSIVE;
ret = SCSI_DH_OK; break;
}
fallthrough; default:
sdev_printk(KERN_WARNING, sdev, "%s: sending tur failed, sense %x/%x/%x\n",
HP_SW_NAME, sshdr->sense_key, sshdr->asc,
sshdr->ascq); break;
} return ret;
}
/* * hp_sw_tur - Send TEST UNIT READY * @sdev: sdev command should be sent to * * Use the TEST UNIT READY command to determine * the path state.
*/ staticint hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
{ unsignedchar cmd[6] = { TEST_UNIT_READY }; struct scsi_sense_hdr sshdr; int ret, res;
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER; struct scsi_failure failure_defs[] = {
{
.sense = UNIT_ATTENTION,
.asc = SCMD_FAILURE_ASC_ANY,
.ascq = SCMD_FAILURE_ASCQ_ANY,
.allowed = SCMD_FAILURE_NO_LIMIT,
.result = SAM_STAT_CHECK_CONDITION,
},
{}
}; struct scsi_failures failures = {
.failure_definitions = failure_defs,
}; conststruct scsi_exec_args exec_args = {
.sshdr = &sshdr,
.failures = &failures,
};
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
HP_SW_RETRIES, &exec_args); if (res > 0 && scsi_sense_valid(&sshdr)) {
ret = tur_done(sdev, h, &sshdr);
} elseif (res == 0) {
h->path_state = HP_SW_PATH_ACTIVE;
ret = SCSI_DH_OK;
} else {
sdev_printk(KERN_WARNING, sdev, "%s: sending tur failed with %x\n",
HP_SW_NAME, res);
ret = SCSI_DH_IO;
}
/* * hp_sw_activate - Activate a path * @sdev: sdev on the path to be activated * * The HP Active/Passive firmware is pretty simple; * the passive path reports NOT READY with sense codes * 0x04/0x02; a START STOP UNIT command will then * activate the passive path (and deactivate the * previously active one).
*/ staticint hp_sw_activate(struct scsi_device *sdev,
activate_complete fn, void *data)
{ int ret = SCSI_DH_OK; struct hp_sw_dh_data *h = sdev->handler_data;
ret = hp_sw_tur(sdev, h);
if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE)
ret = hp_sw_start_stop(h);
if (fn)
fn(data, ret); return 0;
}
staticint hp_sw_bus_attach(struct scsi_device *sdev)
{ struct hp_sw_dh_data *h; int ret;
h = kzalloc(sizeof(*h), GFP_KERNEL); if (!h) return SCSI_DH_NOMEM;
h->path_state = HP_SW_PATH_UNINITIALIZED;
h->retries = HP_SW_RETRIES;
h->sdev = sdev;
ret = hp_sw_tur(sdev, h); if (ret != SCSI_DH_OK) goto failed; if (h->path_state == HP_SW_PATH_UNINITIALIZED) {
ret = SCSI_DH_NOSYS; goto failed;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.