xref: /freebsd/sys/dev/mpt/mpt.h (revision 822923447e454b30d310cb46903c9ddeca9f0a7a)
1 /* $FreeBSD$ */
2 /*-
3  * Generic defines for LSI '909 FC  adapters.
4  * FreeBSD Version.
5  *
6  * Copyright (c)  2000, 2001 by Greg Ansley
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice immediately at the beginning of the file, without modification,
13  *    this list of conditions, and the following disclaimer.
14  * 2. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Additional Copyright (c) 2002 by Matthew Jacob under same license.
30  */
31 /*
32  * Copyright (c) 2004, Avid Technology, Inc. and its contributors.
33  * Copyright (c) 2004, 2005 Justin T. Gibbs
34  * Copyright (c) 2005, WHEEL Sp. z o.o.
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions are
39  * met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
43  *    substantially similar to the "NO WARRANTY" disclaimer below
44  *    ("Disclaimer") and any redistribution must be conditioned upon including
45  *    a substantially similar Disclaimer requirement for further binary
46  *    redistribution.
47  * 3. Neither the names of the above listed copyright holders nor the names
48  *    of any contributors may be used to endorse or promote products derived
49  *    from this software without specific prior written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
52  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
55  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
61  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 #ifndef _MPT_H_
65 #define _MPT_H_
66 
67 /********************************* OS Includes ********************************/
68 #include <sys/types.h>
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/endian.h>
72 #include <sys/eventhandler.h>
73 #if __FreeBSD_version < 500000
74 #include <sys/kernel.h>
75 #include <sys/queue.h>
76 #include <sys/malloc.h>
77 #else
78 #include <sys/lock.h>
79 #include <sys/kernel.h>
80 #include <sys/queue.h>
81 #include <sys/malloc.h>
82 #include <sys/mutex.h>
83 #include <sys/condvar.h>
84 #endif
85 #include <sys/proc.h>
86 #include <sys/bus.h>
87 #include <sys/module.h>
88 
89 #include <machine/bus.h>
90 #include <machine/clock.h>
91 #include <machine/cpu.h>
92 #include <machine/resource.h>
93 
94 #include <sys/rman.h>
95 
96 #include "opt_ddb.h"
97 
98 /**************************** Register Definitions ****************************/
99 #include <dev/mpt/mpt_reg.h>
100 
101 /******************************* MPI Definitions ******************************/
102 #include <dev/mpt/mpilib/mpi_type.h>
103 #include <dev/mpt/mpilib/mpi.h>
104 #include <dev/mpt/mpilib/mpi_cnfg.h>
105 #include <dev/mpt/mpilib/mpi_ioc.h>
106 #include <dev/mpt/mpilib/mpi_raid.h>
107 
108 /* XXX For mpt_debug.c */
109 #include <dev/mpt/mpilib/mpi_init.h>
110 
111 /****************************** Misc Definitions ******************************/
112 #define MPT_OK (0)
113 #define MPT_FAIL (0x10000)
114 
115 #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
116 
117 /**************************** Forward Declarations ****************************/
118 struct mpt_softc;
119 struct mpt_personality;
120 typedef struct req_entry request_t;
121 
122 /************************* Personality Module Support *************************/
123 typedef int mpt_load_handler_t(struct mpt_personality *);
124 typedef int mpt_probe_handler_t(struct mpt_softc *);
125 typedef int mpt_attach_handler_t(struct mpt_softc *);
126 typedef int mpt_event_handler_t(struct mpt_softc *, request_t *,
127 				MSG_EVENT_NOTIFY_REPLY *);
128 typedef void mpt_reset_handler_t(struct mpt_softc *, int /*type*/);
129 /* XXX Add return value and use for veto? */
130 typedef void mpt_shutdown_handler_t(struct mpt_softc *);
131 typedef void mpt_detach_handler_t(struct mpt_softc *);
132 typedef int mpt_unload_handler_t(struct mpt_personality *);
133 
134 struct mpt_personality
135 {
136 	const char		*name;
137 	uint32_t		 id;		/* Assigned identifier. */
138 	u_int			 use_count;	/* Instances using personality*/
139 	mpt_load_handler_t	*load;		/* configure personailty */
140 #define MPT_PERS_FIRST_HANDLER(pers) (&(pers)->load)
141 	mpt_probe_handler_t	*probe;		/* configure personailty */
142 	mpt_attach_handler_t	*attach;	/* initialize device instance */
143 	mpt_event_handler_t	*event;		/* Handle MPI event. */
144 	mpt_reset_handler_t	*reset;		/* Re-init after reset. */
145 	mpt_shutdown_handler_t	*shutdown;	/* Shutdown instance. */
146 	mpt_detach_handler_t	*detach;	/* release device instance */
147 	mpt_unload_handler_t	*unload;	/* Shutdown personality */
148 #define MPT_PERS_LAST_HANDLER(pers) (&(pers)->unload)
149 };
150 
151 int mpt_modevent(module_t, int, void *);
152 
153 /* Maximum supported number of personalities. */
154 #define MPT_MAX_PERSONALITIES	(15)
155 
156 #define MPT_PERSONALITY_DEPEND(name, dep, vmin, vpref, vmax) \
157 	MODULE_DEPEND(name, dep, vmin, vpref, vmax)
158 
159 #define DECLARE_MPT_PERSONALITY(name, order)				  \
160 	static moduledata_t name##_mod = {				  \
161 		#name, mpt_modevent, &name##_personality		  \
162 	};								  \
163 	DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, order);	  \
164 	MODULE_VERSION(name, 1);					  \
165 	MPT_PERSONALITY_DEPEND(name, mpt_core, 1, 1, 1)
166 
167 /******************************* Bus DMA Support ******************************/
168 /* XXX Need to update bus_dmamap_sync to take a range argument. */
169 #define bus_dmamap_sync_range(dma_tag, dmamap, offset, len, op)	\
170 	bus_dmamap_sync(dma_tag, dmamap, op)
171 
172 #if __FreeBSD_version >= 501102
173 #define mpt_dma_tag_create(mpt, parent_tag, alignment, boundary,	\
174 			   lowaddr, highaddr, filter, filterarg,	\
175 			   maxsize, nsegments, maxsegsz, flags,		\
176 			   dma_tagp)					\
177 	bus_dma_tag_create(parent_tag, alignment, boundary,		\
178 			   lowaddr, highaddr, filter, filterarg,	\
179 			   maxsize, nsegments, maxsegsz, flags,		\
180 			   busdma_lock_mutex, &Giant,			\
181 			   dma_tagp)
182 #else
183 #define mpt_dma_tag_create(mpt, parent_tag, alignment, boundary,	\
184 			   lowaddr, highaddr, filter, filterarg,	\
185 			   maxsize, nsegments, maxsegsz, flags,		\
186 			   dma_tagp)					\
187 	bus_dma_tag_create(parent_tag, alignment, boundary,		\
188 			   lowaddr, highaddr, filter, filterarg,	\
189 			   maxsize, nsegments, maxsegsz, flags,		\
190 			   dma_tagp)
191 #endif
192 
193 struct mpt_map_info {
194 	struct mpt_softc *mpt;
195 	int		  error;
196 	uint32_t	  phys;
197 };
198 
199 void mpt_map_rquest(void *, bus_dma_segment_t *, int, int);
200 
201 /**************************** Kernel Thread Support ***************************/
202 #if __FreeBSD_version > 500005
203 #define mpt_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \
204 	kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg)
205 #else
206 #define mpt_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \
207 	kthread_create(func, farg, proc_ptr, fmtstr, arg)
208 #endif
209 
210 /****************************** Timer Facilities ******************************/
211 #if __FreeBSD_version > 500000
212 #define mpt_callout_init(c)	callout_init(c, /*mpsafe*/0);
213 #else
214 #define mpt_callout_init(c)	callout_init(c);
215 #endif
216 
217 /********************************** Endianess *********************************/
218 static __inline uint64_t
219 u64toh(U64 s)
220 {
221 	uint64_t result;
222 
223 	result = le32toh(s.Low);
224 	result |= ((uint64_t)le32toh(s.High)) << 32;
225 	return (result);
226 }
227 
228 /**************************** MPI Transaction State ***************************/
229 typedef enum {
230 	REQ_STATE_FREE		= 0x00,
231 	REQ_STATE_ALLOCATED	= 0x01,
232 	REQ_STATE_QUEUED	= 0x02,
233 	REQ_STATE_DONE		= 0x04,
234 	REQ_STATE_TIMEDOUT	= 0x08,
235 	REQ_STATE_NEED_WAKEUP	= 0x10,
236 	REQ_STATE_MASK		= 0xFF
237 } mpt_req_state_t;
238 
239 struct req_entry {
240 	TAILQ_ENTRY(req_entry) links;	/* Pointer to next in list */
241 	mpt_req_state_t	state;		/* Request State Information */
242 	uint16_t	index;		/* Index of this entry */
243 	uint16_t	IOCStatus;	/* Completion status */
244 	union ccb      *ccb;		/* CAM request */
245 	void	       *req_vbuf;	/* Virtual Address of Entry */
246 	void	       *sense_vbuf;	/* Virtual Address of sense data */
247 	bus_addr_t	req_pbuf;	/* Physical Address of Entry */
248 	bus_addr_t	sense_pbuf;	/* Physical Address of sense data */
249 	bus_dmamap_t	dmap;		/* DMA map for data buffer */
250 };
251 
252 /**************************** Handler Registration ****************************/
253 /*
254  * Global table of registered reply handlers.  The
255  * handler is indicated by byte 3 of the request
256  * index submitted to the IOC.  This allows the
257  * driver core to perform generic processing without
258  * any knowledge of per-personality behavior.
259  *
260  * MPT_NUM_REPLY_HANDLERS must be a power of 2
261  * to allow the easy generation of a mask.
262  *
263  * The handler offsets used by the core are hard coded
264  * allowing faster code generation when assigning a handler
265  * to a request.  All "personalities" must use the
266  * the handler registration mechanism.
267  *
268  * The IOC handlers that are rarely executed are placed
269  * at the tail of the table to make it more likely that
270  * all commonly executed handlers fit in a single cache
271  * line.
272  */
273 #define MPT_NUM_REPLY_HANDLERS		(16)
274 #define MPT_REPLY_HANDLER_EVENTS	MPT_CBI_TO_HID(0)
275 #define MPT_REPLY_HANDLER_CONFIG	MPT_CBI_TO_HID(MPT_NUM_REPLY_HANDLERS-1)
276 #define MPT_REPLY_HANDLER_HANDSHAKE	MPT_CBI_TO_HID(MPT_NUM_REPLY_HANDLERS-2)
277 typedef int mpt_reply_handler_t(struct mpt_softc *mpt, request_t *request,
278 				 MSG_DEFAULT_REPLY *reply_frame);
279 typedef union {
280 	mpt_reply_handler_t	*reply_handler;
281 } mpt_handler_t;
282 
283 typedef enum {
284 	MPT_HANDLER_REPLY,
285 	MPT_HANDLER_EVENT,
286 	MPT_HANDLER_RESET,
287 	MPT_HANDLER_SHUTDOWN
288 } mpt_handler_type;
289 
290 struct mpt_handler_record
291 {
292 	LIST_ENTRY(mpt_handler_record)	links;
293 	mpt_handler_t			handler;
294 };
295 
296 LIST_HEAD(mpt_handler_list, mpt_handler_record);
297 
298 /*
299  * The handler_id is currently unused but would contain the
300  * handler ID used in the MsgContext field to allow direction
301  * of replies to the handler.  Registrations that don't require
302  * a handler id can pass in NULL for the handler_id.
303  *
304  * Deregistrations for handlers without a handler id should
305  * pass in MPT_HANDLER_ID_NONE.
306  */
307 #define MPT_HANDLER_ID_NONE		(0xFFFFFFFF)
308 int mpt_register_handler(struct mpt_softc *, mpt_handler_type,
309 			 mpt_handler_t, uint32_t *);
310 int mpt_deregister_handler(struct mpt_softc *, mpt_handler_type,
311 			   mpt_handler_t, uint32_t);
312 
313 /******************* Per-Controller Instance Data Structures ******************/
314 TAILQ_HEAD(req_queue, req_entry);
315 
316 /* Structure for saving proper values for modifyable PCI config registers */
317 struct mpt_pci_cfg {
318 	uint16_t Command;
319 	uint16_t LatencyTimer_LineSize;
320 	uint32_t IO_BAR;
321 	uint32_t Mem0_BAR[2];
322 	uint32_t Mem1_BAR[2];
323 	uint32_t ROM_BAR;
324 	uint8_t  IntLine;
325 	uint32_t PMCSR;
326 };
327 
328 typedef enum {
329 	MPT_RVF_NONE		= 0x0,
330 	MPT_RVF_ACTIVE		= 0x1,
331 	MPT_RVF_ANNOUNCED	= 0x2,
332 	MPT_RVF_UP2DATE		= 0x4,
333 	MPT_RVF_REFERENCED	= 0x8,
334 	MPT_RVF_WCE_CHANGED	= 0x10
335 } mpt_raid_volume_flags;
336 
337 struct mpt_raid_volume {
338 	CONFIG_PAGE_RAID_VOL_0	       *config_page;
339 	MPI_RAID_VOL_INDICATOR		sync_progress;
340 	mpt_raid_volume_flags		flags;
341 	u_int				quieced_disks;
342 };
343 
344 typedef enum {
345 	MPT_RDF_NONE		= 0x00,
346 	MPT_RDF_ACTIVE		= 0x01,
347 	MPT_RDF_ANNOUNCED	= 0x02,
348 	MPT_RDF_UP2DATE		= 0x04,
349 	MPT_RDF_REFERENCED	= 0x08,
350 	MPT_RDF_QUIESCING	= 0x10,
351 	MPT_RDF_QUIESCED	= 0x20
352 } mpt_raid_disk_flags;
353 
354 struct mpt_raid_disk {
355 	CONFIG_PAGE_RAID_PHYS_DISK_0	config_page;
356 	struct mpt_raid_volume	       *volume;
357 	u_int				member_number;
358 	u_int				pass_thru_active;
359 	mpt_raid_disk_flags		flags;
360 };
361 
362 struct mpt_evtf_record {
363 	MSG_EVENT_NOTIFY_REPLY		reply;
364 	uint32_t			context;
365 	LIST_ENTRY(mpt_evtf_record)	links;
366 };
367 
368 LIST_HEAD(mpt_evtf_list, mpt_evtf_record);
369 
370 struct mpt_softc {
371 	device_t		dev;
372 #if __FreeBSD_version < 500000
373 	int			mpt_splsaved;
374 	uint32_t		mpt_islocked;
375 #else
376 	struct mtx		mpt_lock;
377 #endif
378 	uint32_t		mpt_pers_mask;
379 	uint32_t		: 15,
380 		raid_mwce_set	: 1,
381 		getreqwaiter	: 1,
382 		shutdwn_raid    : 1,
383 		shutdwn_recovery: 1,
384 		unit		: 8,
385 		outofbeer	: 1,
386 		mpt_locksetup	: 1,
387 		disabled	: 1,
388 		is_fc		: 1,
389 		bus		: 1;	/* FC929/1030 have two busses */
390 
391 	u_int			verbose;
392 
393 	/*
394 	 * IOC Facts
395 	 */
396 	uint16_t	mpt_global_credits;
397 	uint16_t	request_frame_size;
398 	uint8_t		mpt_max_devices;
399 	uint8_t		mpt_max_buses;
400 
401 	/*
402 	 * Port Facts
403 	 * XXX - Add multi-port support!.
404 	 */
405 	uint16_t	mpt_ini_id;
406 	uint16_t	mpt_port_type;
407 	uint16_t	mpt_proto_flags;
408 
409 	/*
410 	 * Device Configuration Information
411 	 */
412 	union {
413 		struct mpt_spi_cfg {
414 			CONFIG_PAGE_SCSI_PORT_0		_port_page0;
415 			CONFIG_PAGE_SCSI_PORT_1		_port_page1;
416 			CONFIG_PAGE_SCSI_PORT_2		_port_page2;
417 			CONFIG_PAGE_SCSI_DEVICE_0	_dev_page0[16];
418 			CONFIG_PAGE_SCSI_DEVICE_1	_dev_page1[16];
419 			uint16_t			_tag_enable;
420 			uint16_t			_disc_enable;
421 			uint16_t			_update_params0;
422 			uint16_t			_update_params1;
423 		} spi;
424 #define	mpt_port_page0		cfg.spi._port_page0
425 #define	mpt_port_page1		cfg.spi._port_page1
426 #define	mpt_port_page2		cfg.spi._port_page2
427 #define	mpt_dev_page0		cfg.spi._dev_page0
428 #define	mpt_dev_page1		cfg.spi._dev_page1
429 #define	mpt_tag_enable		cfg.spi._tag_enable
430 #define	mpt_disc_enable		cfg.spi._disc_enable
431 #define	mpt_update_params0	cfg.spi._update_params0
432 #define	mpt_update_params1	cfg.spi._update_params1
433 		struct mpi_fc_cfg {
434 			uint8_t	nada;
435 		} fc;
436 	} cfg;
437 
438 	/* Controller Info */
439 	CONFIG_PAGE_IOC_2 *	ioc_page2;
440 	CONFIG_PAGE_IOC_3 *	ioc_page3;
441 
442 	/* Raid Data */
443 	struct mpt_raid_volume* raid_volumes;
444 	struct mpt_raid_disk*	raid_disks;
445 	u_int			raid_max_volumes;
446 	u_int			raid_max_disks;
447 	u_int			raid_page0_len;
448 	u_int			raid_wakeup;
449 	u_int			raid_rescan;
450 	u_int			raid_resync_rate;
451 	u_int			raid_mwce_setting;
452 	u_int			raid_queue_depth;
453 	struct proc	       *raid_thread;
454 	struct callout		raid_timer;
455 
456 	/*
457 	 * PCI Hardware info
458 	 */
459 	struct resource *	pci_irq;	/* Interrupt map for chip */
460 	void *			ih;		/* Interupt handle */
461 	struct mpt_pci_cfg	pci_cfg;	/* saved PCI conf registers */
462 
463 	/*
464 	 * DMA Mapping Stuff
465 	 */
466 	struct resource *	pci_reg;	/* Register map for chip */
467 	int			pci_mem_rid;	/* Resource ID */
468 	bus_space_tag_t		pci_st;		/* Bus tag for registers */
469 	bus_space_handle_t	pci_sh;		/* Bus handle for registers */
470 	/* PIO versions of above. */
471 	int			pci_pio_rid;
472 	struct resource *	pci_pio_reg;
473 	bus_space_tag_t		pci_pio_st;
474 	bus_space_handle_t	pci_pio_sh;
475 
476 	bus_dma_tag_t		parent_dmat;	/* DMA tag for parent PCI bus */
477 	bus_dma_tag_t		reply_dmat;	/* DMA tag for reply memory */
478 	bus_dmamap_t		reply_dmap;	/* DMA map for reply memory */
479 	uint8_t		       *reply;		/* KVA of reply memory */
480 	bus_addr_t		reply_phys;	/* BusAddr of reply memory */
481 
482 	bus_dma_tag_t		buffer_dmat;	/* DMA tag for buffers */
483 	bus_dma_tag_t		request_dmat;	/* DMA tag for request memroy */
484 	bus_dmamap_t		request_dmap;	/* DMA map for request memroy */
485 	uint8_t		       *request;	/* KVA of Request memory */
486 	bus_addr_t		request_phys;	/* BusADdr of request memory */
487 
488 	u_int			reset_cnt;
489 
490 	/*
491 	 * CAM && Software Management
492 	 */
493 	request_t	       *request_pool;
494 	struct req_queue	request_free_list;
495 	struct req_queue	request_pending_list;
496 	struct req_queue	request_timeout_list;
497 
498 	/*
499 	 * Deferred frame acks due to resource shortage.
500 	 */
501 	struct mpt_evtf_list	ack_frames;
502 
503 
504 	struct cam_sim	       *sim;
505 	struct cam_path	       *path;
506 
507 	struct cam_sim	       *phydisk_sim;
508 	struct cam_path	       *phydisk_path;
509 
510 	struct proc	       *recovery_thread;
511 	request_t	       *tmf_req;
512 
513 	uint32_t		sequence;	/* Sequence Number */
514 	uint32_t		timeouts;	/* timeout count */
515 	uint32_t		success;	/* successes afer timeout */
516 
517 	/* Opposing port in a 929 or 1030, or NULL */
518 	struct mpt_softc *	mpt2;
519 
520 	/* FW Image management */
521 	uint32_t		fw_image_size;
522 	uint8_t		       *fw_image;
523 	bus_dma_tag_t		fw_dmat;	/* DMA tag for firmware image */
524 	bus_dmamap_t		fw_dmap;	/* DMA map for firmware image */
525 	bus_addr_t		fw_phys;	/* BusAddr of request memory */
526 
527 	/* Shutdown Event Handler. */
528 	eventhandler_tag         eh;
529 
530 	TAILQ_ENTRY(mpt_softc)	links;
531 };
532 
533 /***************************** Locking Primatives *****************************/
534 #if __FreeBSD_version < 500000
535 #define	MPT_IFLAGS		INTR_TYPE_CAM
536 #define	MPT_LOCK(mpt)		mpt_lockspl(mpt)
537 #define	MPT_UNLOCK(mpt)		mpt_unlockspl(mpt)
538 #define	MPTLOCK_2_CAMLOCK	MPT_UNLOCK
539 #define	CAMLOCK_2_MPTLOCK	MPT_LOCK
540 #define	MPT_LOCK_SETUP(mpt)
541 #define	MPT_LOCK_DESTROY(mpt)
542 
543 static __inline void mpt_lockspl(struct mpt_softc *mpt);
544 static __inline void mpt_unlockspl(struct mpt_softc *mpt);
545 
546 static __inline void
547 mpt_lockspl(struct mpt_softc *mpt)
548 {
549        int s;
550 
551        s = splcam();
552        if (mpt->mpt_islocked++ == 0) {
553                mpt->mpt_splsaved = s;
554        } else {
555                splx(s);
556 	       panic("Recursed lock with mask: 0x%x\n", s);
557        }
558 }
559 
560 static __inline void
561 mpt_unlockspl(struct mpt_softc *mpt)
562 {
563        if (mpt->mpt_islocked) {
564                if (--mpt->mpt_islocked == 0) {
565                        splx(mpt->mpt_splsaved);
566                }
567        } else
568 	       panic("Negative lock count\n");
569 }
570 
571 static __inline int
572 mpt_sleep(struct mpt_softc *mpt, void *ident, int priority,
573 	   const char *wmesg, int timo)
574 {
575 	int saved_cnt;
576 	int saved_spl;
577 	int error;
578 
579 	KASSERT(mpt->mpt_islocked <= 1, ("Invalid lock count on tsleep"));
580 	saved_cnt = mpt->mpt_islocked;
581 	saved_spl = mpt->mpt_splsaved;
582 	mpt->mpt_islocked = 0;
583 	error = tsleep(ident, priority, wmesg, timo);
584 	KASSERT(mpt->mpt_islocked = 0, ("Invalid lock count on wakeup"));
585 	mpt->mpt_islocked = saved_cnt;
586 	mpt->mpt_splsaved = saved_spl;
587 	return (error);
588 }
589 
590 #else
591 #if	LOCKING_WORKED_AS_IT_SHOULD
592 #error "Shouldn't Be Here!"
593 #define	MPT_IFLAGS		INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
594 #define	MPT_LOCK_SETUP(mpt)						\
595 		mtx_init(&mpt->mpt_lock, "mpt", NULL, MTX_DEF);		\
596 		mpt->mpt_locksetup = 1
597 #define	MPT_LOCK_DESTROY(mpt)						\
598 	if (mpt->mpt_locksetup) {					\
599 		mtx_destroy(&mpt->mpt_lock);				\
600 		mpt->mpt_locksetup = 0;					\
601 	}
602 
603 #define	MPT_LOCK(mpt)		mtx_lock(&(mpt)->mpt_lock)
604 #define	MPT_UNLOCK(mpt)		mtx_unlock(&(mpt)->mpt_lock)
605 #define	MPTLOCK_2_CAMLOCK(mpt)	\
606 	mtx_unlock(&(mpt)->mpt_lock); mtx_lock(&Giant)
607 #define	CAMLOCK_2_MPTLOCK(mpt)	\
608 	mtx_unlock(&Giant); mtx_lock(&(mpt)->mpt_lock)
609 #define mpt_sleep(mpt, ident, priority, wmesg, timo) \
610 	msleep(ident, &(mpt)->mpt_lock, priority, wmesg, timo)
611 #else
612 #define	MPT_IFLAGS		INTR_TYPE_CAM | INTR_ENTROPY
613 #define	MPT_LOCK_SETUP(mpt)	do { } while (0)
614 #define	MPT_LOCK_DESTROY(mpt)	do { } while (0)
615 #define	MPT_LOCK(mpt)		do { } while (0)
616 #define	MPT_UNLOCK(mpt)		do { } while (0)
617 #define	MPTLOCK_2_CAMLOCK(mpt)	do { } while (0)
618 #define	CAMLOCK_2_MPTLOCK(mpt)	do { } while (0)
619 #define mpt_sleep(mpt, ident, priority, wmesg, timo) \
620 	tsleep(ident, priority, wmesg, timo)
621 #endif
622 #endif
623 
624 /******************************* Register Access ******************************/
625 static __inline void mpt_write(struct mpt_softc *, size_t, uint32_t);
626 static __inline uint32_t mpt_read(struct mpt_softc *, int);
627 static __inline void mpt_pio_write(struct mpt_softc *, size_t, uint32_t);
628 static __inline uint32_t mpt_pio_read(struct mpt_softc *, int);
629 
630 static __inline void
631 mpt_write(struct mpt_softc *mpt, size_t offset, uint32_t val)
632 {
633 	bus_space_write_4(mpt->pci_st, mpt->pci_sh, offset, val);
634 }
635 
636 static __inline uint32_t
637 mpt_read(struct mpt_softc *mpt, int offset)
638 {
639 	return (bus_space_read_4(mpt->pci_st, mpt->pci_sh, offset));
640 }
641 
642 /*
643  * Some operations (e.g. diagnostic register writes while the ARM proccessor
644  * is disabled), must be performed using "PCI pio" operations.  On non-PCI
645  * busses, these operations likely map to normal register accesses.
646  */
647 static __inline void
648 mpt_pio_write(struct mpt_softc *mpt, size_t offset, uint32_t val)
649 {
650 	bus_space_write_4(mpt->pci_pio_st, mpt->pci_pio_sh, offset, val);
651 }
652 
653 static __inline uint32_t
654 mpt_pio_read(struct mpt_softc *mpt, int offset)
655 {
656 	return (bus_space_read_4(mpt->pci_pio_st, mpt->pci_pio_sh, offset));
657 }
658 /*********************** Reply Frame/Request Management ***********************/
659 /* Max MPT Reply we are willing to accept (must be power of 2) */
660 #define MPT_REPLY_SIZE   	128
661 
662 #define MPT_MAX_REQUESTS(mpt)	((mpt)->is_fc ? 1024 : 256)
663 #define MPT_REQUEST_AREA 512
664 #define MPT_SENSE_SIZE    32	/* included in MPT_REQUEST_SIZE */
665 #define MPT_REQ_MEM_SIZE(mpt)	(MPT_MAX_REQUESTS(mpt) * MPT_REQUEST_AREA)
666 
667 #define MPT_CONTEXT_CB_SHIFT	(16)
668 #define MPT_CBI(handle)	(handle >> MPT_CONTEXT_CB_SHIFT)
669 #define MPT_CBI_TO_HID(cbi)	((cbi) << MPT_CONTEXT_CB_SHIFT)
670 #define MPT_CONTEXT_TO_CBI(x)	\
671     (((x) >> MPT_CONTEXT_CB_SHIFT) & (MPT_NUM_REPLY_HANDLERS - 1))
672 #define MPT_CONTEXT_REQI_MASK 0xFFFF
673 #define MPT_CONTEXT_TO_REQI(x)	\
674     ((x) & MPT_CONTEXT_REQI_MASK)
675 
676 /*
677  * Convert a 32bit physical address returned from IOC to an
678  * offset into our reply frame memory or the kvm address needed
679  * to access the data.  The returned address is only the low
680  * 32 bits, so mask our base physical address accordingly.
681  */
682 #define MPT_REPLY_BADDR(x)		\
683 	(x << 1)
684 #define MPT_REPLY_OTOV(m, i) 		\
685 	((void *)(&m->reply[i]))
686 
687 #define	MPT_DUMP_REPLY_FRAME(mpt, reply_frame)		\
688 do {							\
689 	if (mpt->verbose >= MPT_PRT_DEBUG)		\
690 		mpt_dump_reply_frame(mpt, reply_frame);	\
691 } while(0)
692 
693 static __inline uint32_t mpt_pop_reply_queue(struct mpt_softc *mpt);
694 static __inline void mpt_free_reply(struct mpt_softc *mpt, uint32_t ptr);
695 
696 /*
697  * Give the reply buffer back to the IOC after we have
698  * finished processing it.
699  */
700 static __inline void
701 mpt_free_reply(struct mpt_softc *mpt, uint32_t ptr)
702 {
703      mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
704 }
705 
706 /* Get a reply from the IOC */
707 static __inline uint32_t
708 mpt_pop_reply_queue(struct mpt_softc *mpt)
709 {
710      return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
711 }
712 
713 void mpt_complete_request_chain(struct mpt_softc *mpt,
714 				struct req_queue *chain, u_int iocstatus);
715 /************************** Scatter Gather Managment **************************/
716 /*
717  * We cannot tell prior to getting IOC facts how big the IOC's request
718  * area is. Because of this we cannot tell at compile time how many
719  * simple SG elements we can fit within an IOC request prior to having
720  * to put in a chain element.
721  *
722  * Experimentally we know that the Ultra4 parts have a 96 byte request
723  * element size and the Fibre Channel units have a 144 byte request
724  * element size. Therefore, if we have 512-32 (== 480) bytes of request
725  * area to play with, we have room for between 3 and 5 request sized
726  * regions- the first of which is the command  plus a simple SG list,
727  * the rest of which are chained continuation SG lists. Given that the
728  * normal request we use is 48 bytes w/o the first SG element, we can
729  * assume we have 480-48 == 432 bytes to have simple SG elements and/or
730  * chain elements. If we assume 32 bit addressing, this works out to
731  * 54 SG or chain elements. If we assume 5 chain elements, then we have
732  * a maximum of 49 seperate actual SG segments.
733  */
734 #define MPT_SGL_MAX		49
735 
736 #define	MPT_RQSL(mpt)		(mpt->request_frame_size << 2)
737 #define	MPT_NSGL(mpt)		(MPT_RQSL(mpt) / sizeof (SGE_SIMPLE32))
738 
739 #define	MPT_NSGL_FIRST(mpt)				\
740 	(((mpt->request_frame_size << 2) -		\
741 	sizeof (MSG_SCSI_IO_REQUEST) -			\
742 	sizeof (SGE_IO_UNION)) / sizeof (SGE_SIMPLE32))
743 
744 /***************************** IOC Initialization *****************************/
745 int mpt_reset(struct mpt_softc *, int /*reinit*/);
746 
747 /****************************** Debugging/Logging *****************************/
748 typedef struct mpt_decode_entry {
749 	char    *name;
750 	u_int	 value;
751 	u_int	 mask;
752 } mpt_decode_entry_t;
753 
754 int mpt_decode_value(mpt_decode_entry_t *table, u_int num_entries,
755 		     const char *name, u_int value, u_int *cur_column,
756 		     u_int wrap_point);
757 
758 enum {
759 	MPT_PRT_ALWAYS,
760 	MPT_PRT_FATAL,
761 	MPT_PRT_ERROR,
762 	MPT_PRT_WARN,
763 	MPT_PRT_INFO,
764 	MPT_PRT_DEBUG,
765 	MPT_PRT_TRACE
766 };
767 
768 #define mpt_lprt(mpt, level, ...)		\
769 do {						\
770 	if (level <= (mpt)->verbose)		\
771 		mpt_prt(mpt, __VA_ARGS__);	\
772 } while (0)
773 
774 #define mpt_lprtc(mpt, level, ...)		 \
775 do {						 \
776 	if (level <= (mpt)->debug_level)	 \
777 		mpt_prtc(mpt, __VA_ARGS__);	 \
778 } while (0)
779 
780 void mpt_prt(struct mpt_softc *, const char *, ...);
781 void mpt_prtc(struct mpt_softc *, const char *, ...);
782 
783 /**************************** Unclassified Routines ***************************/
784 void		mpt_send_cmd(struct mpt_softc *mpt, request_t *req);
785 int		mpt_recv_handshake_reply(struct mpt_softc *mpt,
786 					 size_t reply_len, void *reply);
787 int		mpt_wait_req(struct mpt_softc *mpt, request_t *req,
788 			     mpt_req_state_t state, mpt_req_state_t mask,
789 			     int sleep_ok, int time_ms);
790 void		mpt_enable_ints(struct mpt_softc *mpt);
791 void		mpt_disable_ints(struct mpt_softc *mpt);
792 int		mpt_attach(struct mpt_softc *mpt);
793 int		mpt_shutdown(struct mpt_softc *mpt);
794 int		mpt_detach(struct mpt_softc *mpt);
795 int		mpt_send_handshake_cmd(struct mpt_softc *mpt,
796 				       size_t len, void *cmd);
797 request_t *	mpt_get_request(struct mpt_softc *mpt, int sleep_ok);
798 void		mpt_free_request(struct mpt_softc *mpt, request_t *req);
799 void		mpt_intr(void *arg);
800 void		mpt_check_doorbell(struct mpt_softc *mpt);
801 void		mpt_dump_reply_frame(struct mpt_softc *mpt,
802 				     MSG_DEFAULT_REPLY *reply_frame);
803 
804 void		mpt_set_config_regs(struct mpt_softc *);
805 int		mpt_issue_cfg_req(struct mpt_softc */*mpt*/, request_t */*req*/,
806 				  u_int /*Action*/, u_int /*PageVersion*/,
807 				  u_int /*PageLength*/, u_int /*PageNumber*/,
808 				  u_int /*PageType*/, uint32_t /*PageAddress*/,
809 				  bus_addr_t /*addr*/, bus_size_t/*len*/,
810 				  int /*sleep_ok*/, int /*timeout_ms*/);
811 int		mpt_read_cfg_header(struct mpt_softc *, int /*PageType*/,
812 				    int /*PageNumber*/,
813 				    uint32_t /*PageAddress*/,
814 				    CONFIG_PAGE_HEADER *,
815 				    int /*sleep_ok*/, int /*timeout_ms*/);
816 int		mpt_read_cfg_page(struct mpt_softc *t, int /*Action*/,
817 				  uint32_t /*PageAddress*/,
818 				  CONFIG_PAGE_HEADER *, size_t /*len*/,
819 				  int /*sleep_ok*/, int /*timeout_ms*/);
820 int		mpt_write_cfg_page(struct mpt_softc *, int /*Action*/,
821 				   uint32_t /*PageAddress*/,
822 				   CONFIG_PAGE_HEADER *, size_t /*len*/,
823 				   int /*sleep_ok*/, int /*timeout_ms*/);
824 static __inline int
825 mpt_read_cur_cfg_page(struct mpt_softc *mpt, uint32_t PageAddress,
826 		      CONFIG_PAGE_HEADER *hdr, size_t len,
827 		      int sleep_ok, int timeout_ms)
828 {
829 	return (mpt_read_cfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
830 				  PageAddress, hdr, len, sleep_ok, timeout_ms));
831 }
832 
833 static __inline int
834 mpt_write_cur_cfg_page(struct mpt_softc *mpt, uint32_t PageAddress,
835 		       CONFIG_PAGE_HEADER *hdr, size_t len, int sleep_ok,
836 		       int timeout_ms)
837 {
838 	return (mpt_write_cfg_page(mpt, MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT,
839 				   PageAddress, hdr, len, sleep_ok,
840 				   timeout_ms));
841 }
842 
843 /* mpt_debug.c functions */
844 void mpt_print_reply(void *vmsg);
845 void mpt_print_db(uint32_t mb);
846 void mpt_print_config_reply(void *vmsg);
847 char *mpt_ioc_diag(uint32_t diag);
848 void mpt_req_state(mpt_req_state_t state);
849 void mpt_print_config_request(void *vmsg);
850 void mpt_print_request(void *vmsg);
851 void mpt_print_scsi_io_request(MSG_SCSI_IO_REQUEST *msg);
852 #endif /* _MPT_H_ */
853