qla_inline.h 4.2 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
A
Andrew Vasquez 已提交
2
 * QLogic Fibre Channel HBA Driver
3
 * Copyright (c)  2003-2011 QLogic Corporation
L
Linus Torvalds 已提交
4
 *
A
Andrew Vasquez 已提交
5
 * See LICENSE.qla2xxx for copyright and licensing details.
L
Linus Torvalds 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18
 */

/*
 * qla2x00_debounce_register
 *      Debounce register.
 *
 * Input:
 *      port = register address.
 *
 * Returns:
 *      register value.
 */
static __inline__ uint16_t
A
Andrew Vasquez 已提交
19
qla2x00_debounce_register(volatile uint16_t __iomem *addr)
L
Linus Torvalds 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33
{
	volatile uint16_t first;
	volatile uint16_t second;

	do {
		first = RD_REG_WORD(addr);
		barrier();
		cpu_relax();
		second = RD_REG_WORD(addr);
	} while (first != second);

	return (first);
}

A
Andrew Vasquez 已提交
34
static inline void
35
qla2x00_poll(struct rsp_que *rsp)
L
Linus Torvalds 已提交
36
{
37
	unsigned long flags;
38
	struct qla_hw_data *ha = rsp->hw;
39
	local_irq_save(flags);
40 41 42 43
	if (IS_QLA82XX(ha))
		qla82xx_poll(0, rsp);
	else
		ha->isp_ops->intr_handler(0, rsp);
44
	local_irq_restore(flags);
L
Linus Torvalds 已提交
45 46
}

47 48 49 50 51 52 53 54 55 56 57 58
static inline uint8_t *
host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
{
       uint32_t *ifcp = (uint32_t *) fcp;
       uint32_t *ofcp = (uint32_t *) fcp;
       uint32_t iter = bsize >> 2;

       for (; iter ; iter--)
               *ofcp++ = swab32(*ifcp++);

       return fcp;
}
59 60

static inline int
61
qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
62
{
63
	struct qla_hw_data *ha = vha->hw;
64
	if (IS_FWI2_CAPABLE(ha))
65 66
		return (loop_id > NPH_LAST_HANDLE);

67
	return ((loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
68
	    loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST);
69
}
70 71 72 73 74

static inline void
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
{
	struct dsd_dma *dsd_ptr, *tdsd_ptr;
75 76 77
	struct crc_context *ctx;

	ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
78 79 80

	/* clean up allocated prev pool */
	list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
81
	    &ctx->dsd_list, list) {
82 83 84 85 86
		dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
		    dsd_ptr->dsd_list_dma);
		list_del(&dsd_ptr->list);
		kfree(dsd_ptr);
	}
87
	INIT_LIST_HEAD(&ctx->dsd_list);
88
}
89 90 91 92 93 94 95 96 97 98 99

static inline void
qla2x00_set_fcport_state(fc_port_t *fcport, int state)
{
	int old_state;

	old_state = atomic_read(&fcport->state);
	atomic_set(&fcport->state, state);

	/* Don't print state transitions during initial allocation of fcport */
	if (old_state && old_state != state) {
100 101 102
		ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
		    "FCPort state transitioned from %s to %s - "
		    "portid=%02x%02x%02x.\n",
103 104
		    port_state_str[old_state], port_state_str[state],
		    fcport->d_id.b.domain, fcport->d_id.b.area,
105
		    fcport->d_id.b.al_pa);
106 107
	}
}
108 109

static inline int
110
qla2x00_hba_err_chk_enabled(srb_t *sp)
111
{
112 113 114 115 116 117 118
	/*
	 * Uncomment when corresponding SCSI changes are done.
	 *
	if (!sp->cmd->prot_chk)
		return 0;
	 *
	 */
119
	switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	case SCSI_PROT_READ_STRIP:
	case SCSI_PROT_WRITE_INSERT:
		if (ql2xenablehba_err_chk >= 1)
			return 1;
		break;
	case SCSI_PROT_READ_PASS:
	case SCSI_PROT_WRITE_PASS:
		if (ql2xenablehba_err_chk >= 2)
			return 1;
		break;
	case SCSI_PROT_READ_INSERT:
	case SCSI_PROT_WRITE_STRIP:
		return 1;
	}
	return 0;
}
136 137 138 139 140 141 142 143 144 145 146 147 148

static inline int
qla2x00_reset_active(scsi_qla_host_t *vha)
{
	scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);

	/* Test appropriate base-vha and vha flags. */
	return test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) ||
	    test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
}
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183

static inline srb_t *
qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
{
	srb_t *sp = NULL;
	struct qla_hw_data *ha = vha->hw;
	uint8_t bail;

	QLA_VHA_MARK_BUSY(vha, bail);
	if (unlikely(bail))
		return NULL;

	sp = mempool_alloc(ha->srb_mempool, flag);
	if (!sp)
		goto done;

	memset(sp, 0, sizeof(*sp));
	sp->fcport = fcport;
	sp->iocbs = 1;
done:
	if (!sp)
		QLA_VHA_MARK_NOT_BUSY(vha);
	return sp;
}

static inline void
qla2x00_init_timer(srb_t *sp, unsigned long tmo)
{
	init_timer(&sp->u.iocb_cmd.timer);
	sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
	sp->u.iocb_cmd.timer.data = (unsigned long)sp;
	sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
	add_timer(&sp->u.iocb_cmd.timer);
	sp->free = qla2x00_sp_free;
}
184 185 186 187 188 189

static inline int
qla2x00_gid_list_size(struct qla_hw_data *ha)
{
	return sizeof(struct gid_list_info) * ha->max_fibre_devices;
}