1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
14  */
15 
16 #ifndef	_CPQARY3_H
17 #define	_CPQARY3_H
18 
19 #include <sys/types.h>
20 #include <sys/pci.h>
21 #include <sys/param.h>
22 #include <sys/errno.h>
23 #include <sys/conf.h>
24 #include <sys/map.h>
25 #include <sys/modctl.h>
26 #include <sys/kmem.h>
27 #include <sys/cmn_err.h>
28 #include <sys/stat.h>
29 #include <sys/scsi/scsi.h>
30 #include <sys/devops.h>
31 #include <sys/ddi.h>
32 #include <sys/sunddi.h>
33 
34 #include <cpqary3_ciss.h>
35 #include <cpqary3_bd.h>
36 
37 #ifdef	__cplusplus
38 extern "C" {
39 #endif
40 
41 /*
42  *	Ioctl Commands
43  */
44 #define	CPQARY3_IOCTL_CMD		('c' << 4)
45 #define	CPQARY3_IOCTL_DRIVER_INFO	CPQARY3_IOCTL_CMD | 0x01
46 #define	CPQARY3_IOCTL_CTLR_INFO		CPQARY3_IOCTL_CMD | 0x02
47 #define	CPQARY3_IOCTL_BMIC_PASS		CPQARY3_IOCTL_CMD | 0x04
48 #define	CPQARY3_IOCTL_SCSI_PASS		CPQARY3_IOCTL_CMD | 0x08
49 
50 /* Driver Revision : Used in Ioctl */
51 #define	CPQARY3_MINOR_REV_NO	00
52 #define	CPQARY3_MAJOR_REV_NO	01
53 #define	CPQARY3_REV_DATE	05
54 #define	CPQARY3_REV_MONTH	04
55 #define	CPQARY3_REV_YEAR	2001
56 
57 /* Some Useful definations */
58 #define	CPQARY3_FAILURE		0
59 #define	CPQARY3_SUCCESS		1
60 #define	CPQARY3_SENT		2
61 #define	CPQARY3_SUBMITTED	3
62 #define	CPQARY3_NO_SIG		4
63 
64 #define	CPQARY3_TRUE		1
65 #define	CPQARY3_FALSE		0
66 
67 #define	CTLR_SCSI_ID		7
68 #define	CPQARY3_LD_FAILED	1
69 /*
70  * Defines for cleanup in cpqary3_attach and cpqary3_detach.
71  */
72 #define	CPQARY3_HBA_TRAN_ALLOC_DONE	0x0001
73 #define	CPQARY3_HBA_TRAN_ATTACH_DONE	0x0002
74 #define	CPQARY3_CTLR_CONFIG_DONE	0x0004
75 #define	CPQARY3_INTR_HDLR_SET		0x0008
76 #define	CPQARY3_CREATE_MINOR_NODE	0x0010
77 #define	CPQARY3_SOFTSTATE_ALLOC_DONE	0x0020
78 #define	CPQARY3_MUTEX_INIT_DONE		0x0040
79 #define	CPQARY3_TICK_TMOUT_REGD		0x0080
80 #define	CPQARY3_MEM_MAPPED		0x0100
81 #define	CPQARY3_SW_INTR_HDLR_SET	0x0200
82 #define	CPQARY3_SW_MUTEX_INIT_DONE	0x0400
83 #define	CPQARY3_NOE_INIT_DONE		0x0800
84 
85 #define	CPQARY3_CLEAN_ALL		0x0FFF
86 
87 #define	CPQARY3_TICKTMOUT_VALUE		180000000    /* 180 seconds */
88 
89 /*
90  * Defines for Maximum and Default Settings.
91  */
92 
93 #define	MAX_LOGDRV		64	/* Max supported Logical Drivers */
94 #define	MAX_CTLRS		8	/* Max supported Controllers */
95 #define	MAX_TAPE		28
96 /*
97  * NOTE: When changing the below two entries, Max SG count in cpqary3_ciss.h
98  * should also be changed.
99  */
100 /* SG */
101 #define	MAX_PERF_SG_CNT		64	/* Maximum S/G in performant mode */
102 #define	CPQARY3_SG_CNT		30	/* minimum S/G in simple mode */
103 #define	CPQARY3_PERF_SG_CNT	31	/* minimum S/G for performant mode */
104 /* SG */
105 
106 
107 #define	CPQARY3_MAX_TGT		(MAX_LOGDRV + MAX_TAPE + 1)
108 
109 /*
110  * SCSI Capabilities Related IDs
111  */
112 #define	CPQARY3_CAP_DISCON_ENABLED		0x01
113 #define	CPQARY3_CAP_SYNC_ENABLED		0x02
114 #define	CPQARY3_CAP_WIDE_XFER_ENABLED		0x04
115 #define	CPQARY3_CAP_ARQ_ENABLED			0x08
116 #define	CPQARY3_CAP_TAG_QING_ENABLED		0x10
117 #define	CPQARY3_CAP_TAG_QING_SUPP		0x20
118 #define	CPQARY3_CAP_UNTAG_DRV_QING_ENABLED	0x40
119 
120 /*
121  * Defines for HBA
122  */
123 #define	CAP_NOT_DEFINED		-1
124 #define	CAP_CHG_NOT_ALLOWED	0
125 #define	CAP_CHG_SUCCESS		1
126 
127 /*
128  * Macros for Data Access
129  */
130 
131 /* SCSI Addr to Per Controller */
132 #define	SA2CTLR(saddr)	((cpqary3_t *)((saddr)->a_hba_tran->tran_hba_private))
133 #define	SA2TGT(sa)	(sa)->a_target	/* SCSI Addr to Target ID */
134 #define	SD2TGT(sd)	(sd)->sd_address.a_target /* SCSI Dev to Target ID */
135 #define	SD2LUN(sd)	(sd)->sd_address.a_lun	/* SCSI Dev to Lun */
136 #define	SD2SA(sd)	((sd)->sd_address)	/* SCSI Dev to SCSI Addr */
137 
138 /* SCSI Dev to Per Controller */
139 #define	SD2CTLR(sd)	\
140 	((cpqary3_t *)sd->sd_address.a_hba_tran->tran_hba_private)
141 
142 #define	PKT2PVTPKT(sp)  	((cpqary3_pkt_t *)((sp)->pkt_ha_private))
143 #define	PVTPKT2MEM(p)		((cpqary3_cmdpvt_t *)p->memp)
144 #define	MEM2CMD(m)		((CommandList_t *)m->cmdlist_memaddr)
145 #define	SP2CMD(sp)		MEM2CMD(PVTPKT2MEM(PKT2PVTPKT(sp)))
146 #define	CTLR2MEMLISTP(ctlr)	((cpqary3_cmdmemlist_t *)ctlr->cmdmemlistp)
147 #define	MEM2PVTPKT(m)		((cpqary3_pkt_t *)m->pvt_pkt)
148 #define	MEM2DRVPVT(m)		((cpqary3_private_t *)m->driverdata)
149 #define	TAG2MEM(ctlr, tag)	\
150 	((cpqary3_cmdpvt_t *)(CTLR2MEMLISTP(ctlr)->pool[tag]))
151 
152 /* MACROS */
153 #define	CPQARY3_MIN(x, y)    		(x < y ? x : y)
154 #define	CPQARY3_SWAP(val)   		((val >> 8) | ((val & 0xff) << 8))
155 #define	RETURN_VOID_IF_NULL(x)  	if (NULL == x) return
156 #define	RETURN_NULL_IF_NULL(x)  	if (NULL == x) return (NULL)
157 #define	RETURN_FAILURE_IF_NULL(x)	if (NULL == x) return (CPQARY3_FAILURE)
158 
159 /*
160  * Macros for memory allocation/deallocations
161  */
162 #define	MEM_ZALLOC(x)		kmem_zalloc(x, KM_NOSLEEP)
163 #define	MEM_SFREE(x, y)		if (x) kmem_free((void*)x, y)
164 
165 /*
166  * Convenient macros for reading/writing Configuration table registers
167  */
168 #define	DDI_GET8(ctlr, regp)	 		\
169 	ddi_get8((ctlr)->ct_handle, (uint8_t *)(regp))
170 #define	DDI_PUT8(ctlr, regp, value)		\
171 	ddi_put8((ctlr)->ct_handle, (uint8_t *)(regp), (value))
172 #define	DDI_GET16(ctlr, regp)	 		\
173 	ddi_get16((ctlr)->ct_handle, (uint16_t *)(regp))
174 #define	DDI_PUT16(ctlr, regp, value)	\
175 	ddi_put16((ctlr)->ct_handle, (uint16_t *)(regp), (value))
176 #define	DDI_GET32(ctlr, regp)	 		\
177 	ddi_get32((ctlr)->ct_handle, (uint32_t *)(regp))
178 #define	DDI_PUT32(ctlr, regp, value) 	\
179 	ddi_put32((ctlr)->ct_handle, (uint32_t *)(regp), (value))
180 			/* PERF */
181 #define	DDI_PUT32_CP(ctlr, regp, value)   \
182 	ddi_put32((ctlr)->cp_handle, (uint32_t *)(regp), (value))
183 			/* PERF */
184 
185 #define	CPQARY3_BUFFER_ERROR_CLEAR	0x0	/* to be used with bioerror */
186 #define	CPQARY3_DMA_NO_CALLBACK		0x0	/* to be used with DMA calls */
187 #define	CPQARY3_DMA_ALLOC_HANDLE_DONE	0x01
188 #define	CPQARY3_DMA_ALLOC_MEM_DONE	0x02
189 #define	CPQARY3_DMA_BIND_ADDR_DONE	0x04
190 #define	CPQARY3_FREE_PHYCTG_MEM		0x07
191 #define	CPQARY3_SYNCCMD_SEND_WAITSIG	(0x0001)
192 
193 /*
194  * Include the driver specific relevant header files here.
195  */
196 #include "cpqary3_ciss.h"
197 #include "cpqary3_q_mem.h"
198 #include "cpqary3_noe.h"
199 #include "cpqary3_scsi.h"
200 #include "cpqary3_ioctl.h"
201 
202 /*
203  * Per Target Structure
204  */
205 
206 typedef struct cpqary3_target {
207 	uint32_t	logical_id : 30; /* at most 64 : 63 drives + 1 CTLR */
208 	uint32_t	type : 2;	/* NONE, CTLR, LOGICAL DRIVE, TAPE */
209 	PhysDevAddr_t	PhysID;
210 	union {
211 		struct {
212 			uint8_t	id;
213 			uint8_t	bus;
214 		} scsi;		/* To support tapes */
215 		struct {
216 			uint8_t	heads;
217 			uint8_t	sectors;
218 		} drive;	/* Logical drives */
219 	} properties;
220 
221 	uint32_t	ctlr_flags;
222 	dev_info_t	*tgt_dip;
223 	ddi_dma_attr_t	dma_attrs;
224 } cpqary3_tgt_t;
225 
226 
227 /*
228  * Values for the type field in the Per Target Structure (above)
229  */
230 #define	CPQARY3_TARGET_NONE		0	/* No Device */
231 #define	CPQARY3_TARGET_CTLR		1	/* Controller */
232 #define	CPQARY3_TARGET_LOG_VOL		2	/* Logical Volume */
233 #define	CPQARY3_TARGET_TAPE		3	/* SCSI Device - Tape */
234 
235 /*
236  * Index into PCI Configuration Registers for Base Address Registers(BAR)
237  * Currently, only index for BAR 0 and BAR 1 are defined
238  */
239 #define	INDEX_PCI_BASE0			1	/* offset 0x10 */
240 #define	INDEX_PCI_BASE1			2	/* offset 0x14 */
241 
242 /* Offset Values for IO interface from BAR 0 */
243 #define	INBOUND_DOORBELL		0x20
244 #define	OUTBOUND_LIST_STATUS		0x30
245 #define	OUTBOUND_INTERRUPT_MASK		0x34
246 #define	INBOUND_QUEUE			0x40
247 #define	OUTBOUND_QUEUE			0x44
248 
249 /* Offset Values for IO interface from BAR 1 */
250 #define	CONFIGURATION_TABLE		0x00
251 
252 #define	INTR_DISABLE_5300_MASK		0x00000008l
253 #define	INTR_DISABLE_5I_MASK		0x00000004l
254 
255 #define	OUTBOUND_LIST_5300_EXISTS	0x00000008l
256 #define	OUTBOUND_LIST_5I_EXISTS		0x00000004l
257 
258 #define	INTR_PERF_MASK			0x00000001l
259 
260 #define	INTR_PERF_LOCKUP_MASK		0x00000004l
261 
262 #define	INTR_E200_PERF_MASK		0x00000004l
263 
264 #define	INTR_SIMPLE_MASK		0x00000008l
265 #define	INTR_SIMPLE_LOCKUP_MASK		0x0000000cl
266 
267 
268 #define	INTR_SIMPLE_5I_MASK		0x00000004l
269 #define	INTR_SIMPLE_5I_LOCKUP_MASK	0x0000000cl
270 
271 typedef struct cpqary3_per_controller CTLR;
272 /*
273  * Per Controller Structure
274  */
275 typedef struct cpqary3_per_controller {
276 	/* System Dependent Entities */
277 	uint8_t			bus;
278 	uint8_t			dev : 5;
279 	uint8_t			fun : 3;
280 	uint32_t		instance;
281 	dev_info_t		*dip;
282 
283 	/* Controller Specific Information */
284 	int8_t			hba_name[38];
285 	ulong_t			num_of_targets;
286 	uint32_t		heartbeat;
287 	uint32_t		board_id;
288 	cpqary3_bd_t		*bddef;
289 
290 	/* Condition Variables used */
291 	kcondvar_t		cv_immediate_wait;
292 	kcondvar_t		cv_noe_wait;
293 	kcondvar_t		cv_flushcache_wait;
294 	kcondvar_t		cv_abort_wait;
295 	kcondvar_t		cv_ioctl_wait; /* Variable for ioctls */
296 
297 	/*
298 	 * CPQary3 driver related entities related to :
299 	 * 	Hardware & Software Interrupts, Cookies & Mutex.
300 	 * 	Timeout Handler
301 	 *	Driver Transport Layer/Structure
302 	 *	Database for the per-controller Command Memory Pool
303 	 *	Target List for the per-controller
304 	 */
305 	uint8_t			irq;		/* h/w IRQ */
306 	ddi_iblock_cookie_t	hw_iblock_cookie; /* cookie for h/w intr */
307 	kmutex_t		hw_mutex;	/* h/w mutex */
308 	ddi_iblock_cookie_t	sw_iblock_cookie; /* cookie for s/w intr */
309 	kmutex_t		sw_mutex;	/* s/w mutex */
310 	ddi_softintr_t		cpqary3_softintr_id; /* s/w intr identifier */
311 	uint8_t			swintr_flag;
312 	timeout_id_t		tick_tmout_id;	/* timeout identifier */
313 	uint8_t			cpqary3_tick_hdlr;
314 	scsi_hba_tran_t		*hba_tran;	/* transport structure */
315 	cpqary3_cmdmemlist_t	*cmdmemlistp;	/* database - Memory Pool */
316 	cpqary3_tgt_t		*cpqary3_tgtp[CPQARY3_MAX_TGT];
317 	cpqary3_drvr_replyq_t	*drvr_replyq;
318 
319 
320 	uint8_t			(*check_ctlr_intr)(CTLR *);
321 
322 	/*
323 	 * PCI Configuration Registers
324 	 * 0x10	Primary I2O Memory BAR 	- for Host Interface
325 	 * 0x14	Primary DRAM 1 BAR	- for Transport Configuration Table
326 	 *
327 	 * Host Interface Registers
328 	 * Offset from Primary I2O Memory BAR
329 	 * 0x20 Inbound Doorbell	- for interrupting controller
330 	 * 0x30	Outbound List Status 	- for signalling status of Reply Q
331 	 * 0x34	Outbound Interrupt Mask	- for masking Interrupts to host
332 	 * 0x40	Host Inbound Queue	- Request Q
333 	 * 0x44	Host Outbound Queue	- reply Q
334 	 *
335 	 * Offset from Primary DRAM 1 BAR
336 	 * 0x00	Configuration Table 	- for Controller Transport Layer
337 	 */
338 
339 	uint32_t		*idr;
340 	ddi_acc_handle_t	idr_handle;
341 
342 	/* LOCKUP CODE */
343 	uint32_t		*spr0;
344 	ddi_acc_handle_t    	spr0_handle;
345 	/* LOCKUP CODE */
346 
347 	uint32_t		*odr;
348 	ddi_acc_handle_t	odr_handle;
349 
350 	uint32_t		*odr_cl;
351 	ddi_acc_handle_t	odr_cl_handle;
352 
353 	uint32_t		*isr;
354 	ddi_acc_handle_t	isr_handle;
355 
356 	uint32_t		*imr;
357 	ddi_acc_handle_t	imr_handle;
358 
359 	uint32_t		*ipq;
360 	ddi_acc_handle_t	ipq_handle;
361 
362 	uint32_t		*opq;
363 	ddi_acc_handle_t	opq_handle;
364 
365 	CfgTable_t		*ct;
366 	ddi_acc_handle_t	ct_handle;
367 
368 	CfgTrans_Perf_t		*cp;
369 	ddi_acc_handle_t	cp_handle;
370 
371 	uint32_t		legacy_mapping;
372 	uint32_t		noe_support;
373 	/* SG */
374 	uint32_t		sg_cnt;
375 	/* SG */
376 	uint32_t		ctlr_maxcmds;
377 	uint32_t		host_support;
378 	uint8_t			controller_lockup;
379 	uint8_t			lockup_logged;
380 	uint32_t		poll_flag;
381 } cpqary3_t;
382 
383 
384 /*
385  * Private Structure for Self Issued Commands
386  */
387 
388 typedef struct cpqary3_driver_private {
389 	void				*sg;
390 	cpqary3_phyctg_t	*phyctgp;
391 }cpqary3_private_t;
392 
393 /* cmd_flags */
394 #define	CFLAG_DMASEND	0x01
395 #define	CFLAG_CMDIOPB	0x02
396 #define	CFLAG_DMAVALID	0x04
397 
398 /*
399  * Driver Private Packet
400  */
401 typedef struct cpqary3_pkt {
402 	struct scsi_pkt		*scsi_cmd_pkt;
403 	ddi_dma_win_t		prev_winp;
404 	ddi_dma_seg_t		prev_segp;
405 	clock_t			cmd_start_time;
406 	/* SG */
407 	ddi_dma_cookie_t	cmd_dmacookies[MAX_PERF_SG_CNT];
408 	/* SG */
409 	uint32_t		cmd_ncookies;
410 	uint32_t		cmd_cookie;
411 	uint32_t		cmd_cookiecnt;
412 	uint32_t		cmd_nwin;
413 	uint32_t		cmd_curwin;
414 	off_t			cmd_dma_offset;
415 	size_t			cmd_dma_len;
416 	size_t			cmd_dmacount;
417 	struct buf		*bf;
418 	ddi_dma_handle_t   	cmd_dmahandle;
419 	uint32_t		bytes;
420 	uint32_t		cmd_flags;
421 	uint32_t		cdb_len;
422 	uint32_t		scb_len;
423 	cpqary3_cmdpvt_t	*memp;
424 } cpqary3_pkt_t;
425 
426 #pragma pack(1)
427 
428 typedef struct cpqary3_ioctlresp {
429 	/* Driver Revision */
430 	struct cpqary3_revision {
431 		uint8_t		minor; /* Version */
432 		uint8_t		major;
433 		uint8_t		mm;    /* Revision Date */
434 		uint8_t		dd;
435 		uint16_t	yyyy;
436 	} cpqary3_drvrev;
437 
438 	/* HBA Info */
439 	struct cpqary3_ctlr {
440 		uint8_t		num_of_tgts; /* No of Logical Drive */
441 		uint8_t		*name;
442 	} cpqary3_ctlr;
443 } cpqary3_ioctlresp_t;
444 
445 typedef struct cpqary3_ioctlreq {
446 	cpqary3_ioctlresp_t	*cpqary3_ioctlrespp;
447 } cpqary3_ioctlreq_t;
448 
449 #pragma pack()
450 
451 /* Driver function definitions */
452 
453 void cpqary3_init_hbatran(cpqary3_t *);
454 void cpqary3_read_conf_file(dev_info_t *, cpqary3_t *);
455 void cpqary3_tick_hdlr(void *);
456 void cpqary3_flush_cache(cpqary3_t *);
457 void cpqary3_intr_onoff(cpqary3_t *, uint8_t);
458 void cpqary3_lockup_intr_onoff(cpqary3_t *, uint8_t);
459 uint8_t cpqary3_disable_NOE_command(cpqary3_t *);
460 uint8_t cpqary3_send_NOE_command(cpqary3_t *, cpqary3_cmdpvt_t *, uint8_t);
461 uint16_t cpqary3_init_ctlr_resource(cpqary3_t *);
462 uint32_t cpqary3_hw_isr(caddr_t);
463 uint32_t cpqary3_sw_isr(caddr_t);
464 int32_t cpqary3_ioctl_driver_info(uintptr_t, int);
465 int32_t cpqary3_ioctl_ctlr_info(uintptr_t, cpqary3_t *, int);
466 int32_t cpqary3_ioctl_bmic_pass(uintptr_t, cpqary3_t *, int);
467 int32_t cpqary3_ioctl_scsi_pass(uintptr_t, cpqary3_t *, int);
468 uint8_t cpqary3_probe4targets(cpqary3_t *);
469 void cpqary3_cmdlist_release(cpqary3_cmdpvt_t *, uint8_t);
470 int32_t cpqary3_submit(cpqary3_t *, uint32_t);
471 void cpqary3_free_phyctgs_mem(cpqary3_phyctg_t *, uint8_t);
472 caddr_t cpqary3_alloc_phyctgs_mem(cpqary3_t *, size_t, uint32_t *,
473     cpqary3_phyctg_t *);
474 cpqary3_cmdpvt_t *cpqary3_cmdlist_occupy(cpqary3_t *);
475 void cpqary3_synccmd_complete(cpqary3_cmdpvt_t *);
476 void cpqary3_NOE_handler(cpqary3_cmdpvt_t *);
477 uint8_t cpqary3_retrieve(cpqary3_t *);
478 void cpqary3_synccmd_cleanup(cpqary3_cmdpvt_t *);
479 int cpqary3_target_geometry(struct scsi_address *);
480 uint8_t cpqary3_send_abortcmd(cpqary3_t *, uint16_t, CommandList_t *);
481 void cpqary3_memfini(cpqary3_t *, uint8_t);
482 uint8_t cpqary3_init_ctlr(cpqary3_t *);
483 int16_t cpqary3_meminit(cpqary3_t *);
484 void cpqary3_noe_complete(cpqary3_cmdpvt_t *cpqary3_cmdpvtp);
485 cpqary3_cmdpvt_t *cpqary3_synccmd_alloc(cpqary3_t *, size_t);
486 void cpqary3_synccmd_free(cpqary3_t *, cpqary3_cmdpvt_t *);
487 int cpqary3_synccmd_send(cpqary3_t *, cpqary3_cmdpvt_t *, clock_t, int);
488 uint8_t cpqary3_poll_retrieve(cpqary3_t *cpqary3p, uint32_t poll_tag);
489 uint8_t cpqary3_build_cmdlist(cpqary3_cmdpvt_t *cpqary3_cmdpvtp, uint32_t tid);
490 
491 #ifdef	__cplusplus
492 }
493 #endif
494 
495 #endif	/* _CPQARY3_H */
496