summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/cpqary3/cpqary3.h
blob: 0c56d3b3565e7a0708531b15216f8fed02cf70de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
 */

#ifndef	_CPQARY3_H
#define	_CPQARY3_H

#include <sys/types.h>
#include <sys/pci.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/conf.h>
#include <sys/map.h>
#include <sys/modctl.h>
#include <sys/kmem.h>
#include <sys/cmn_err.h>
#include <sys/stat.h>
#include <sys/scsi/scsi.h>
#include <sys/devops.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>

#include <cpqary3_ciss.h>
#include <cpqary3_bd.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 *	Ioctl Commands
 */
#define	CPQARY3_IOCTL_CMD		('c' << 4)
#define	CPQARY3_IOCTL_DRIVER_INFO	CPQARY3_IOCTL_CMD | 0x01
#define	CPQARY3_IOCTL_CTLR_INFO		CPQARY3_IOCTL_CMD | 0x02
#define	CPQARY3_IOCTL_BMIC_PASS		CPQARY3_IOCTL_CMD | 0x04
#define	CPQARY3_IOCTL_SCSI_PASS		CPQARY3_IOCTL_CMD | 0x08

/* Driver Revision : Used in Ioctl */
#define	CPQARY3_MINOR_REV_NO	00
#define	CPQARY3_MAJOR_REV_NO	01
#define	CPQARY3_REV_DATE	05
#define	CPQARY3_REV_MONTH	04
#define	CPQARY3_REV_YEAR	2001

/* Some Useful definations */
#define	CPQARY3_FAILURE		0
#define	CPQARY3_SUCCESS		1
#define	CPQARY3_SENT		2
#define	CPQARY3_SUBMITTED	3
#define	CPQARY3_NO_SIG		4

#define	CPQARY3_TRUE		1
#define	CPQARY3_FALSE		0

#define	CTLR_SCSI_ID		7
#define	CPQARY3_LD_FAILED	1
/*
 * Defines for cleanup in cpqary3_attach and cpqary3_detach.
 */
#define	CPQARY3_HBA_TRAN_ALLOC_DONE	0x0001
#define	CPQARY3_HBA_TRAN_ATTACH_DONE	0x0002
#define	CPQARY3_CTLR_CONFIG_DONE	0x0004
#define	CPQARY3_INTR_HDLR_SET		0x0008
#define	CPQARY3_CREATE_MINOR_NODE	0x0010
#define	CPQARY3_SOFTSTATE_ALLOC_DONE	0x0020
#define	CPQARY3_MUTEX_INIT_DONE		0x0040
#define	CPQARY3_TICK_TMOUT_REGD		0x0080
#define	CPQARY3_MEM_MAPPED		0x0100
#define	CPQARY3_SW_INTR_HDLR_SET	0x0200
#define	CPQARY3_SW_MUTEX_INIT_DONE	0x0400
#define	CPQARY3_NOE_INIT_DONE		0x0800

#define	CPQARY3_CLEAN_ALL		0x0FFF

#define	CPQARY3_TICKTMOUT_VALUE		180000000    /* 180 seconds */

/*
 * Defines for Maximum and Default Settings.
 */

#define	MAX_LOGDRV		64	/* Max supported Logical Drivers */
#define	MAX_CTLRS		8	/* Max supported Controllers */
#define	MAX_TAPE		28
/*
 * NOTE: When changing the below two entries, Max SG count in cpqary3_ciss.h
 * should also be changed.
 */
/* SG */
#define	MAX_PERF_SG_CNT		64	/* Maximum S/G in performant mode */
#define	CPQARY3_SG_CNT		30	/* minimum S/G in simple mode */
#define	CPQARY3_PERF_SG_CNT	31	/* minimum S/G for performant mode */
/* SG */


#define	CPQARY3_MAX_TGT		(MAX_LOGDRV + MAX_TAPE + 1)

/*
 * SCSI Capabilities Related IDs
 */
#define	CPQARY3_CAP_DISCON_ENABLED		0x01
#define	CPQARY3_CAP_SYNC_ENABLED		0x02
#define	CPQARY3_CAP_WIDE_XFER_ENABLED		0x04
#define	CPQARY3_CAP_ARQ_ENABLED			0x08
#define	CPQARY3_CAP_TAG_QING_ENABLED		0x10
#define	CPQARY3_CAP_TAG_QING_SUPP		0x20
#define	CPQARY3_CAP_UNTAG_DRV_QING_ENABLED	0x40

