Change the kernel dev_t, representing a pointer to a specinfo structure,
[dragonfly.git] / sys / dev / raid / twe / twevar.h
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 2000 Michael Smith
a062d8a7
HP
3 * Copyright (c) 2003 Paul Saab
4 * Copyright (c) 2003 Vinod Kashyap
984263bc
MD
5 * Copyright (c) 2000 BSDi
6 * All rights reserved.
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, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
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
21 * FOR 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 *
a062d8a7 29 * $FreeBSD: src/sys/dev/twe/twevar.h,v 1.1.2.8 2004/06/11 18:57:32 vkashyap Exp $
b13267a5 30 * $DragonFly: src/sys/dev/raid/twe/twevar.h,v 1.7 2006/09/10 01:26:36 dillon Exp $
984263bc
MD
31 */
32
a062d8a7
HP
33#define TWE_DRIVER_VERSION_STRING "1.40.01.002"
34#define TWE_CDEV_MAJOR 146
35#define TWED_CDEV_MAJOR 147
36
37
984263bc
MD
38#ifdef TWE_DEBUG
39#define debug(level, fmt, args...) \
40 do { \
41 if (level <= TWE_DEBUG) printf("%s: " fmt "\n", __func__ , ##args); \
42 } while(0)
43#define debug_called(level) \
44 do { \
45 if (level <= TWE_DEBUG) printf("%s: called\n", __func__); \
46 } while(0)
47#else
48#define debug(level, fmt, args...)
49#define debug_called(level)
50#endif
51
52/*
53 * Structure describing a logical unit as attached to the controller
54 */
55struct twe_drive
56{
57 /* unit properties */
58 u_int32_t td_size;
59 int td_cylinders;
60 int td_heads;
61 int td_sectors;
a062d8a7
HP
62 int td_sys_unit; /* Unit #, as seen by the system
63 (the 0 in twed0, the 1 in twed1 etc.) */
64 int td_twe_unit; /* Unit #, as seen by us, and our ctlr
65 (index into sc->twe_drive[]) */
984263bc
MD
66
67 /* unit state and type */
68 u_int8_t td_state;
69 u_int8_t td_type;
70
71 /* handle for attached driver */
72 device_t td_disk;
73};
74
a062d8a7
HP
75/*
76 * Disk device softc
77 */
78struct twed_softc
79{
80 device_t twed_dev;
b13267a5 81 cdev_t twed_dev_t;
a062d8a7
HP
82 struct twe_softc *twed_controller; /* parent device softc */
83 struct twe_drive *twed_drive; /* drive data in parent softc */
84 struct disk twed_disk; /* generic disk handle */
85 struct devstat twed_stats; /* accounting */
86 struct disklabel twed_label; /* synthetic label */
87 int twed_flags;
88#define TWED_OPEN (1<<0) /* drive is open (can't shut down) */
89};
90
984263bc
MD
91/*
92 * Per-command control structure.
93 *
94 * Note that due to alignment constraints on the tc_command field, this *must* be 64-byte aligned.
95 * We achieve this by placing the command at the beginning of the structure, and using malloc()
96 * to allocate each structure.
97 */
98struct twe_request
99{
100 /* controller command */
101 TWE_Command tr_command; /* command as submitted to controller */
102
103 /* command payload */
104 void *tr_data; /* data buffer */
105 void *tr_realdata; /* copy of real data buffer pointer for alignment fixup */
106 size_t tr_length;
107
108 TAILQ_ENTRY(twe_request) tr_link; /* list linkage */
109 struct twe_softc *tr_sc; /* controller that owns us */
110 int tr_status; /* command status */
111#define TWE_CMD_SETUP 0 /* being assembled */
112#define TWE_CMD_BUSY 1 /* submitted to controller */
113#define TWE_CMD_COMPLETE 2 /* completed by controller (maybe with error) */
a062d8a7 114#define TWE_CMD_ERROR 3 /* encountered error, even before submission to controller */
984263bc
MD
115 int tr_flags;
116#define TWE_CMD_DATAIN (1<<0)
117#define TWE_CMD_DATAOUT (1<<1)
118#define TWE_CMD_ALIGNBUF (1<<2) /* data in bio is misaligned, have to copy to/from private buffer */
119#define TWE_CMD_SLEEPER (1<<3) /* owner is sleeping on this command */
a062d8a7
HP
120#define TWE_CMD_MAPPED (1<<4) /* cmd has been mapped */
121#define TWE_CMD_IN_PROGRESS (1<<5) /* bus_dmamap_load returned EINPROGRESS */
984263bc
MD
122 void (* tr_complete)(struct twe_request *tr); /* completion handler */
123 void *tr_private; /* submitter-private data or wait channel */
124
125 TWE_PLATFORM_REQUEST /* platform-specific request elements */
126};
127
128/*
129 * Per-controller state.
130 */
131struct twe_softc
132{
133 /* controller queues and arrays */
134 TAILQ_HEAD(, twe_request) twe_free; /* command structures available for reuse */
135 twe_bioq twe_bioq; /* outstanding I/O operations */
136 TAILQ_HEAD(, twe_request) twe_ready; /* requests ready for the controller */
137 TAILQ_HEAD(, twe_request) twe_busy; /* requests busy in the controller */
138 TAILQ_HEAD(, twe_request) twe_complete; /* active commands (busy or waiting for completion) */
139 struct twe_request *twe_lookup[TWE_Q_LENGTH]; /* commands indexed by request ID */
140 struct twe_drive twe_drive[TWE_MAX_UNITS]; /* attached drives */
141
142 /* asynchronous event handling */
143 u_int16_t twe_aen_queue[TWE_Q_LENGTH]; /* AENs queued for userland tool(s) */
144 int twe_aen_head, twe_aen_tail; /* ringbuffer pointers for AEN queue */
145 int twe_wait_aen; /* wait-for-aen notification */
146
147 /* controller status */
148 int twe_state;
149#define TWE_STATE_INTEN (1<<0) /* interrupts have been enabled */
150#define TWE_STATE_SHUTDOWN (1<<1) /* controller is shut down */
151#define TWE_STATE_OPEN (1<<2) /* control device is open */
152#define TWE_STATE_SUSPEND (1<<3) /* controller is suspended */
a062d8a7
HP
153#define TWE_STATE_FRZN (1<<4) /* got EINPROGRESS */
154#define TWE_STATE_CTLR_BUSY (1<<5) /* controller cmd queue full */
984263bc
MD
155 int twe_host_id;
156 struct twe_qstat twe_qstat[TWEQ_COUNT]; /* queue statistics */
157
158 TWE_PLATFORM_SOFTC /* platform-specific softc elements */
159};
160
161/*
162 * Interface betwen driver core and platform-dependant code.
163 */
164extern int twe_setup(struct twe_softc *sc); /* do early driver/controller setup */
165extern void twe_init(struct twe_softc *sc); /* init controller */
166extern void twe_deinit(struct twe_softc *sc); /* stop controller */
167extern void twe_intr(struct twe_softc *sc); /* hardware interrupt signalled */
168extern void twe_startio(struct twe_softc *sc);
a062d8a7 169extern int twe_start(struct twe_request *tr);
984263bc
MD
170extern int twe_dump_blocks(struct twe_softc *sc, int unit, /* crashdump block write */
171 u_int32_t lba, void *data, int nblks);
172extern int twe_ioctl(struct twe_softc *sc, int cmd,
173 void *addr); /* handle user request */
174extern void twe_describe_controller(struct twe_softc *sc); /* print controller info */
a062d8a7 175extern char *twe_describe_code(struct twe_code_lookup *table, u_int32_t code);
984263bc
MD
176extern void twe_print_controller(struct twe_softc *sc);
177extern void twe_enable_interrupts(struct twe_softc *sc); /* enable controller interrupts */
178extern void twe_disable_interrupts(struct twe_softc *sc); /* disable controller interrupts */
179
a062d8a7
HP
180extern int twe_attach_drive(struct twe_softc *sc,
181 struct twe_drive *dr); /* attach drive when found in twe_init */
182extern int twe_detach_drive(struct twe_softc *sc,
0a62b1be 183 int unit); /* detach drive */
984263bc
MD
184extern void twe_clear_pci_parity_error(struct twe_softc *sc);
185extern void twe_clear_pci_abort(struct twe_softc *sc);
186extern void twed_intr(twe_bio *bp); /* return bio from core */
a062d8a7
HP
187extern struct twe_request *twe_allocate_request(struct twe_softc *sc);/* allocate request structure */
188extern int twe_map_request(struct twe_request *tr); /* make request visible to controller, do s/g */
984263bc
MD
189extern void twe_unmap_request(struct twe_request *tr); /* cleanup after transfer, unmap */
190
191/********************************************************************************
192 * Queue primitives
193 */
194#define TWEQ_ADD(sc, qname) \
195 do { \
196 struct twe_qstat *qs = &(sc)->twe_qstat[qname]; \
197 \
198 qs->q_length++; \
199 if (qs->q_length > qs->q_max) \
200 qs->q_max = qs->q_length; \
201 } while(0)
202
a062d8a7
HP
203#define TWEQ_REMOVE(sc, qname) \
204 do { \
205 struct twe_qstat *qs = &(sc)->twe_qstat[qname]; \
206 \
207 qs->q_length--; \
208 if (qs->q_length < qs->q_min) \
209 qs->q_min = qs->q_length; \
210 } while(0)
211
212#define TWEQ_INIT(sc, qname) \
213 do { \
214 sc->twe_qstat[qname].q_length = 0; \
215 sc->twe_qstat[qname].q_max = 0; \
216 sc->twe_qstat[qname].q_min = 0xFFFFFFFF; \
984263bc
MD
217 } while(0)
218
219
220#define TWEQ_REQUEST_QUEUE(name, index) \
221static __inline void \
222twe_initq_ ## name (struct twe_softc *sc) \
223{ \
224 TAILQ_INIT(&sc->twe_ ## name); \
225 TWEQ_INIT(sc, index); \
226} \
227static __inline void \
228twe_enqueue_ ## name (struct twe_request *tr) \
229{ \
5eb77fd5 230 crit_enter(); \
984263bc
MD
231 TAILQ_INSERT_TAIL(&tr->tr_sc->twe_ ## name, tr, tr_link); \
232 TWEQ_ADD(tr->tr_sc, index); \
5eb77fd5 233 crit_exit(); \
984263bc
MD
234} \
235static __inline void \
236twe_requeue_ ## name (struct twe_request *tr) \
237{ \
5eb77fd5 238 crit_enter(); \
984263bc
MD
239 TAILQ_INSERT_HEAD(&tr->tr_sc->twe_ ## name, tr, tr_link); \
240 TWEQ_ADD(tr->tr_sc, index); \
5eb77fd5 241 crit_exit(); \
984263bc
MD
242} \
243static __inline struct twe_request * \
244twe_dequeue_ ## name (struct twe_softc *sc) \
245{ \
246 struct twe_request *tr; \
984263bc 247 \
5eb77fd5 248 crit_enter(); \
984263bc
MD
249 if ((tr = TAILQ_FIRST(&sc->twe_ ## name)) != NULL) { \
250 TAILQ_REMOVE(&sc->twe_ ## name, tr, tr_link); \
251 TWEQ_REMOVE(sc, index); \
252 } \
5eb77fd5 253 crit_exit(); \
984263bc
MD
254 return(tr); \
255} \
256static __inline void \
257twe_remove_ ## name (struct twe_request *tr) \
258{ \
5eb77fd5 259 crit_enter(); \
984263bc
MD
260 TAILQ_REMOVE(&tr->tr_sc->twe_ ## name, tr, tr_link); \
261 TWEQ_REMOVE(tr->tr_sc, index); \
5eb77fd5 262 crit_exit(); \
984263bc
MD
263}
264
265TWEQ_REQUEST_QUEUE(free, TWEQ_FREE)
266TWEQ_REQUEST_QUEUE(ready, TWEQ_READY)
267TWEQ_REQUEST_QUEUE(busy, TWEQ_BUSY)
268TWEQ_REQUEST_QUEUE(complete, TWEQ_COMPLETE)
269
270
271/*
272 * outstanding bio queue
273 */
274static __inline void
275twe_initq_bio(struct twe_softc *sc)
276{
81b5c339 277 bioq_init(&sc->twe_bioq);
984263bc
MD
278 TWEQ_INIT(sc, TWEQ_BIO);
279}
280
281static __inline void
81b5c339 282twe_enqueue_bio(struct twe_softc *sc, struct bio *bio)
984263bc 283{
5eb77fd5 284 crit_enter();
81b5c339 285 bioq_insert_tail(&sc->twe_bioq, bio);
984263bc 286 TWEQ_ADD(sc, TWEQ_BIO);
5eb77fd5 287 crit_exit();
984263bc
MD
288}
289
81b5c339
MD
290static __inline
291struct bio *
984263bc
MD
292twe_dequeue_bio(struct twe_softc *sc)
293{
81b5c339 294 struct bio *bio;
984263bc 295
5eb77fd5 296 crit_enter();
81b5c339
MD
297 if ((bio = bioq_first(&sc->twe_bioq)) != NULL) {
298 bioq_remove(&sc->twe_bioq, bio);
984263bc
MD
299 TWEQ_REMOVE(sc, TWEQ_BIO);
300 }
5eb77fd5 301 crit_exit();
81b5c339 302 return(bio);
984263bc 303}