xref: /freebsd/sys/dev/ciss/cissvar.h (revision 45645518ea19ccb4761aee3a525aab2f323d37d4)
1  /*-
2   * SPDX-License-Identifier: BSD-2-Clause
3   *
4   * Copyright (c) 2001 Michael Smith
5   * All rights reserved.
6   *
7   * Redistribution and use in source and binary forms, with or without
8   * modification, are permitted provided that the following conditions
9   * are met:
10   * 1. Redistributions of source code must retain the above copyright
11   *    notice, this list of conditions and the following disclaimer.
12   * 2. Redistributions in binary form must reproduce the above copyright
13   *    notice, this list of conditions and the following disclaimer in the
14   *    documentation and/or other materials provided with the distribution.
15   *
16   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26   * SUCH DAMAGE.
27   */
28  
29  /*
30   * CISS adapter driver datastructures
31   */
32  
33  typedef STAILQ_HEAD(, ciss_request)	cr_qhead_t;
34  
35  /************************************************************************
36   * Tunable parameters
37   */
38  
39  /*
40   * There is no guaranteed upper bound on the number of concurrent
41   * commands an adapter may claim to support.  Cap it at a reasonable
42   * value.
43   */
44  #define CISS_MAX_REQUESTS	1024
45  
46  /*
47   * Maximum number of logical drives we support.
48   * If the controller does not indicate a maximum
49   * value.  This is a compatibiliy value to support
50   * older ciss controllers (e.g. model 6i)
51   */
52  #define CISS_MAX_LOGICAL	16
53  
54  /*
55   * Maximum number of physical devices we support.
56   */
57  #define CISS_MAX_PHYSICAL	1024
58  
59  /*
60   * Interrupt reduction can be controlled by tuning the interrupt
61   * coalesce delay and count parameters.  The delay (in microseconds)
62   * defers delivery of interrupts to increase the chance of there being
63   * more than one completed command ready when the interrupt is
64   * delivered.  The count expedites the delivery of the interrupt when
65   * the given number of commands are ready.
66   *
67   * If the delay is set to 0, interrupts are delivered immediately.
68   */
69  #define CISS_INTERRUPT_COALESCE_DELAY	0
70  #define CISS_INTERRUPT_COALESCE_COUNT	16
71  
72  /*
73   * Heartbeat routine timeout in seconds.  Note that since event
74   * handling is performed on a callback basis, we don't need this to
75   * run very often.
76   */
77  #define CISS_HEARTBEAT_RATE		10
78  
79  /************************************************************************
80   * Driver version.  Only really significant to the ACU interface.
81   */
82  #define CISS_DRIVER_VERSION	20011201
83  
84  /************************************************************************
85   * Driver data structures
86   */
87  
88  /*
89   * Each command issued to the adapter is managed by a request
90   * structure.
91   */
92  struct ciss_request
93  {
94      STAILQ_ENTRY(ciss_request)	cr_link;
95      int				cr_onq;		/* which queue we are on */
96  
97      struct ciss_softc		*cr_sc;		/* controller softc */
98      void			*cr_data;	/* data buffer */
99      u_int32_t			cr_length;	/* data length */
100      bus_dmamap_t		cr_datamap;	/* DMA map for data */
101      struct ciss_command		*cr_cc;
102      uint32_t			cr_ccphys;
103      int				cr_tag;
104      int				cr_flags;
105  #define CISS_REQ_MAPPED		(1<<0)		/* data mapped */
106  #define CISS_REQ_SLEEP		(1<<1)		/* submitter sleeping */
107  #define CISS_REQ_POLL		(1<<2)		/* submitter polling */
108  #define CISS_REQ_DATAOUT	(1<<3)		/* data host->adapter */
109  #define CISS_REQ_DATAIN		(1<<4)		/* data adapter->host */
110  #define CISS_REQ_BUSY		(1<<5)		/* controller has req */
111  #define CISS_REQ_CCB		(1<<6)		/* data is ccb */
112  
113      void			(* cr_complete)(struct ciss_request *);
114      void			*cr_private;
115      int				cr_sg_tag;
116  #define CISS_SG_MAX		((CISS_SG_FETCH_MAX << 1) | 0x1)
117  #define CISS_SG_1		((CISS_SG_FETCH_1 << 1) | 0x01)
118  #define CISS_SG_2		((CISS_SG_FETCH_2 << 1) | 0x01)
119  #define CISS_SG_4		((CISS_SG_FETCH_4 << 1) | 0x01)
120  #define CISS_SG_8		((CISS_SG_FETCH_8 << 1) | 0x01)
121  #define CISS_SG_16		((CISS_SG_FETCH_16 << 1) | 0x01)
122  #define CISS_SG_32		((CISS_SG_FETCH_32 << 1) | 0x01)
123  #define CISS_SG_NONE		((CISS_SG_FETCH_NONE << 1) | 0x01)
124  };
125  
126  /*
127   * The adapter command structure is defined with a zero-length
128   * scatter/gather list size.  In practise, we want space for a
129   * scatter-gather list, and we also want to avoid having commands
130   * cross page boundaries.
131   *
132   * The size of the ciss_command is 52 bytes.  65 s/g elements are reserved
133   * to allow a max i/o size of 256k.  This gives a total command size of
134   * 1120 bytes, including the 32 byte alignment padding.  Modern controllers
135   * seem to saturate nicely at this value.
136   */
137  
138  #define CISS_MAX_SG_ELEMENTS	65
139  #define CISS_COMMAND_ALIGN	32
140  #define CISS_COMMAND_SG_LENGTH	(sizeof(struct ciss_sg_entry) * CISS_MAX_SG_ELEMENTS)
141  #define CISS_COMMAND_ALLOC_SIZE		(roundup2(sizeof(struct ciss_command) + CISS_COMMAND_SG_LENGTH, CISS_COMMAND_ALIGN))
142  
143  /*
144   * Per-logical-drive data.
145   */
146  struct ciss_ldrive
147  {
148      union ciss_device_address	cl_address;
149      union ciss_device_address	*cl_controller;
150      int				cl_status;
151  #define CISS_LD_NONEXISTENT	0
152  #define CISS_LD_ONLINE		1
153  #define CISS_LD_OFFLINE		2
154  
155      int				cl_update;
156  
157      struct ciss_bmic_id_ldrive	*cl_ldrive;
158      struct ciss_bmic_id_lstatus	*cl_lstatus;
159      struct ciss_ldrive_geometry	cl_geometry;
160  
161      char			cl_name[16];		/* device name */
162  };
163  
164  /*
165   * Per-physical-drive data
166   */
167  struct ciss_pdrive
168  {
169      union ciss_device_address	cp_address;
170      int				cp_online;
171  };
172  
173  #define CISS_PHYSICAL_SHIFT	5
174  #define CISS_PHYSICAL_BASE	(1 << CISS_PHYSICAL_SHIFT)
175  #define CISS_MAX_PHYSTGT	256
176  
177  #define CISS_IS_PHYSICAL(bus)	(bus >= CISS_PHYSICAL_BASE)
178  #define CISS_CAM_TO_PBUS(bus)	(bus - CISS_PHYSICAL_BASE)
179  
180  /*
181   * Per-adapter data
182   */
183  struct ciss_softc
184  {
185      /* bus connections */
186      device_t			ciss_dev;		/* bus attachment */
187      struct cdev			*ciss_dev_t;		/* control device */
188  
189      struct resource		*ciss_regs_resource;	/* register interface window */
190      int				ciss_regs_rid;		/* resource ID */
191      bus_space_handle_t		ciss_regs_bhandle;	/* bus space handle */
192      bus_space_tag_t		ciss_regs_btag;		/* bus space tag */
193  
194      struct resource		*ciss_cfg_resource;	/* config struct interface window */
195      int				ciss_cfg_rid;		/* resource ID */
196      struct ciss_config_table	*ciss_cfg;		/* config table in adapter memory */
197      struct ciss_perf_config	*ciss_perf;		/* config table for the performant */
198      struct ciss_bmic_id_table	*ciss_id;		/* ID table in host memory */
199      u_int32_t			ciss_heartbeat;		/* last heartbeat value */
200      int				ciss_heart_attack;	/* number of times we have seen this value */
201  
202      int				ciss_msi;
203      struct resource		*ciss_irq_resource;	/* interrupt */
204      int				ciss_irq_rid[CISS_MSI_COUNT];		/* resource ID */
205      void			*ciss_intr;		/* interrupt handle */
206  
207      bus_dma_tag_t		ciss_parent_dmat;	/* parent DMA tag */
208      bus_dma_tag_t		ciss_buffer_dmat;	/* data buffer/command DMA tag */
209  
210      u_int32_t			ciss_interrupt_mask;	/* controller interrupt mask bits */
211  
212      uint64_t			*ciss_reply;
213      int				ciss_cycle;
214      int				ciss_rqidx;
215      bus_dma_tag_t		ciss_reply_dmat;
216      bus_dmamap_t		ciss_reply_map;
217      uint32_t			ciss_reply_phys;
218  
219      int				ciss_max_requests;
220      struct ciss_request		ciss_request[CISS_MAX_REQUESTS];	/* requests */
221      void			*ciss_command;		/* command structures */
222      bus_dma_tag_t		ciss_command_dmat;	/* command DMA tag */
223      bus_dmamap_t		ciss_command_map;	/* command DMA map */
224      u_int32_t			ciss_command_phys;	/* command array base address */
225      cr_qhead_t			ciss_free;		/* requests available for reuse */
226      cr_qhead_t			ciss_notify;		/* requests which are defered for processing */
227      struct proc			*ciss_notify_thread;
228  
229      struct callout		ciss_periodic;		/* periodic event handling */
230      struct ciss_request		*ciss_periodic_notify;	/* notify callback request */
231  
232      struct mtx			ciss_mtx;
233      struct ciss_ldrive		**ciss_logical;
234      struct ciss_pdrive		**ciss_physical;
235      union ciss_device_address	*ciss_controllers;	/* controller address */
236      int				ciss_max_bus_number;	/* maximum bus number */
237      int				ciss_max_logical_bus;
238      int				ciss_max_physical_bus;
239      int				ciss_max_physical_target;	/* highest physical target number */
240  
241      struct cam_devq		*ciss_cam_devq;
242      struct cam_sim		**ciss_cam_sim;
243  
244      int				ciss_soft_reset;
245  
246      int				ciss_flags;
247  #define CISS_FLAG_NOTIFY_OK	(1<<0)		/* notify command running OK */
248  #define CISS_FLAG_CONTROL_OPEN	(1<<1)		/* control device is open */
249  #define CISS_FLAG_ABORTING	(1<<2)		/* driver is going away */
250  #define CISS_FLAG_RUNNING	(1<<3)		/* driver is running (interrupts usable) */
251  #define CISS_FLAG_BUSY		(1<<4)		/* no free commands */
252  
253  #define CISS_FLAG_FAKE_SYNCH	(1<<16)		/* needs SYNCHRONISE_CACHE faked */
254  #define CISS_FLAG_BMIC_ABORT	(1<<17)		/* use BMIC command to abort Notify on Event */
255  #define CISS_FLAG_THREAD_SHUT	(1<<20)		/* shutdown the kthread */
256  
257      struct ciss_qstat		ciss_qstat[CISSQ_COUNT];	/* queue statistics */
258  };
259  
260  /************************************************************************
261   * Debugging/diagnostic output.
262   */
263  
264  /*
265   * Debugging levels:
266   *  0 - quiet, only emit warnings
267   *  1 - talkative, log major events, but nothing on the I/O path
268   *  2 - noisy, log events on the I/O path
269   *  3 - extremely noisy, log items in loops
270   */
271  #ifdef CISS_DEBUG
272  # define debug(level, fmt, args...)							\
273  	do {										\
274  	    if (level <= CISS_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);	\
275  	} while(0)
276  # define debug_called(level)						\
277  	do {								\
278  	    if (level <= CISS_DEBUG) printf("%s: called\n", __func__);	\
279  	} while(0)
280  # define debug_struct(s)		printf("  SIZE %s: %zu\n", #s, sizeof(struct s))
281  # define debug_union(s)			printf("  SIZE %s: %zu\n", #s, sizeof(union s))
282  # define debug_type(s)			printf("  SIZE %s: %zu\n", #s, sizeof(s))
283  # define debug_field(s, f)		printf("  OFFSET %s.%s: %d\n", #s, #f, ((int)&(((struct s *)0)->f)))
284  # define debug_const(c)			printf("  CONST %s %jd/0x%jx\n", #c, (intmax_t)c, (intmax_t)c);
285  #else
286  # define debug(level, fmt, args...)
287  # define debug_called(level)
288  # define debug_struct(s)
289  # define debug_union(s)
290  # define debug_type(s)
291  # define debug_field(s, f)
292  # define debug_const(c)
293  #endif
294  
295  #define ciss_printf(sc, fmt, args...)	device_printf(sc->ciss_dev, fmt , ##args)
296  
297  /************************************************************************
298   * Queue primitives
299   */
300  
301  #define CISSQ_ADD(sc, qname)					\
302  	do {							\
303  	    struct ciss_qstat *qs = &(sc)->ciss_qstat[qname];	\
304  								\
305  	    qs->q_length++;					\
306  	    if (qs->q_length > qs->q_max)			\
307  		qs->q_max = qs->q_length;			\
308  	} while(0)
309  
310  #define CISSQ_REMOVE(sc, qname)    (sc)->ciss_qstat[qname].q_length--
311  #define CISSQ_INIT(sc, qname)			\
312  	do {					\
313  	    sc->ciss_qstat[qname].q_length = 0;	\
314  	    sc->ciss_qstat[qname].q_max = 0;	\
315  	} while(0)
316  
317  #define CISSQ_REQUEST_QUEUE(name, index)				\
318  static __inline void							\
319  ciss_initq_ ## name (struct ciss_softc *sc)				\
320  {									\
321      STAILQ_INIT(&sc->ciss_ ## name);					\
322      CISSQ_INIT(sc, index);						\
323  }									\
324  static __inline void							\
325  ciss_enqueue_ ## name (struct ciss_request *cr)				\
326  {									\
327  									\
328      STAILQ_INSERT_TAIL(&cr->cr_sc->ciss_ ## name, cr, cr_link);		\
329      CISSQ_ADD(cr->cr_sc, index);					\
330      cr->cr_onq = index;							\
331  }									\
332  static __inline void							\
333  ciss_requeue_ ## name (struct ciss_request *cr)				\
334  {									\
335  									\
336      STAILQ_INSERT_HEAD(&cr->cr_sc->ciss_ ## name, cr, cr_link);		\
337      CISSQ_ADD(cr->cr_sc, index);					\
338      cr->cr_onq = index;							\
339  }									\
340  static __inline struct ciss_request *					\
341  ciss_dequeue_ ## name (struct ciss_softc *sc)				\
342  {									\
343      struct ciss_request	*cr;						\
344  									\
345      if ((cr = STAILQ_FIRST(&sc->ciss_ ## name)) != NULL) {		\
346  	STAILQ_REMOVE_HEAD(&sc->ciss_ ## name, cr_link);		\
347  	CISSQ_REMOVE(sc, index);					\
348  	cr->cr_onq = -1;						\
349      }									\
350      return(cr);								\
351  }									\
352  struct hack
353  
354  CISSQ_REQUEST_QUEUE(free, CISSQ_FREE);
355  CISSQ_REQUEST_QUEUE(notify, CISSQ_NOTIFY);
356  
357  static __inline void
ciss_enqueue_complete(struct ciss_request * ac,cr_qhead_t * head)358  ciss_enqueue_complete(struct ciss_request *ac, cr_qhead_t *head)
359  {
360  
361      STAILQ_INSERT_TAIL(head, ac, cr_link);
362  }
363  
364  static __inline struct ciss_request *
ciss_dequeue_complete(struct ciss_softc * sc,cr_qhead_t * head)365  ciss_dequeue_complete(struct ciss_softc *sc, cr_qhead_t *head)
366  {
367      struct ciss_request  *ac;
368  
369      if ((ac = STAILQ_FIRST(head)) != NULL)
370          STAILQ_REMOVE_HEAD(head, cr_link);
371      return(ac);
372  }
373  
374  /********************************************************************************
375   * space-fill a character string
376   */
377  static __inline void
padstr(char * targ,const char * src,int len)378  padstr(char *targ, const char *src, int len)
379  {
380      while (len-- > 0) {
381  	if (*src != 0) {
382  	    *targ++ = *src++;
383  	} else {
384  	    *targ++ = ' ';
385  	}
386      }
387  }
388  
389  #define ciss_report_request(a, b, c)	\
390  	_ciss_report_request(a, b, c, __FUNCTION__)
391