/*
 * Defines for HBA
 */
#define	CAP_NOT_DEFINED		-1
#define	CAP_CHG_NOT_ALLOWED	0
#define	CAP_CHG_SUCCESS		1

/*
 * Macros for Data Access
 */

/* SCSI Addr to Per Controller */
#define	SA2CTLR(saddr)	((cpqary3_t *)((saddr)->a_hba_tran->tran_hba_private))
#define	SA2TGT(sa)	(sa)->a_target	/* SCSI Addr to Target ID */
#define	SD2TGT(sd)	(sd)->sd_address.a_target /* SCSI Dev to Target ID */
#define	SD2LUN(sd)	(sd)->sd_address.a_lun	/* SCSI Dev to Lun */
#define	SD2SA(sd)	((sd)->sd_address)	/* SCSI Dev to SCSI Addr */

/* SCSI Dev to Per Controller */
#define	SD2CTLR(sd)	\
	((cpqary3_t *)sd->sd_address.a_hba_tran->tran_hba_private)

#define	PKT2PVTPKT(sp)  	((cpqary3_pkt_t *)((sp)->pkt_ha_private))
#define	PVTPKT2MEM(p)		((cpqary3_cmdpvt_t *)p->memp)
#define	MEM2CMD(m)		((CommandList_t *)m->cmdlist_memaddr)
#define	SP2CMD(sp)		MEM2CMD(PVTPKT2MEM(PKT2PVTPKT(sp)))
#define	CTLR2MEMLISTP(ctlr)	((cpqary3_cmdmemlist_t *)ctlr->cmdmemlistp)
#define	MEM2PVTPKT(m)		((cpqary3_pkt_t *)m->pvt_pkt)
#define	MEM2DRVPVT(m)		((cpqary3_private_t *)m->driverdata)
#define	TAG2MEM(ctlr, tag)	\
	((cpqary3_cmdpvt_t *)(CTLR2MEMLISTP(ctlr)->pool[tag]))

/* MACROS */
#define	CPQARY3_MIN(x, y)    		(x < y ? x : y)
#define	CPQARY3_SWAP(val)   		((val >> 8) | ((val & 0xff) << 8))
#define	RETURN_VOID_IF_NULL(x)  	if (NULL == x) return
#define	RETURN_NULL_IF_NULL(x)  	if (NULL == x) return (NULL)
#define	RETURN_FAILURE_IF_NULL(x)	if (NULL == x) return (CPQARY3_FAILURE)

/*
 * Macros for memory allocation/deallocations
 */
#define	MEM_ZALLOC(x)		kmem_zalloc(x, KM_NOSLEEP)
#define	MEM_SFREE(x, y)		if (x) kmem_free((void*)x, y)

/*
 * Convenient macros for reading/writing Configuration table registers
 */
#define	DDI_GET8(ctlr, regp)	 		\
	ddi_get8((ctlr)->ct_handle, (uint8_t *)(regp))
#define	DDI_PUT8(ctlr, regp, value)		\
	ddi_put8((ctlr)->ct_handle, (uint8_t *)(regp), (value))
#define	DDI_GET16(ctlr, regp)	 		\
	ddi_get16((ctlr)->ct_handle, (uint16_t *)(regp))
#define	DDI_PUT16(ctlr, regp, value)	\
	ddi_put16((ctlr)->ct_handle, (uint16_t *)(regp), (value))
#define	DDI_GET32(ctlr, regp)	 		\
	ddi_get32((ctlr)->ct_handle, (uint32_t *)(regp))
#define	DDI_PUT32(ctlr, regp, value) 	\
	ddi_put32((ctlr)->ct_handle, (uint32_t *)(regp), (value))
			/* PERF */
#define	DDI_PUT32_CP(ctlr, regp, value)   \
	ddi_put32((ctlr)->cp_handle, (uint32_t *)(regp), (value))
			/* PERF */

#define	CPQARY3_BUFFER_ERROR_CLEAR	0x0	/* to be used with bioerror */
#define	CPQARY3_DMA_NO_CALLBACK		0x0	/* to be used with DMA calls */
#define	CPQARY3_DMA_ALLOC_HANDLE_DONE	0x01
#define	CPQARY3_DMA_ALLOC_MEM_DONE	0x02
#define	CPQARY3_DMA_BIND_ADDR_DONE	0x04
#define	CPQARY3_FREE_PHYCTG_MEM		0x07
#define	CPQARY3_SYNCCMD_SEND_WAITSIG	(0x0001)

