#include "qla2x00t.h"
+/*
+ * This driver calls qla2x00_req_pkt() and qla2x00_issue_marker(), which
+ * must be called under HW lock and could unlock/lock it inside.
+ * It isn't an issue, since in the current implementation on the time when
+ * those functions are called:
+ *
+ * - Either context is IRQ and only IRQ handler can modify HW data,
+ * including rings related fields,
+ *
+ * - Or access to target mode variables from struct q2t_tgt doesn't
+ * cross those functions boundaries, except tgt_shutdown, which
+ * additionally protected by irq_cmd_count.
+ */
+
#ifndef CONFIG_SCSI_QLA2XXX_TARGET
#error "CONFIG_SCSI_QLA2XXX_TARGET is NOT DEFINED"
#endif
#endif
static struct kmem_cache *q2t_cmd_cachep;
-static struct qla_target tgt_data;
static struct kmem_cache *q2t_mgmt_cmd_cachep;
static mempool_t *q2t_mgmt_cmd_mempool;
return NULL;
}
-
/* ha->hardware_lock supposed to be held on entry */
static inline void q2t_exec_queue(scsi_qla_host_t *ha)
{
- tgt_data.isp_cmd(ha);
+ qla2x00_isp_cmd(ha);
}
/* Might release hw lock, then reaquire!! */
{
/* Send marker if required */
if (unlikely(ha->marker_needed != 0)) {
- int rc = tgt_data.issue_marker(ha, ha_locked);
+ int rc = qla2x00_issue_marker(ha, ha_locked);
if (rc != QLA_SUCCESS) {
PRINT_ERROR("qla2x00tgt(%ld): issue_marker() "
"failed", ha->instance);
static int q2x_target_detect(struct scst_tgt_template *templ)
{
int res;
- struct qla_tgt_initiator itd = {
+ struct qla_tgt_data t = {
.magic = QLA2X_TARGET_MAGIC,
.tgt24_atio_pkt = q24_atio_pkt,
.tgt_response_pkt = q2t_response_pkt,
TRACE_ENTRY();
- res = qla2xxx_tgt_register_driver(&itd, &tgt_data);
- if (res != 0) {
+ res = qla2xxx_tgt_register_driver(&t);
+ if (res < 0) {
PRINT_ERROR("Unable to register driver: %d", res);
goto out;
}
- if (tgt_data.magic != QLA2X_INITIATOR_MAGIC) {
+ if (res != QLA2X_INITIATOR_MAGIC) {
PRINT_ERROR("Wrong version of the initiator part: %d",
- tgt_data.magic);
+ res);
res = -EINVAL;
+ goto out;
}
PRINT_INFO("%s", "Target mode driver for QLogic 2x00 controller "
/* Big hammer */
if (!ha->host_shutting_down)
- tgt_data.disable_tgt_mode(ha);
+ qla2x00_disable_tgt_mode(ha);
/* Wait for sessions to clear out (just in case) */
wait_event(tgt->waitQ, test_tgt_sess_count(tgt));
/* Sending marker isn't necessary, since we called from ISR */
- pkt = (modify_lun_entry_t *)tgt_data.req_pkt(ha);
+ pkt = (modify_lun_entry_t *)qla2x00_req_pkt(ha);
if (pkt == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (q2t_issue_marker(ha, 1) != QLA_SUCCESS)
goto out;
- ntfy = (nack_entry_t *)tgt_data.req_pkt(ha);
+ ntfy = (nack_entry_t *)qla2x00_req_pkt(ha);
if (ntfy == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (q2t_issue_marker(ha, 1) != QLA_SUCCESS)
goto out;
- resp = (abts24_resp_entry_t *)tgt_data.req_pkt(ha);
+ resp = (abts24_resp_entry_t *)qla2x00_req_pkt(ha);
if (resp == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (q2t_issue_marker(ha, 1) != QLA_SUCCESS)
goto out;
- ctio = (ctio7_status1_entry_t *)tgt_data.req_pkt(ha);
+ ctio = (ctio7_status1_entry_t *)qla2x00_req_pkt(ha);
if (ctio == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (q2t_issue_marker(ha, 1) != QLA_SUCCESS)
goto out;
- ctio = (ctio7_status1_entry_t *)tgt_data.req_pkt(ha);
+ ctio = (ctio7_status1_entry_t *)qla2x00_req_pkt(ha);
if (ctio == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (ha->tgt != NULL)
ha->tgt->notify_ack_expected++;
- nack = (nack24xx_entry_t *)tgt_data.req_pkt(ha);
+ nack = (nack24xx_entry_t *)qla2x00_req_pkt(ha);
if (nack == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (!ha_locked)
spin_lock_irqsave(&ha->hardware_lock, flags);
- ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
+ ctio = (ctio_ret_entry_t *)qla2x00_req_pkt(ha);
if (ctio == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
if (!ha_locked)
spin_lock_irqsave(&ha->hardware_lock, flags);
- ctio = (ctio7_status1_entry_t *)tgt_data.req_pkt(ha);
+ ctio = (ctio7_status1_entry_t *)qla2x00_req_pkt(ha);
if (ctio == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
/* set the Clear LIP reset event flag */
add_flags |= NOTIFY_ACK_CLEAR_LIP_RESET;
}
- tgt_data.mark_all_devices_lost(ha, 1);
+ qla2x00_mark_all_devices_lost(ha, 1);
if (q2t_reset(ha, iocb, Q2T_ABORT_ALL) == 0)
send_notify_ack = 0;
break;
case IMM_NTFY_PORT_LOGOUT:
TRACE(TRACE_MGMT, "Port logout (S %08x -> L %#x)",
le16_to_cpu(iocb2x->seq_id), le16_to_cpu(iocb2x->lun));
- tgt_data.mark_all_devices_lost(ha, 1);
+ qla2x00_mark_all_devices_lost(ha, 1);
if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS_SESS) == 0)
send_notify_ack = 0;
/* The sessions will be cleared in the callback, if needed */
case IMM_NTFY_GLBL_TPRLO:
TRACE(TRACE_MGMT, "Global TPRLO (%x)", status);
- tgt_data.mark_all_devices_lost(ha, 1);
+ qla2x00_mark_all_devices_lost(ha, 1);
if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS) == 0)
send_notify_ack = 0;
/* The sessions will be cleared in the callback, if needed */
case IMM_NTFY_PORT_CONFIG:
TRACE(TRACE_MGMT, "Port config changed (%x)", status);
- tgt_data.mark_all_devices_lost(ha, 1);
+ qla2x00_mark_all_devices_lost(ha, 1);
if (q2t_reset(ha, iocb, Q2T_ABORT_ALL) == 0)
send_notify_ack = 0;
/* The sessions will be cleared in the callback, if needed */
PRINT_ERROR("qla2x00tgt(%ld): Link failure detected",
ha->instance);
/* I_T nexus loss */
- tgt_data.mark_all_devices_lost(ha, 1);
+ qla2x00_mark_all_devices_lost(ha, 1);
if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS) == 0)
send_notify_ack = 0;
break;
/* Sending marker isn't necessary, since we called from ISR */
- ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
+ ctio = (ctio_ret_entry_t *)qla2x00_req_pkt(ha);
if (ctio == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
/* Sending marker isn't necessary, since we called from ISR */
- ctio = (ctio7_status1_entry_t *)tgt_data.req_pkt(ha);
+ ctio = (ctio7_status1_entry_t *)qla2x00_req_pkt(ha);
if (ctio == NULL) {
PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
"request packet", ha->instance, __func__);
}
/* Get list of logged in devices */
- rc = tgt_data.get_id_list(ha, gid_list, gid_list_dma, &entries);
+ rc = qla2x00_get_id_list(ha, gid_list, gid_list_dma, &entries);
if (rc != QLA_SUCCESS) {
PRINT_ERROR("get_id_list() failed: %x", rc);
res = -1;
fcport->loop_id = loop_id;
- rc = tgt_data.get_port_database(ha, fcport, 0);
+ rc = qla2x00_get_port_database(ha, fcport, 0);
if (rc != QLA_SUCCESS) {
PRINT_ERROR("Failed to retrieve fcport information "
"-- get_port_database() returned %x "
do_enable:
TRACE_DBG("Enable tgt mode for host %ld(%ld,%p)",
ha->host_no, ha->instance, ha);
- tgt_data.enable_tgt_mode(ha);
+ qla2x00_enable_tgt_mode(ha);
break;
}
module_init(q2t_init);
module_exit(q2t_exit);
-MODULE_AUTHOR("Vladislav Bolkhovitin, Leonid Stoljar & Nathaniel Clark");
-MODULE_DESCRIPTION("Target mode addon for qla2[2,3,4+]xx");
+MODULE_AUTHOR("Vladislav Bolkhovitin and others");
+MODULE_DESCRIPTION("Target mode addon for qla2[2,3,4,5+]xx");
MODULE_LICENSE("GPL");
MODULE_VERSION(Q2T_VERSION_STRING);
#define LEAVE(a)
#endif
-#define QLA2X_TARGET_MAGIC 263
-#define QLA2X_INITIATOR_MAGIC 57216
+/*
+ * Must be changed on any change in any initiator visible interfaces or
+ * data in the target add-on
+ */
+#define QLA2X_TARGET_MAGIC 264
+
+/*
+ * Must be changed on any change in any target visible interfaces or
+ * data in the initiator
+ */
+#define QLA2X_INITIATOR_MAGIC 57217
#define QLA2X00_COMMAND_COUNT_INIT 250
#define QLA2X00_IMMED_NOTIFY_COUNT_INIT 250
ENABLE_TARGET_MODE = 1
} qla2x_tgt_host_action_t;
-struct qla_tgt_initiator {
+/* Changing it don't forget to change QLA2X_TARGET_MAGIC! */
+struct qla_tgt_data {
int magic;
/* Callbacks */
void (*tgt_fc_port_deleted)(scsi_qla_host_t *ha, fc_port_t *fcport);
};
-struct qla_target {
- int magic;
-
- /*
- * Callbacks - H/W lock MUST be held while calling any.
- *
- * !!! req_pkt() and issue_marker() could unlock/lock it inside !!!
- *
- * But it isn't an issue, since in the current implementation:
- *
- * - Either we in IRQ and only IRQ handler can modify HW data,
- * including rings related fields.
- *
- * - Or access to target mode variables from struct q2t_tgt don't
- * cross those functions boundaries, except tgt_shutdown, which
- * additionally protected by irq_cmd_count.
- */
- request_t *(*req_pkt)(scsi_qla_host_t *ha);
- void (*isp_cmd)(scsi_qla_host_t *ha);
- void (*enable_tgt_mode)(scsi_qla_host_t *ha);
- void (*disable_tgt_mode)(scsi_qla_host_t *ha);
- int (*issue_marker)(scsi_qla_host_t *ha, int ha_locked);
- void (*mark_all_devices_lost)(scsi_qla_host_t *ha, int defer);
- int (*get_id_list)(scsi_qla_host_t *ha, void *id_list,
- dma_addr_t id_list_dma, uint16_t *entries);
- int (*get_port_database)(scsi_qla_host_t *ha, fc_port_t *fcport,
- uint8_t opt);
-};
-
-int qla2xxx_tgt_register_driver(/* IN */ struct qla_tgt_initiator *tgt,
- /* OUT */ struct qla_target *init);
+int qla2xxx_tgt_register_driver(struct qla_tgt_data *tgt);
void qla2xxx_tgt_unregister_driver(void);