mptsas_var.h revision 9907:98086c85a8f7
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 * Copyright (c) 2000 to 2009, LSI Corporation.
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms of all code within
32 * this file that is exclusively owned by LSI, with or without
33 * modification, is permitted provided that, in addition to the CDDL 1.0
34 * License requirements, the following conditions are met:
35 *
36 *    Neither the name of the author nor the names of its contributors may be
37 *    used to endorse or promote products derived from this software without
38 *    specific prior written permission.
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
43 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
44 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
46 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
47 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
48 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
51 * DAMAGE.
52 */
53
54#ifndef _SYS_SCSI_ADAPTERS_MPTVAR_H
55#define	_SYS_SCSI_ADAPTERS_MPTVAR_H
56
57#include <sys/byteorder.h>
58#include <sys/isa_defs.h>
59#include <sys/sunmdi.h>
60#include <sys/mdi_impldefs.h>
61#include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
62
63#ifdef	__cplusplus
64extern "C" {
65#endif
66
67/*
68 * Compile options
69 */
70#ifdef DEBUG
71#define	MPTSAS_DEBUG		/* turn on debugging code */
72#endif	/* DEBUG */
73
74#define	MPTSAS_INITIAL_SOFT_SPACE	4
75
76#define	MAX_MPI_PORTS		16
77
78#define	MPTSAS_MAX_PHYS		8
79
80#define	MPTSAS_INVALID_DEVHDL	0xffff
81
82/*
83 * MPT HW defines
84 */
85#define	MPTSAS_MAX_DISKS_IN_CONFIG	14
86#define	MPTSAS_MAX_DISKS_IN_VOL		10
87#define	MPTSAS_MAX_HOTSPARES		2
88#define	MPTSAS_MAX_RAIDVOLS		2
89#define	MPTSAS_MAX_RAIDCONFIGS		5
90
91/*
92 * 64-bit SAS WWN is displayed as 16 characters as HEX characters,
93 * plus one means the end of the string '\0'.
94 */
95#define	MPTSAS_WWN_STRLEN 16 + 1
96#define	MPTSAS_MAX_GUID_LEN	64
97
98/*
99 * DMA routine flags
100 */
101#define	MPTSAS_DMA_HANDLE_ALLOCD	0x2
102#define	MPTSAS_DMA_MEMORY_ALLOCD	0x4
103#define	MPTSAS_DMA_HANDLE_BOUND	0x8
104
105/*
106 * If the HBA supports DMA or bus-mastering, you may have your own
107 * scatter-gather list for physically non-contiguous memory in one
108 * I/O operation; if so, there's probably a size for that list.
109 * It must be placed in the ddi_dma_lim_t structure, so that the system
110 * DMA-support routines can use it to break up the I/O request, so we
111 * define it here.
112 */
113#if defined(__sparc)
114#define	MPTSAS_MAX_DMA_SEGS	1
115#define	MPTSAS_MAX_CMD_SEGS	1
116#else
117#define	MPTSAS_MAX_DMA_SEGS	256
118#define	MPTSAS_MAX_CMD_SEGS	257
119#endif
120#define	MPTSAS_MAX_FRAME_SGES(mpt) \
121	(((mpt->m_req_frame_size - (sizeof (MPI2_SCSI_IO_REQUEST))) / 8) + 1)
122
123/*
124 * Caculating how many 64-bit DMA simple elements can be stored in the first
125 * frame. Note that msg_scsi_io_request contains 2 double-words (8 bytes) for
126 * element storage.  And 64-bit dma element is 3 double-words (12 bytes) in
127 * size.
128 */
129#define	MPTSAS_MAX_FRAME_SGES64(mpt) \
130	((mpt->m_req_frame_size - \
131	(sizeof (MPI2_SCSI_IO_REQUEST)) + sizeof (MPI2_SGE_IO_UNION)) / 12)
132
133/*
134 * Scatter-gather list structure defined by HBA hardware
135 */
136typedef	struct NcrTableIndirect {	/* Table Indirect entries */
137	uint32_t count;		/* 24 bit count */
138	union {
139		uint32_t address32;	/* 32 bit address */
140		struct {
141			uint32_t Low;
142			uint32_t High;
143		} address64;		/* 64 bit address */
144	} addr;
145} mptti_t;
146
147/*
148 * preferred pkt_private length in 64-bit quantities
149 */
150#ifdef	_LP64
151#define	PKT_PRIV_SIZE	2
152#define	PKT_PRIV_LEN	16	/* in bytes */
153#else /* _ILP32 */
154#define	PKT_PRIV_SIZE	1
155#define	PKT_PRIV_LEN	8	/* in bytes */
156#endif
157
158#define	PKT2CMD(pkt)	((struct mptsas_cmd *)((pkt)->pkt_ha_private))
159#define	CMD2PKT(cmdp)	((struct scsi_pkt *)((cmdp)->cmd_pkt))
160#define	EXTCMDS_STATUS_SIZE (sizeof (struct scsi_arq_status))
161
162/*
163 * get offset of item in structure
164 */
165#define	MPTSAS_GET_ITEM_OFF(type, member) ((size_t)(&((type *)0)->member))
166
167/*
168 * WWID provided by LSI firmware is generated by firmware but the WWID is not
169 * IEEE NAA standard format, OBP has no chance to distinguish format of unit
170 * address. According LSI's confirmation, the top nibble of RAID WWID is
171 * meanless, so the consensus between Solaris and OBP is to replace top nibble
172 * of WWID provided by LSI to "3" always to hint OBP that this is a RAID WWID
173 * format unit address.
174 */
175#define	MPTSAS_RAID_WWID(wwid) \
176	((wwid & 0x0FFFFFFFFFFFFFFF) | 0x3000000000000000)
177
178typedef	struct mptsas_target {
179		uint64_t		m_sas_wwn;	/* hash key1 */
180		uint8_t			m_phymask;	/* hash key2 */
181		/*
182		 * m_dr_flag is a flag for DR, make sure the member
183		 * take the place of dr_flag of mptsas_hash_data.
184		 */
185		uint8_t			m_dr_flag;	/* dr_flag */
186		uint16_t		m_devhdl;
187		uint32_t		m_deviceinfo;
188		uint8_t			m_phynum;
189		uint32_t		m_dups;
190		int32_t			m_timeout;
191		int32_t			m_timebase;
192		int32_t			m_t_throttle;
193		int32_t			m_t_ncmds;
194		int32_t			m_reset_delay;
195		int32_t			m_t_nwait;
196
197		uint16_t		m_qfull_retry_interval;
198		uint8_t			m_qfull_retries;
199
200} mptsas_target_t;
201
202typedef struct mptsas_smp {
203	uint64_t	m_sasaddr;	/* hash key1 */
204	uint8_t		m_phymask;	/* hash key2 */
205	uint8_t		reserved1;
206	uint16_t	m_devhdl;
207	uint32_t	m_deviceinfo;
208} mptsas_smp_t;
209
210typedef struct mptsas_hash_data {
211	uint64_t	key1;
212	uint8_t		key2;
213	uint8_t		dr_flag;
214	uint16_t	devhdl;
215	uint32_t	device_info;
216} mptsas_hash_data_t;
217
218typedef struct mptsas_cache_frames {
219	ddi_dma_handle_t m_dma_hdl;
220	ddi_acc_handle_t m_acc_hdl;
221	caddr_t m_frames_addr;
222	uint32_t m_phys_addr;
223} mptsas_cache_frames_t;
224
225typedef struct	mptsas_cmd {
226	uint_t			cmd_flags;	/* flags from scsi_init_pkt */
227	ddi_dma_handle_t	cmd_dmahandle;	/* dma handle */
228	ddi_dma_cookie_t	cmd_cookie;
229	uint_t			cmd_cookiec;
230	uint_t			cmd_winindex;
231	uint_t			cmd_nwin;
232	uint_t			cmd_cur_cookie;
233	off_t			cmd_dma_offset;
234	size_t			cmd_dma_len;
235	uint32_t		cmd_totaldmacount;
236
237	ddi_dma_handle_t	cmd_arqhandle;	/* dma arq handle */
238	ddi_dma_cookie_t	cmd_arqcookie;
239	struct buf		*cmd_arq_buf;
240	ddi_dma_handle_t	cmd_ext_arqhandle; /* dma extern arq handle */
241	ddi_dma_cookie_t	cmd_ext_arqcookie;
242	struct buf		*cmd_ext_arq_buf;
243
244	int			cmd_pkt_flags;
245
246	/* timer for command in active slot */
247	int			cmd_active_timeout;
248
249	struct scsi_pkt		*cmd_pkt;
250	struct scsi_arq_status	cmd_scb;
251	uchar_t			cmd_cdblen;	/* length of cdb */
252	uchar_t			cmd_rqslen;	/* len of requested rqsense */
253	uchar_t			cmd_privlen;
254	uint_t			cmd_scblen;
255	uint32_t		cmd_dmacount;
256	uint64_t		cmd_dma_addr;
257	uchar_t			cmd_age;
258	ushort_t		cmd_qfull_retries;
259	uchar_t			cmd_queued;	/* true if queued */
260	struct mptsas_cmd	*cmd_linkp;
261	mptti_t			*cmd_sg; /* Scatter/Gather structure */
262	uchar_t			cmd_cdb[SCSI_CDB_SIZE];
263	uint64_t		cmd_pkt_private[PKT_PRIV_LEN];
264	uint32_t		cmd_slot;
265	uint32_t		ioc_cmd_slot;
266
267	mptsas_cache_frames_t	*cmd_extra_frames;
268
269	uint32_t		cmd_rfm;
270	mptsas_target_t		*cmd_tgt_addr;
271} mptsas_cmd_t;
272
273/*
274 * These are the defined cmd_flags for this structure.
275 */
276#define	CFLAG_CMDDISC		0x000001 /* cmd currently disconnected */
277#define	CFLAG_WATCH		0x000002 /* watchdog time for this command */
278#define	CFLAG_FINISHED		0x000004 /* command completed */
279#define	CFLAG_CHKSEG		0x000008 /* check cmd_data within seg */
280#define	CFLAG_COMPLETED		0x000010 /* completion routine called */
281#define	CFLAG_PREPARED		0x000020 /* pkt has been init'ed */
282#define	CFLAG_IN_TRANSPORT	0x000040 /* in use by host adapter driver */
283#define	CFLAG_RESTORE_PTRS	0x000080 /* implicit restore ptr on reconnect */
284#define	CFLAG_ARQ_IN_PROGRESS	0x000100 /* auto request sense in progress */
285#define	CFLAG_TRANFLAG		0x0001ff /* covers transport part of flags */
286#define	CFLAG_TM_CMD		0x000200 /* cmd is a task management command */
287#define	CFLAG_CMDARQ		0x000400 /* cmd is a 'rqsense' command */
288#define	CFLAG_DMAVALID		0x000800 /* dma mapping valid */
289#define	CFLAG_DMASEND		0x001000 /* data is going 'out' */
290#define	CFLAG_CMDIOPB		0x002000 /* this is an 'iopb' packet */
291#define	CFLAG_CDBEXTERN		0x004000 /* cdb kmem_alloc'd */
292#define	CFLAG_SCBEXTERN		0x008000 /* scb kmem_alloc'd */
293#define	CFLAG_FREE		0x010000 /* packet is on free list */
294#define	CFLAG_PRIVEXTERN	0x020000 /* target private kmem_alloc'd */
295#define	CFLAG_DMA_PARTIAL	0x040000 /* partial xfer OK */
296#define	CFLAG_QFULL_STATUS	0x080000 /* pkt got qfull status */
297#define	CFLAG_TIMEOUT		0x100000 /* passthru/config command timeout */
298#define	CFLAG_PMM_RECEIVED	0x200000 /* use cmd_pmm* for saving pointers */
299#define	CFLAG_RETRY		0x400000 /* cmd has been retried */
300#define	CFLAG_CMDIOC		0x800000 /* cmd is just for for ioc, no io */
301#define	CFLAG_EXTARQBUFVALID	0x1000000 /* extern arq buf handle is valid */
302#define	CFLAG_PASSTHRU		0x2000000 /* cmd is a passthrough command */
303#define	CFLAG_XARQ		0x4000000 /* cmd requests for extra sense */
304#define	CFLAG_CMDACK		0x8000000 /* cmd for event ack */
305#define	CFLAG_TXQ		0x10000000 /* cmd queued in the tx_waitq */
306#define	CFLAG_FW_CMD		0x20000000 /* cmd is a fw up/down command */
307#define	CFLAG_CONFIG		0x40000000 /* cmd is for config header/page */
308
309#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE			8
310#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK			0xC0
311#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL			0x00
312#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE			0x40
313#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT		0x80
314#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_EXTENDED_UNIT		0xC0
315#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_2B		0x00
316#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_4B		0x01
317#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_6B		0x10
318#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_8B		0x20
319#define	MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_SIZE		0x30
320
321#define	MPTSAS_HASH_ARRAY_SIZE	16
322/*
323 * hash table definition
324 */
325
326#define	MPTSAS_HASH_FIRST	0xffff
327#define	MPTSAS_HASH_NEXT	0x0000
328
329/*
330 * passthrough request structure
331 */
332typedef struct mptsas_pt_request {
333	uint8_t *request;
334	uint32_t request_size;
335	uint32_t data_size;
336	uint32_t dataout_size;
337	uint32_t direction;
338	ddi_dma_cookie_t data_cookie;
339	ddi_dma_cookie_t dataout_cookie;
340} mptsas_pt_request_t;
341
342/*
343 * config page request structure
344 */
345typedef struct mptsas_config_request {
346	uint32_t	page_address;
347	uint8_t		action;
348	uint8_t		page_type;
349	uint8_t		page_number;
350	uint8_t		page_length;
351	uint8_t		page_version;
352	uint8_t		ext_page_type;
353	uint16_t	ext_page_length;
354} mptsas_config_request_t;
355
356typedef struct mptsas_hash_node {
357	void *data;
358	struct mptsas_hash_node *next;
359} mptsas_hash_node_t;
360
361typedef struct mptsas_hash_table {
362	struct mptsas_hash_node *head[MPTSAS_HASH_ARRAY_SIZE];
363	/*
364	 * last position in traverse
365	 */
366	struct mptsas_hash_node *cur;
367	uint16_t line;
368
369} mptsas_hash_table_t;
370
371/*
372 * RAID volume information
373 */
374typedef struct mptsas_raidvol {
375	ushort_t	m_israid;
376	uint16_t	m_raidhandle;
377	uint64_t	m_raidwwid;
378	uint8_t		m_state;
379	uint32_t	m_statusflags;
380	uint32_t	m_settings;
381	uint16_t	m_devhdl[MPTSAS_MAX_DISKS_IN_VOL];
382	uint8_t		m_disknum[MPTSAS_MAX_DISKS_IN_VOL];
383	ushort_t	m_diskstatus[MPTSAS_MAX_DISKS_IN_VOL];
384	uint64_t	m_raidsize;
385	int		m_raidlevel;
386	int		m_ndisks;
387	mptsas_target_t	*m_raidtgt;
388} mptsas_raidvol_t;
389
390/*
391 * RAID configurations
392 */
393typedef struct mptsas_raidconfig {
394		mptsas_raidvol_t	m_raidvol[MPTSAS_MAX_RAIDVOLS];
395		uint16_t		m_physdisk_devhdl[
396					    MPTSAS_MAX_DISKS_IN_CONFIG];
397		uint8_t			m_native;
398} m_raidconfig_t;
399
400/*
401 * Structure to hold active outstanding cmds.  Also, keep
402 * timeout on a per target basis.
403 */
404typedef struct mptsas_slots {
405	mptsas_hash_table_t	m_tgttbl;
406	mptsas_hash_table_t	m_smptbl;
407	m_raidconfig_t		m_raidconfig[MPTSAS_MAX_RAIDCONFIGS];
408	uint8_t			m_num_raid_configs;
409	uint16_t		m_tags;
410	uint32_t		m_buffer;
411	size_t			m_size;
412	uint16_t		m_n_slots;
413	mptsas_cmd_t		*m_slot[1];
414} mptsas_slots_t;
415
416/*
417 * Structure to hold command and packets for event ack
418 * and task management commands.
419 */
420typedef struct  m_event_struct {
421	struct mptsas_cmd		m_event_cmd;
422	struct m_event_struct	*m_event_linkp;
423	/*
424	 * event member record the failure event and eventcntx
425	 * event member would be used in send ack pending process
426	 */
427	uint32_t		m_event;
428	uint32_t		m_eventcntx;
429	uint_t			in_use;
430	struct scsi_pkt		m_event_pkt;	/* must be last */
431						/* ... scsi_pkt_size() */
432} m_event_struct_t;
433#define	M_EVENT_STRUCT_SIZE	(sizeof (m_event_struct_t) - \
434				sizeof (struct scsi_pkt) + scsi_pkt_size())
435
436#define	MAX_IOC_COMMANDS	8
437
438/*
439 * A pool of MAX_IOC_COMMANDS is maintained for event ack commands.
440 * A new event ack command requests mptsas_cmd and scsi_pkt structures
441 * from this pool, and returns it back when done.
442 */
443
444typedef struct m_replyh_arg {
445	void *mpt;
446	uint32_t rfm;
447} m_replyh_arg_t;
448_NOTE(DATA_READABLE_WITHOUT_LOCK(m_replyh_arg_t::mpt))
449_NOTE(DATA_READABLE_WITHOUT_LOCK(m_replyh_arg_t::rfm))
450
451/*
452 * Flags for DR handler topology change
453 */
454#define	MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE		0x0
455#define	MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED		0x1
456#define	MPTSAS_TOPO_FLAG_LUN_ASSOCIATED			0x2
457#define	MPTSAS_TOPO_FLAG_RAID_ASSOCIATED		0x4
458#define	MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED	0x8
459#define	MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE	0x10
460
461typedef struct mptsas_topo_change_list {
462	void *mpt;
463	uint_t  event;
464	union {
465		uint8_t physport;
466		uint8_t phymask;
467	} un;
468	uint16_t devhdl;
469	void *object;
470	uint8_t flags;
471	struct mptsas_topo_change_list *next;
472} mptsas_topo_change_list_t;
473
474
475_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::mpt))
476_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::event))
477_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::physport))
478_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::devhdl))
479_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::object))
480_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::flags))
481
482/*
483 * Status types when calling mptsas_get_target_device_info
484 */
485#define	DEV_INFO_SUCCESS		0x0
486#define	DEV_INFO_FAIL_PAGE0		0x1
487#define	DEV_INFO_WRONG_DEVICE_TYPE	0x2
488#define	DEV_INFO_PHYS_DISK		0x3
489#define	DEV_INFO_FAIL_ALLOC		0x4
490
491/*
492 * mpt hotplug event defines
493 */
494#define	MPTSAS_DR_EVENT_RECONFIG_TARGET	0x01
495#define	MPTSAS_DR_EVENT_OFFLINE_TARGET	0x02
496#define	MPTSAS_TOPO_FLAG_REMOVE_HANDLE	0x04
497
498/*
499 * SMP target hotplug events
500 */
501#define	MPTSAS_DR_EVENT_RECONFIG_SMP	0x10
502#define	MPTSAS_DR_EVENT_OFFLINE_SMP	0x20
503#define	MPTSAS_DR_EVENT_MASK		0x3F
504
505/*
506 * mpt hotplug status definition for m_dr_flag
507 */
508
509/*
510 * MPTSAS_DR_INACTIVE
511 *
512 * The target is in a normal operating state.
513 * No dynamic reconfiguration operation is in progress.
514 */
515#define	MPTSAS_DR_INACTIVE				0x0
516/*
517 * MPTSAS_DR_INTRANSITION
518 *
519 * The target is in a transition mode since
520 * hotplug event happens and offline procedure has not
521 * been finished
522 */
523#define	MPTSAS_DR_INTRANSITION			0x1
524
525typedef struct mptsas_tgt_private {
526	int t_lun;
527	struct mptsas_target *t_private;
528} mptsas_tgt_private_t;
529
530/*
531 * The following defines are used in mptsas_set_init_mode to track the current
532 * state as we progress through reprogramming the HBA from target mode into
533 * initiator mode.
534 */
535
536#define	IOUC_READ_PAGE0		0x00000100
537#define	IOUC_READ_PAGE1		0x00000200
538#define	IOUC_WRITE_PAGE1	0x00000400
539#define	IOUC_DONE		0x00000800
540#define	DISCOVERY_IN_PROGRESS	MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS
541#define	AUTO_PORT_CONFIGURATION	MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG
542
543/*
544 * Last allocated slot is used for TM requests.  Since only m_max_requests
545 * frames are allocated, the last SMID will be m_max_requests - 1.
546 */
547#define	MPTSAS_SLOTS_SIZE(mpt) \
548	(sizeof (struct mptsas_slots) + (sizeof (struct mptsas_cmd *) * \
549		mpt->m_max_requests))
550#define	MPTSAS_TM_SLOT(mpt)	(mpt->m_max_requests - 1)
551
552/*
553 * Macro for phy_flags
554 */
555typedef struct mptsas_phy_info {
556	uint8_t			port_num;
557	uint8_t			port_flags;
558	uint16_t		ctrl_devhdl;
559	uint32_t		phy_device_type;
560	uint16_t		attached_devhdl;
561	uint8_t			phy_mask;
562} mptsas_phy_info_t;
563
564typedef struct mptsas_doneq_thread_arg {
565	void		*mpt;
566	uint64_t	t;
567} mptsas_doneq_thread_arg_t;
568
569#define	MPTSAS_DONEQ_THREAD_ACTIVE	0x1
570typedef struct mptsas_doneq_thread_list {
571	mptsas_cmd_t		*doneq;
572	mptsas_cmd_t		**donetail;
573	kthread_t		*threadp;
574	kcondvar_t		cv;
575	ushort_t		reserv1;
576	uint32_t		reserv2;
577	kmutex_t		mutex;
578	uint32_t		flag;
579	uint32_t		len;
580	mptsas_doneq_thread_arg_t	arg;
581} mptsas_doneq_thread_list_t;
582
583typedef struct mptsas {
584	int		m_instance;
585
586	struct mptsas *m_next;
587
588	scsi_hba_tran_t		*m_tran;
589	sas_hba_tran_t		*m_smptran;
590	kmutex_t		m_mutex;
591	kcondvar_t		m_cv;
592	kcondvar_t		m_passthru_cv;
593	kcondvar_t		m_fw_cv;
594	kcondvar_t		m_config_cv;
595	dev_info_t		*m_dip;
596
597	/*
598	 * soft state flags
599	 */
600	uint_t		m_softstate;
601
602	struct mptsas_slots *m_active;	/* outstanding cmds */
603
604	mptsas_cmd_t	*m_waitq;	/* cmd queue for active request */
605	mptsas_cmd_t	**m_waitqtail;	/* wait queue tail ptr */
606
607	kmutex_t	m_tx_waitq_mutex;
608	mptsas_cmd_t	*m_tx_waitq;	/* TX cmd queue for active request */
609	mptsas_cmd_t	**m_tx_waitqtail;	/* tx_wait queue tail ptr */
610	int		m_tx_draining;	/* TX queue draining flag */
611
612	mptsas_cmd_t	*m_doneq;	/* queue of completed commands */
613	mptsas_cmd_t	**m_donetail;	/* queue tail ptr */
614
615	/*
616	 * variables for helper threads (fan-out interrupts)
617	 */
618	mptsas_doneq_thread_list_t	*m_doneq_thread_id;
619	uint32_t		m_doneq_thread_n;
620	uint32_t		m_doneq_thread_threshold;
621	uint32_t		m_doneq_length_threshold;
622	uint32_t		m_doneq_len;
623	kcondvar_t		m_doneq_thread_cv;
624	kmutex_t		m_doneq_mutex;
625
626	int		m_ncmds;	/* number of outstanding commands */
627	m_event_struct_t *m_ioc_event_cmdq;	/* cmd queue for ioc event */
628	m_event_struct_t **m_ioc_event_cmdtail;	/* ioc cmd queue tail */
629
630	ddi_acc_handle_t m_datap;	/* operating regs data access handle */
631
632	struct _MPI2_SYSTEM_INTERFACE_REGS	*m_reg;
633
634	ushort_t	m_devid;	/* device id of chip. */
635	uchar_t		m_revid;	/* revision of chip. */
636	uint16_t	m_svid;		/* subsystem Vendor ID of chip */
637	uint16_t	m_ssid;		/* subsystem Device ID of chip */
638
639	uchar_t		m_sync_offset;	/* default offset for this chip. */
640
641	timeout_id_t	m_quiesce_timeid;
642	timeout_id_t	m_pm_timeid;
643
644	ddi_dma_handle_t m_dma_req_frame_hdl;
645	ddi_acc_handle_t m_acc_req_frame_hdl;
646	ddi_dma_handle_t m_dma_reply_frame_hdl;
647	ddi_acc_handle_t m_acc_reply_frame_hdl;
648	ddi_dma_handle_t m_dma_free_queue_hdl;
649	ddi_acc_handle_t m_acc_free_queue_hdl;
650	ddi_dma_handle_t m_dma_post_queue_hdl;
651	ddi_acc_handle_t m_acc_post_queue_hdl;
652
653	/*
654	 * list of reset notification requests
655	 */
656	struct scsi_reset_notify_entry	*m_reset_notify_listf;
657
658	/*
659	 * qfull handling
660	 */
661	timeout_id_t	m_restart_cmd_timeid;
662
663	/*
664	 * scsi	reset delay per	bus
665	 */
666	uint_t		m_scsi_reset_delay;
667
668	int		m_pm_idle_delay;
669
670	uchar_t		m_polled_intr;	/* intr was polled. */
671	uchar_t		m_suspended;	/* true	if driver is suspended */
672
673	struct kmem_cache *m_kmem_cache;
674	struct kmem_cache *m_cache_frames;
675
676	/*
677	 * hba options.
678	 */
679	uint_t		m_options;
680
681	int		m_in_callback;
682
683	int		m_power_level;	/* current power level */
684
685	int		m_busy;		/* power management busy state */
686
687	off_t		m_pmcsr_offset; /* PMCSR offset */
688
689	ddi_acc_handle_t m_config_handle;
690
691	ddi_dma_attr_t		m_io_dma_attr;	/* Used for data I/O */
692	ddi_dma_attr_t		m_msg_dma_attr; /* Used for message frames */
693	ddi_device_acc_attr_t	m_dev_acc_attr;
694
695	/*
696	 * request/reply variables
697	 */
698	caddr_t		m_req_frame;
699	uint64_t	m_req_frame_dma_addr;
700	caddr_t		m_reply_frame;
701	uint64_t	m_reply_frame_dma_addr;
702	caddr_t		m_free_queue;
703	uint64_t	m_free_queue_dma_addr;
704	caddr_t		m_post_queue;
705	uint64_t	m_post_queue_dma_addr;
706
707	m_replyh_arg_t *m_replyh_args;
708
709	uint16_t	m_max_requests;
710	uint16_t	m_req_frame_size;
711
712	/*
713	 * Max frames per request reprted in IOC Facts
714	 */
715	uint8_t		m_max_chain_depth;
716	/*
717	 * Max frames per request which is used in reality. It's adjusted
718	 * according DMA SG length attribute, and shall not exceed the
719	 * m_max_chain_depth.
720	 */
721	uint8_t		m_max_request_frames;
722
723	uint16_t	m_free_queue_depth;
724	uint16_t	m_post_queue_depth;
725	uint16_t	m_max_replies;
726	uint32_t	m_free_index;
727	uint32_t	m_post_index;
728	uint8_t		m_reply_frame_size;
729
730	/*
731	 * indicates if the firmware was upload by the driver
732	 * at boot time
733	 */
734	ushort_t	m_fwupload;
735
736	uint16_t	m_productid;
737
738	/*
739	 * per instance data structures for dma memory resources for
740	 * MPI handshake protocol. only one handshake cmd can run at a time.
741	 */
742	ddi_dma_handle_t	m_hshk_dma_hdl;
743
744	ddi_acc_handle_t	m_hshk_acc_hdl;
745
746	caddr_t			m_hshk_memp;
747
748	size_t			m_hshk_dma_size;
749
750	/* Firmware version on the card at boot time */
751	uint32_t		m_fwversion;
752
753	/* MSI specific fields */
754	ddi_intr_handle_t	*m_htable;	/* For array of interrupts */
755	int			m_intr_type;	/* What type of interrupt */
756	int			m_intr_cnt;	/* # of intrs count returned */
757	size_t			m_intr_size;    /* Size of intr array */
758	uint_t			m_intr_pri;	/* Interrupt priority   */
759	int			m_intr_cap;	/* Interrupt capabilities */
760	ddi_taskq_t		*m_event_taskq;
761
762	/* SAS specific information */
763
764	union {
765		uint64_t	m_base_wwid;	/* Base WWID */
766		struct {
767#ifdef _BIG_ENDIAN
768			uint32_t	m_base_wwid_hi;
769			uint32_t	m_base_wwid_lo;
770#else
771			uint32_t	m_base_wwid_lo;
772			uint32_t	m_base_wwid_hi;
773#endif
774		} sasaddr;
775	} un;
776
777	uint8_t			m_num_phys;		/* # of PHYs */
778	mptsas_phy_info_t	m_phy_info[MPTSAS_MAX_PHYS];
779	uint8_t			m_port_chng;	/* initiator port changes */
780
781	/* FMA Capabilities */
782	int			m_fm_capabilities;
783	ddi_taskq_t		*m_dr_taskq;
784	int			m_mpxio_enable;
785	uint8_t			m_done_traverse_dev;
786	uint8_t			m_done_traverse_smp;
787	int			m_passthru_in_progress;
788	uint16_t		m_dev_handle;
789	uint16_t		m_smp_devhdl;
790
791	/*
792	 * Event recording
793	 */
794	uint32_t		m_event_number;
795	uint32_t		m_event_mask[4];
796	mptsas_event_entry_t	m_events[MPTSAS_EVENT_QUEUE_SIZE];
797
798	/*
799	 * per instance cmd data structures for task management cmds
800	 */
801	m_event_struct_t	m_event_task_mgmt;	/* must be last */
802							/* ... scsi_pkt_size */
803} mptsas_t;
804#define	MPTSAS_SIZE	(sizeof (struct mptsas) - \
805			sizeof (struct scsi_pkt) + scsi_pkt_size())
806/*
807 * Only one of below two conditions is satisfied, we
808 * think the target is associated to the iport and
809 * allow call into mptsas_probe_lun().
810 * 1. physicalsport == physport
811 * 2. (phymask & (1 << physport)) == 0
812 * The condition #2 is because LSI uses lowest PHY
813 * number as the value of physical port when auto port
814 * configuration.
815 */
816#define	IS_SAME_PORT(physicalport, physport, phymask, dynamicport) \
817	((physicalport == physport) || (dynamicport && (phymask & \
818	(1 << physport))))
819
820_NOTE(MUTEX_PROTECTS_DATA(mptsas::m_mutex, mptsas))
821_NOTE(SCHEME_PROTECTS_DATA("safe sharing", mptsas::m_next))
822_NOTE(SCHEME_PROTECTS_DATA("stable data", mptsas::m_dip mptsas::m_tran))
823_NOTE(SCHEME_PROTECTS_DATA("stable data", mptsas::m_kmem_cache))
824_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_io_dma_attr.dma_attr_sgllen))
825_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_devid))
826_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_productid))
827_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_port_type))
828_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_mpxio_enable))
829_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_ntargets))
830_NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_instance))
831
832typedef struct mptsas_dma_alloc_state
833{
834	ddi_dma_handle_t	handle;
835	caddr_t			memp;
836	size_t			size;
837	ddi_acc_handle_t	accessp;
838	ddi_dma_cookie_t	cookie;
839} mptsas_dma_alloc_state_t;
840
841/*
842 * These should eventually migrate into the mpt header files
843 * that may become the /kernel/misc/mpt module...
844 */
845#define	mptsas_init_std_hdr(hdl, mp, DevHandle, Lun, ChainOffset, Function) \
846	mptsas_put_msg_DevHandle(hdl, mp, DevHandle); \
847	mptsas_put_msg_ChainOffset(hdl, mp, ChainOffset); \
848	mptsas_put_msg_Function(hdl, mp, Function); \
849	mptsas_put_msg_Lun(hdl, mp, Lun)
850
851#define	mptsas_put_msg_DevHandle(hdl, mp, val) \
852	ddi_put16(hdl, &(mp)->DevHandle, (val))
853#define	mptsas_put_msg_ChainOffset(hdl, mp, val) \
854	ddi_put8(hdl, &(mp)->ChainOffset, (val))
855#define	mptsas_put_msg_Function(hdl, mp, val) \
856	ddi_put8(hdl, &(mp)->Function, (val))
857#define	mptsas_put_msg_Lun(hdl, mp, val) \
858	ddi_put8(hdl, &(mp)->LUN[1], (val))
859
860#define	mptsas_get_msg_Function(hdl, mp) \
861	ddi_get8(hdl, &(mp)->Function)
862
863#define	mptsas_get_msg_MsgFlags(hdl, mp) \
864	ddi_get8(hdl, &(mp)->MsgFlags)
865
866#define	MPTSAS_ENABLE_DRWE(hdl) \
867	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
868		MPI2_WRSEQ_FLUSH_KEY_VALUE); \
869	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
870		MPI2_WRSEQ_1ST_KEY_VALUE); \
871	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
872		MPI2_WRSEQ_2ND_KEY_VALUE); \
873	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
874		MPI2_WRSEQ_3RD_KEY_VALUE); \
875	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
876		MPI2_WRSEQ_4TH_KEY_VALUE); \
877	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
878		MPI2_WRSEQ_5TH_KEY_VALUE); \
879	ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
880		MPI2_WRSEQ_6TH_KEY_VALUE);
881
882/*
883 * m_options flags
884 */
885#define	MPTSAS_OPT_PM		0x01	/* Power Management */
886
887/*
888 * m_softstate flags
889 */
890#define	MPTSAS_SS_DRAINING		0x02
891#define	MPTSAS_SS_QUIESCED		0x04
892#define	MPTSAS_SS_MSG_UNIT_RESET	0x08
893
894/*
895 * regspec defines.
896 */
897#define	CONFIG_SPACE	0	/* regset[0] - configuration space */
898#define	IO_SPACE	1	/* regset[1] - used for i/o mapped device */
899#define	MEM_SPACE	2	/* regset[2] - used for memory mapped device */
900#define	BASE_REG2	3	/* regset[3] - used for 875 scripts ram */
901
902/*
903 * Handy constants
904 */
905#define	FALSE		0
906#define	TRUE		1
907#define	UNDEFINED	-1
908#define	FAILED		-2
909
910/*
911 * power management.
912 */
913#define	MPTSAS_POWER_ON(mpt) { \
914	pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, \
915	    PCI_PMCSR_D0); \
916	delay(drv_usectohz(10000)); \
917	(void) pci_restore_config_regs(mpt->m_dip); \
918	mptsas_setup_cmd_reg(mpt); \
919}
920
921#define	MPTSAS_POWER_OFF(mpt) { \
922	(void) pci_save_config_regs(mpt->m_dip); \
923	pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, \
924	    PCI_PMCSR_D3HOT); \
925	mpt->m_power_level = PM_LEVEL_D3; \
926}
927
928/*
929 * inq_dtype:
930 * Bits 5 through 7 are the Peripheral Device Qualifier
931 * 001b: device not connected to the LUN
932 * Bits 0 through 4 are the Peripheral Device Type
933 * 1fh: Unknown or no device type
934 *
935 * Although the inquiry may return success, the following value
936 * means no valid LUN connected.
937 */
938#define	MPTSAS_VALID_LUN(sd_inq) \
939	(((sd_inq->inq_dtype & 0xe0) != 0x20) && \
940	((sd_inq->inq_dtype & 0x1f) != 0x1f))
941
942/*
943 * Default is to have 10 retries on receiving QFULL status and
944 * each retry to be after 100 ms.
945 */
946#define	QFULL_RETRIES		10
947#define	QFULL_RETRY_INTERVAL	100
948
949/*
950 * Handy macros
951 */
952#define	Tgt(sp)	((sp)->cmd_pkt->pkt_address.a_target)
953#define	Lun(sp)	((sp)->cmd_pkt->pkt_address.a_lun)
954
955#define	IS_HEX_DIGIT(n)	(((n) >= '0' && (n) <= '9') || \
956	((n) >= 'a' && (n) <= 'f') || ((n) >= 'A' && (n) <= 'F'))
957
958/*
959 * poll time for mptsas_pollret() and mptsas_wait_intr()
960 */
961#define	MPTSAS_POLL_TIME	30000	/* 30 seconds */
962
963/*
964 * default time for mptsas_do_passthru
965 */
966#define	MPTSAS_PASS_THRU_TIME_DEFAULT	60	/* 60 seconds */
967
968/*
969 * macro for getting value in micro-seconds since last boot to be used as
970 * timeout in cv_timedwait call.
971 */
972#define	MPTSAS_CV_TIMEOUT(timeout)  (ddi_get_lbolt() + \
973    drv_usectohz(timeout * MICROSEC))
974
975/*
976 * macro to return the effective address of a given per-target field
977 */
978#define	EFF_ADDR(start, offset)		((start) + (offset))
979
980#define	SDEV2ADDR(devp)		(&((devp)->sd_address))
981#define	SDEV2TRAN(devp)		((devp)->sd_address.a_hba_tran)
982#define	PKT2TRAN(pkt)		((pkt)->pkt_address.a_hba_tran)
983#define	ADDR2TRAN(ap)		((ap)->a_hba_tran)
984#define	DIP2TRAN(dip)		(ddi_get_driver_private(dip))
985
986
987#define	TRAN2MPT(hba)		((mptsas_t *)(hba)->tran_hba_private)
988#define	DIP2MPT(dip)		(TRAN2MPT((scsi_hba_tran_t *)DIP2TRAN(dip)))
989#define	SDEV2MPT(sd)		(TRAN2MPT(SDEV2TRAN(sd)))
990#define	PKT2MPT(pkt)		(TRAN2MPT(PKT2TRAN(pkt)))
991
992#define	ADDR2MPT(ap)		(TRAN2MPT(ADDR2TRAN(ap)))
993
994#define	POLL_TIMEOUT		(2 * SCSI_POLL_TIMEOUT * 1000000)
995#define	SHORT_POLL_TIMEOUT	(1000000)	/* in usec, about 1 secs */
996#define	MPTSAS_QUIESCE_TIMEOUT	1		/* 1 sec */
997#define	MPTSAS_PM_IDLE_TIMEOUT	60		/* 60 seconds */
998
999#define	MPTSAS_GET_ISTAT(mpt)  (ddi_get32((mpt)->m_datap, \
1000			&(mpt)->m_reg->HostInterruptStatus))
1001
1002#define	MPTSAS_SET_SIGP(P) \
1003		ClrSetBits(mpt->m_devaddr + NREG_ISTAT, 0, NB_ISTAT_SIGP)
1004
1005#define	MPTSAS_RESET_SIGP(P) (void) ddi_get8(mpt->m_datap, \
1006			(uint8_t *)(mpt->m_devaddr + NREG_CTEST2))
1007
1008#define	MPTSAS_GET_INTCODE(P) (ddi_get32(mpt->m_datap, \
1009			(uint32_t *)(mpt->m_devaddr + NREG_DSPS)))
1010
1011
1012#define	MPTSAS_START_CMD(mpt, req_desc_lo, req_desc_hi) \
1013	ddi_put32(mpt->m_datap, &mpt->m_reg->RequestDescriptorPostLow,\
1014	    req_desc_lo);\
1015	ddi_put32(mpt->m_datap, &mpt->m_reg->RequestDescriptorPostHigh,\
1016	    req_desc_hi);
1017
1018#define	INTPENDING(mpt) \
1019	(MPTSAS_GET_ISTAT(mpt) & MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT)
1020
1021/*
1022 * Mask all interrupts to disable
1023 */
1024#define	MPTSAS_DISABLE_INTR(mpt)	\
1025	ddi_put32((mpt)->m_datap, &(mpt)->m_reg->HostInterruptMask, \
1026	    (MPI2_HIM_RIM | MPI2_HIM_DIM | MPI2_HIM_RESET_IRQ_MASK))
1027
1028/*
1029 * Mask Doorbell and Reset interrupts to enable reply desc int.
1030 */
1031#define	MPTSAS_ENABLE_INTR(mpt)	\
1032	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, \
1033	(MPI2_HIM_DIM | MPI2_HIM_RESET_IRQ_MASK))
1034
1035#define	MPTSAS_GET_NEXT_REPLY(mpt, index)  \
1036	&((uint64_t *)(void *)mpt->m_post_queue)[index]
1037
1038#define	MPTSAS_GET_NEXT_FRAME(mpt, SMID) \
1039	(mpt->m_req_frame + (mpt->m_req_frame_size * SMID))
1040
1041#define	ClrSetBits32(hdl, reg, clr, set) \
1042	ddi_put32(hdl, (reg), \
1043	    ((ddi_get32(mpt->m_datap, (reg)) & ~(clr)) | (set)))
1044
1045#define	ClrSetBits(reg, clr, set) \
1046	ddi_put8(mpt->m_datap, (uint8_t *)(reg), \
1047		((ddi_get8(mpt->m_datap, (uint8_t *)(reg)) & ~(clr)) | (set)))
1048
1049#define	MPTSAS_WAITQ_RM(mpt, cmdp)	\
1050	if ((cmdp = mpt->m_waitq) != NULL) { \
1051		/* If the queue is now empty fix the tail pointer */	\
1052		if ((mpt->m_waitq = cmdp->cmd_linkp) == NULL) \
1053			mpt->m_waitqtail = &mpt->m_waitq; \
1054		cmdp->cmd_linkp = NULL; \
1055		cmdp->cmd_queued = FALSE; \
1056	}
1057
1058#define	MPTSAS_TX_WAITQ_RM(mpt, cmdp)	\
1059	if ((cmdp = mpt->m_tx_waitq) != NULL) { \
1060		/* If the queue is now empty fix the tail pointer */	\
1061		if ((mpt->m_tx_waitq = cmdp->cmd_linkp) == NULL) \
1062			mpt->m_tx_waitqtail = &mpt->m_tx_waitq; \
1063		cmdp->cmd_linkp = NULL; \
1064		cmdp->cmd_queued = FALSE; \
1065	}
1066
1067/*
1068 * defaults for	the global properties
1069 */
1070#define	DEFAULT_SCSI_OPTIONS	SCSI_OPTIONS_DR
1071#define	DEFAULT_TAG_AGE_LIMIT	2
1072#define	DEFAULT_WD_TICK		10
1073
1074/*
1075 * invalid hostid.
1076 */
1077#define	MPTSAS_INVALID_HOSTID  -1
1078
1079/*
1080 * Get/Set hostid from SCSI port configuration page
1081 */
1082#define	MPTSAS_GET_HOST_ID(configuration) (configuration & 0xFF)
1083#define	MPTSAS_SET_HOST_ID(hostid) (hostid | ((1 << hostid) << 16))
1084
1085/*
1086 * Config space.
1087 */
1088#define	MPTSAS_LATENCY_TIMER	0x40
1089
1090/*
1091 * Offset to firmware version
1092 */
1093#define	MPTSAS_FW_VERSION_OFFSET	9
1094
1095/*
1096 * Offset and masks to get at the ProductId field
1097 */
1098#define	MPTSAS_FW_PRODUCTID_OFFSET	8
1099#define	MPTSAS_FW_PRODUCTID_MASK	0xFFFF0000
1100#define	MPTSAS_FW_PRODUCTID_SHIFT	16
1101
1102/*
1103 * Subsystem ID for HBAs.
1104 */
1105#define	MPTSAS_HBA_SUBSYSTEM_ID    0x10C0
1106#define	MPTSAS_RHEA_SUBSYSTEM_ID	0x10B0
1107
1108/*
1109 * reset delay tick
1110 */
1111#define	MPTSAS_WATCH_RESET_DELAY_TICK 50	/* specified in milli seconds */
1112
1113/*
1114 * Ioc reset return values
1115 */
1116#define	MPTSAS_RESET_FAIL	-1
1117#define	MPTSAS_NO_RESET		0
1118#define	MPTSAS_SUCCESS_HARDRESET	1
1119
1120/*
1121 * throttle support.
1122 */
1123#define	MAX_THROTTLE	32
1124#define	HOLD_THROTTLE	0
1125#define	DRAIN_THROTTLE	-1
1126#define	QFULL_THROTTLE	-2
1127
1128/*
1129 * Passthrough/config request flags
1130 */
1131#define	MPTSAS_DATA_ALLOCATED		0x0001
1132#define	MPTSAS_DATAOUT_ALLOCATED	0x0002
1133#define	MPTSAS_REQUEST_POOL_CMD		0x0004
1134#define	MPTSAS_ADDRESS_REPLY		0x0008
1135#define	MPTSAS_CMD_TIMEOUT		0x0010
1136
1137/*
1138 * System Events
1139 */
1140#ifndef	DDI_VENDOR_LSI
1141#define	DDI_VENDOR_LSI	"LSI"
1142#endif	/* DDI_VENDOR_LSI */
1143
1144/*
1145 * Shared functions
1146 */
1147int mptsas_save_cmd(struct mptsas *mpt, struct mptsas_cmd *cmd);
1148void mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
1149void mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
1150int mptsas_config_space_init(struct mptsas *mpt);
1151int mptsas_init_chip(mptsas_t *mpt, int first_time);
1152void mptsas_log(struct mptsas *mpt, int level, char *fmt, ...);
1153int mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime);
1154int mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)());
1155int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action,
1156	uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber,
1157	uint8_t pageversion, uint8_t pagelength, uint32_t
1158	SGEflagslength, uint32_t SGEaddress32);
1159int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
1160	uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
1161	uint8_t pageversion, uint16_t extpagelength,
1162	uint32_t SGEflagslength, uint32_t SGEaddress32);
1163int mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
1164	uint8_t type, int mode);
1165int mptsas_check_flash(mptsas_t *mpt, caddr_t origfile, uint32_t size,
1166	uint8_t type, int mode);
1167int mptsas_download_firmware();
1168int mptsas_can_download_firmware();
1169int mptsas_passthru_dma_alloc(mptsas_t *mpt,
1170    mptsas_dma_alloc_state_t *dma_statep);
1171void mptsas_passthru_dma_free(mptsas_dma_alloc_state_t *dma_statep);
1172uint8_t mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport);
1173uint8_t mptsas_phymask_to_physport(mptsas_t *mpt, uint8_t phymask);
1174void mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd);
1175int mptsas_check_acc_handle(ddi_acc_handle_t handle);
1176int mptsas_check_dma_handle(ddi_dma_handle_t handle);
1177void mptsas_fm_ereport(mptsas_t *mpt, char *detail);
1178
1179/*
1180 * impl functions
1181 */
1182int mptsas_ioc_wait_for_response(mptsas_t *mpt);
1183int mptsas_ioc_wait_for_doorbell(mptsas_t *mpt);
1184int mptsas_ioc_reset(mptsas_t *mpt);
1185int mptsas_send_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
1186    ddi_acc_handle_t accessp);
1187int mptsas_get_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
1188    ddi_acc_handle_t accessp);
1189int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action,
1190    uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber,
1191    uint8_t pageversion, uint8_t pagelength, uint32_t SGEflagslength,
1192    uint32_t SGEaddress32);
1193int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
1194    uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
1195    uint8_t pageversion, uint16_t extpagelength,
1196    uint32_t SGEflagslength, uint32_t SGEaddress32);
1197
1198int mptsas_request_from_pool(mptsas_t *mpt, mptsas_cmd_t **cmd,
1199    struct scsi_pkt **pkt);
1200void mptsas_return_to_pool(mptsas_t *mpt, mptsas_cmd_t *cmd);
1201void mptsas_destroy_ioc_event_cmd(mptsas_t *mpt);
1202void mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd);
1203int mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
1204    uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *,
1205    caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...);
1206
1207int mptsas_ioc_task_management(mptsas_t *mpt, int task_type,
1208    uint16_t dev_handle, int lun);
1209int mptsas_send_event_ack(mptsas_t *mpt, uint32_t event, uint32_t eventcntx);
1210void mptsas_send_pending_event_ack(mptsas_t *mpt);
1211void mptsas_set_throttle(struct mptsas *mpt, mptsas_target_t *ptgt, int what);
1212int mptsas_restart_ioc(mptsas_t *mpt);
1213void mptsas_update_driver_data(struct mptsas *mpt);
1214uint64_t mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun);
1215
1216/*
1217 * init functions
1218 */
1219int mptsas_ioc_get_facts(mptsas_t *mpt);
1220int mptsas_ioc_get_port_facts(mptsas_t *mpt, int port);
1221int mptsas_ioc_enable_port(mptsas_t *mpt);
1222int mptsas_ioc_enable_event_notification(mptsas_t *mpt);
1223int mptsas_ioc_init(mptsas_t *mpt);
1224
1225/*
1226 * configuration pages operation
1227 */
1228int mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
1229    uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
1230    uint8_t *physport, uint8_t *phynum);
1231int mptsas_get_sas_io_unit_page(mptsas_t *mpt);
1232int mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt);
1233int mptsas_get_sas_expander_page0(mptsas_t *mpt, uint32_t page_address,
1234    mptsas_smp_t *info);
1235int mptsas_set_initiator_mode(mptsas_t *mpt);
1236int mptsas_set_ioc_params(mptsas_t *mpt);
1237int mptsas_get_manufacture_page5(mptsas_t *mpt);
1238int mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address,
1239    uint64_t *sas_wwn, uint8_t *portwidth);
1240
1241/*
1242 * RAID functions
1243 */
1244int mptsas_get_raid_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol);
1245int mptsas_get_raid_info(mptsas_t *mpt);
1246int mptsas_get_physdisk_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol,
1247    uint8_t physdisknum);
1248int mptsas_delete_volume(mptsas_t *mpt, uint16_t volid);
1249
1250#define	MPTSAS_IOCSTATUS(status) (status & MPI2_IOCSTATUS_MASK)
1251/*
1252 * debugging.
1253 */
1254#if defined(MPTSAS_DEBUG)
1255
1256void mptsas_printf(char *fmt, ...);
1257
1258#define	MPTSAS_DBGPR(m, args)	\
1259	if (mptsas_debug_flags & (m)) \
1260		mptsas_printf args
1261#else	/* ! defined(MPTSAS_DEBUG) */
1262#define	MPTSAS_DBGPR(m, args)
1263#endif	/* defined(MPTSAS_DEBUG) */
1264
1265#define	NDBG0(args)	MPTSAS_DBGPR(0x01, args)	/* init	*/
1266#define	NDBG1(args)	MPTSAS_DBGPR(0x02, args)	/* normal running */
1267#define	NDBG2(args)	MPTSAS_DBGPR(0x04, args)	/* property handling */
1268#define	NDBG3(args)	MPTSAS_DBGPR(0x08, args)	/* pkt handling */
1269
1270#define	NDBG4(args)	MPTSAS_DBGPR(0x10, args)	/* kmem alloc/free */
1271#define	NDBG5(args)	MPTSAS_DBGPR(0x20, args)	/* polled cmds */
1272#define	NDBG6(args)	MPTSAS_DBGPR(0x40, args)	/* interrupts */
1273#define	NDBG7(args)	MPTSAS_DBGPR(0x80, args)	/* queue handling */
1274
1275#define	NDBG8(args)	MPTSAS_DBGPR(0x0100, args)	/* arq */
1276#define	NDBG9(args)	MPTSAS_DBGPR(0x0200, args)	/* Tagged Q'ing */
1277#define	NDBG10(args)	MPTSAS_DBGPR(0x0400, args)	/* halting chip */
1278#define	NDBG11(args)	MPTSAS_DBGPR(0x0800, args)	/* power management */
1279
1280#define	NDBG12(args)	MPTSAS_DBGPR(0x1000, args)	/* enumeration */
1281#define	NDBG13(args)	MPTSAS_DBGPR(0x2000, args)	/* configuration page */
1282#define	NDBG14(args)	MPTSAS_DBGPR(0x4000, args)
1283#define	NDBG15(args)	MPTSAS_DBGPR(0x8000, args)
1284
1285#define	NDBG16(args)	MPTSAS_DBGPR(0x010000, args)
1286#define	NDBG17(args)	MPTSAS_DBGPR(0x020000, args)	/* scatter/gather */
1287#define	NDBG18(args)	MPTSAS_DBGPR(0x040000, args)
1288#define	NDBG19(args)	MPTSAS_DBGPR(0x080000, args)	/* handshaking */
1289
1290#define	NDBG20(args)	MPTSAS_DBGPR(0x100000, args)	/* events */
1291#define	NDBG21(args)	MPTSAS_DBGPR(0x200000, args)	/* dma */
1292#define	NDBG22(args)	MPTSAS_DBGPR(0x400000, args)	/* reset */
1293#define	NDBG23(args)	MPTSAS_DBGPR(0x800000, args)	/* abort */
1294
1295#define	NDBG24(args)	MPTSAS_DBGPR(0x1000000, args)	/* capabilities */
1296#define	NDBG25(args)	MPTSAS_DBGPR(0x2000000, args)	/* flushing */
1297#define	NDBG26(args)	MPTSAS_DBGPR(0x4000000, args)
1298#define	NDBG27(args)	MPTSAS_DBGPR(0x8000000, args)
1299
1300#define	NDBG28(args)	MPTSAS_DBGPR(0x10000000, args)	/* hotplug */
1301#define	NDBG29(args)	MPTSAS_DBGPR(0x20000000, args)	/* timeouts */
1302#define	NDBG30(args)	MPTSAS_DBGPR(0x40000000, args)	/* mptsas_watch */
1303#define	NDBG31(args)	MPTSAS_DBGPR(0x80000000, args)	/* negotations */
1304
1305/*
1306 * auto request sense
1307 */
1308#define	RQ_MAKECOM_COMMON(pkt, flag, cmd) \
1309	(pkt)->pkt_flags = (flag), \
1310	((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_cmd = (cmd), \
1311	((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
1312	    (pkt)->pkt_address.a_lun
1313
1314#define	RQ_MAKECOM_G0(pkt, flag, cmd, addr, cnt) \
1315	RQ_MAKECOM_COMMON((pkt), (flag), (cmd)), \
1316	FORMG0ADDR(((union scsi_cdb *)(pkt)->pkt_cdbp), (addr)), \
1317	FORMG0COUNT(((union scsi_cdb *)(pkt)->pkt_cdbp), (cnt))
1318
1319
1320#ifdef	__cplusplus
1321}
1322#endif
1323
1324#endif	/* _SYS_SCSI_ADAPTERS_MPTVAR_H */
1325