/*
 * Include the driver specific relevant header files here.
 */
#include "cpqary3_ciss.h"
#include "cpqary3_q_mem.h"
#include "cpqary3_noe.h"
#include "cpqary3_scsi.h"
#include "cpqary3_ioctl.h"

/*
 * Per Target Structure
 */

typedef struct cpqary3_target {
	uint32_t	logical_id : 30; /* at most 64 : 63 drives + 1 CTLR */
	uint32_t	type : 2;	/* NONE, CTLR, LOGICAL DRIVE, TAPE */
	PhysDevAddr_t	PhysID;
	union {
		struct {
			uint8_t	id;
			uint8_t	bus;
		} scsi;		/* To support tapes */
		struct {
			uint8_t	heads;
			uint8_t	sectors;
		} drive;	/* Logical drives */
	} properties;

	uint32_t	ctlr_flags;
	dev_info_t	*tgt_dip;
	ddi_dma_attr_t	dma_attrs;
} cpqary3_tgt_t;


/*
 * Values for the type field in the Per Target Structure (above)
 */
#define	CPQARY3_TARGET_NONE		0	/* No Device */
#define	CPQARY3_TARGET_CTLR		1	/* Controller */
#define	CPQARY3_TARGET_LOG_VOL		2	/* Logical Volume */
#define	CPQARY3_TARGET_TAPE		3	/* SCSI Device - Tape */

/*
 * Index into PCI Configuration Registers for Base Address Registers(BAR)
 * Currently, only index for BAR 0 and BAR 1 are defined
 */
#define	INDEX_PCI_BASE0			1	/* offset 0x10 */
#define	INDEX_PCI_BASE1			2	/* offset 0x14 */

/* Offset Values for IO interface from BAR 0 */
#define	INBOUND_DOORBELL		0x20
#define	OUTBOUND_LIST_STATUS		0x30
#define	OUTBOUND_INTERRUPT_MASK		0x34
#define	INBOUND_QUEUE			0x40
#define	OUTBOUND_QUEUE			0x44

/* Offset Values for IO interface from BAR 1 */
#define	CONFIGURATION_TABLE		0x00

#define	INTR_DISABLE_5300_MASK		0x00000008l
#define	INTR_DISABLE_5I_MASK		0x00000004l

#define	OUTBOUND_LIST_5300_EXISTS	0x00000008l
#define	OUTBOUND_LIST_5I_EXISTS		0x00000004l

#define	INTR_PERF_MASK			0x00000001l

#define	INTR_PERF_LOCKUP_MASK		0x00000004l

#define	INTR_E200_PERF_MASK		0x00000004l

#define	INTR_SIMPLE_MASK		0x00000008l
#define	INTR_SIMPLE_LOCKUP_MASK		0x0000000cl


#define	INTR_SIMPLE_5I_MASK		0x00000004l
#define	INTR_SIMPLE_5I_LOCKUP_MASK	0x0000000cl

typedef struct cpqary3_per_controller CTLR;
/*
 * Per Controller Structure
 */
typedef struct cpqary3_per_controller {
	/* System Dependent Entities */
	uint8_t			bus;
	uint8_t			dev : 5;
	uint8_t			fun : 3;
	uint32_t		instance;
	dev_info_t		*dip;

	/* Controller Specific Information */
	int8_t			hba_name[38];
	ulong_t			num_of_targets;
	uint32_t		heartbeat;
	uint32_t		board_id;
	cpqary3_bd_t		*bddef;

	/* Condition Variables used */
	kcondvar_t		cv_immediate_wait;
	kcondvar_t		cv_noe_wait;
	kcondvar_t		cv_flushcache_wait;
	kcondvar_t		cv_abort_wait;
	kcondvar_t		cv_ioctl_wait; /* Variable for ioctls */

	/*
	 * CPQary3 driver related entities related to :
	 * 	Hardware & Software Interrupts, Cookies & Mutex.
	 * 	Timeout Handler
	 *	Driver Transport Layer/Structure
	 *	Database for the per-controller Command Memory Pool
	 *	Target List for the per-controller
	 */
	uint8_t			irq;		/* h/w IRQ */
	ddi_iblock_cookie_t	hw_iblock_cookie; /* cookie for h/w intr */
	kmutex_t		hw_mutex;	/* h/w mutex */
	ddi_iblock_cookie_t	sw_iblock_cookie; /* cookie for s/w intr */
	kmutex_t		sw_mutex;	/* s/w mutex */
	ddi_softintr_t		cpqary3_softintr_id; /* s/w intr identifier */
	uint8_t			swintr_flag;
	timeout_id_t		tick_tmout_id;	/* timeout identifier */
	uint8_t			cpqary3_tick_hdlr;
	scsi_hba_tran_t		*hba_tran;	/* transport structure */
	cpqary3_cmdmemlist_t	*cmdmemlistp;	/* database - Memory Pool */
	cpqary3_tgt_t		*cpqary3_tgtp[CPQARY3_MAX_TGT];
	cpqary3_drvr_replyq_t	*drvr_replyq;


	uint8_t			(*check_ctlr_intr)(CTLR *);

	/*
	 * PCI Configuration Registers
	 * 0x10	Primary I2O Memory BAR 	- for Host Interface
	 * 0x14	Primary DRAM 1 BAR	- for Transport Configuration Table
	 *
	 * Host Interface Registers
	 * Offset from Primary I2O Memory BAR
	 * 0x20 Inbound Doorbell	- for interrupting controller
	 * 0x30	Outbound List Status 	- for signalling status of Reply Q
	 * 0x34	Outbound Interrupt Mask	- for masking Interrupts to host
	 * 0x40	Host Inbound Queue	- Request Q
	 * 0x44	Host Outbound Queue	- reply Q
	 *
	 * Offset from Primary DRAM 1 BAR
	 * 0x00	Configuration Table 	- for Controller Transport Layer
	 */

	uint32_t		*idr;
	ddi_acc_handle_t	idr_handle;

	/* LOCKUP CODE */
	uint32_t		*spr0;
	ddi_acc_handle_t    	spr0_handle;
	/* LOCKUP CODE */

	uint32_t		*odr;
	ddi_acc_handle_t	odr_handle;

	uint32_t		*odr_cl;
	ddi_acc_handle_t	odr_cl_handle;

	uint32_t		*isr;
	ddi_acc_handle_t	isr_handle;

	uint32_t		*imr;
	ddi_acc_handle_t	imr_handle;

	uint32_t		*ipq;
	ddi_acc_handle_t	ipq_handle;

	uint32_t		*opq;
	ddi_acc_handle_t	opq_handle;

	CfgTable_t		*ct;
	ddi_acc_handle_t	ct_handle;

	CfgTrans_Perf_t		*cp;
	ddi_acc_handle_t	cp_handle;

	uint32_t		legacy_mapping;
	uint32_t		noe_support;
	/* SG */
	uint32_t		sg_cnt;
	/* SG */
	uint32_t		ctlr_maxcmds;
	uint32_t		host_support;
	uint8_t			controller_lockup;
	uint8_t			lockup_logged;
	uint32_t		poll_flag;
} cpqary3_t;


/*
 * Private Structure for Self Issued Commands
 */

typedef struct cpqary3_driver_private {
	void				*sg;
	cpqary3_phyctg_t	*phyctgp;
}cpqary3_private_t;

/* cmd_flags */
#define	CFLAG_DMASEND	0x01
#define	CFLAG_CMDIOPB	0x02
#define	CFLAG_DMAVALID	0x04

/*
 * Driver Private Packet
 */
typedef struct cpqary3_pkt {
	struct scsi_pkt		*scsi_cmd_pkt;
	ddi_dma_win_t		prev_winp;
	ddi_dma_seg_t		prev_segp;
	clock_t			cmd_start_time;
	/* SG */
	ddi_dma_cookie_t	cmd_dmacookies[MAX_PERF_SG_CNT];
	/* SG */
	uint32_t		cmd_ncookies;
	uint32_t		cmd_cookie;
	uint32_t		cmd_cookiecnt;
	uint32_t		cmd_nwin;
	uint32_t		cmd_curwin;
	off_t			cmd_dma_offset;
	size_t			cmd_dma_len;
	size_t			cmd_dmacount;
	struct buf		*bf;
	ddi_dma_handle_t   	cmd_dmahandle;
	uint32_t		bytes;
	uint32_t		cmd_flags;
	uint32_t		cdb_len;
	uint32_t		scb_len;
	cpqary3_cmdpvt_t	*memp;
} cpqary3_pkt_t;

#pragma pack(1)

typedef struct cpqary3_ioctlresp {
	/* Driver Revision */
	struct cpqary3_revision {
		uint8_t		minor; /* Version */
		uint8_t		major;
		uint8_t		mm;    /* Revision Date */
		uint8_t		dd;
		uint16_t	yyyy;
	} cpqary3_drvrev;

	/* HBA Info */
	struct cpqary3_ctlr {
		uint8_t		num_of_tgts; /* No of Logical Drive */
		uint8_t		*name;
	} cpqary3_ctlr;
} cpqary3_ioctlresp_t;

typedef struct cpqary3_ioctlreq {
	cpqary3_ioctlresp_t	*cpqary3_ioctlrespp;
} cpqary3_ioctlreq_t;

#pragma pack()

/* Driver function definitions */

void cpqary3_init_hbatran(cpqary3_t *);
void cpqary3_read_conf_file(dev_info_t *, cpqary3_t *);
void cpqary3_tick_hdlr(void *);
void cpqary3_flush_cache(cpqary3_t *);
void cpqary3_intr_onoff(cpqary3_t *, uint8_t);
void cpqary3_lockup_intr_onoff(cpqary3_t *, uint8_t);
uint8_t cpqary3_disable_NOE_command(cpqary3_t *);
uint8_t cpqary3_send_NOE_command(cpqary3_t *, cpqary3_cmdpvt_t *, uint8_t);
uint16_t cpqary3_init_ctlr_resource(cpqary3_t *);
uint32_t cpqary3_hw_isr(caddr_t);
uint32_t cpqary3_sw_isr(caddr_t);
int32_t cpqary3_ioctl_driver_info(uintptr_t, int);
int32_t cpqary3_ioctl_ctlr_info(uintptr_t, cpqary3_t *, int);
int32_t cpqary3_ioctl_bmic_pass(uintptr_t, cpqary3_t *, int);
int32_t cpqary3_ioctl_scsi_pass(uintptr_t, cpqary3_t *, int);
uint8_t cpqary3_probe4targets(cpqary3_t *);
void cpqary3_cmdlist_release(cpqary3_cmdpvt_t *, uint8_t);
int32_t cpqary3_submit(cpqary3_t *, uint32_t);
void cpqary3_free_phyctgs_mem(cpqary3_phyctg_t *, uint8_t);
caddr_t cpqary3_alloc_phyctgs_mem(cpqary3_t *, size_t, uint32_t *,
    cpqary3_phyctg_t *);
cpqary3_cmdpvt_t *cpqary3_cmdlist_occupy(cpqary3_t *);
void cpqary3_synccmd_complete(cpqary3_cmdpvt_t *);
void cpqary3_NOE_handler(cpqary3_cmdpvt_t *);
uint8_t cpqary3_retrieve(cpqary3_t *);
void cpqary3_synccmd_cleanup(cpqary3_cmdpvt_t *);
int cpqary3_target_geometry(struct scsi_address *);
uint8_t cpqary3_send_abortcmd(cpqary3_t *, uint16_t, CommandList_t *);
void cpqary3_memfini(cpqary3_t *, uint8_t);
uint8_t cpqary3_init_ctlr(cpqary3_t *);
int16_t cpqary3_meminit(cpqary3_t *);
void cpqary3_noe_complete(cpqary3_cmdpvt_t *cpqary3_cmdpvtp);
cpqary3_cmdpvt_t *cpqary3_synccmd_alloc(cpqary3_t *, size_t);
void cpqary3_synccmd_free(cpqary3_t *, cpqary3_cmdpvt_t *);
int cpqary3_synccmd_send(cpqary3_t *, cpqary3_cmdpvt_t *, clock_t, int);
uint8_t cpqary3_poll_retrieve(cpqary3_t *cpqary3p, uint32_t poll_tag);
uint8_t cpqary3_build_cmdlist(cpqary3_cmdpvt_t *cpqary3_cmdpvtp, uint32_t tid);

#ifdef	__cplusplus
}
#endif

#endif	/* _CPQARY3_H */