Deleted Added
full compact
aac.c (82856) aac.c (83114)
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

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 *
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

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 *
29 * $FreeBSD: head/sys/dev/aac/aac.c 82856 2001-09-03 07:50:14Z scottl $
29 * $FreeBSD: head/sys/dev/aac/aac.c 83114 2001-09-05 20:43:02Z scottl $
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

--- 23 unchanged lines hidden (view full) ---

61#include <dev/aac/aacreg.h>
62#include <dev/aac/aac_ioctl.h>
63#include <dev/aac/aacvar.h>
64#include <dev/aac/aac_tables.h>
65
66devclass_t aac_devclass;
67
68static void aac_startup(void *arg);
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

--- 23 unchanged lines hidden (view full) ---

61#include <dev/aac/aacreg.h>
62#include <dev/aac/aac_ioctl.h>
63#include <dev/aac/aacvar.h>
64#include <dev/aac/aac_tables.h>
65
66devclass_t aac_devclass;
67
68static void aac_startup(void *arg);
69static void aac_add_container(struct aac_softc *sc,
70 struct aac_mntinforesponse *mir, int f);
69
70/* Command Processing */
71static void aac_startio(struct aac_softc *sc);
72static void aac_timeout(struct aac_softc *sc);
73static int aac_start(struct aac_command *cm);
74static void aac_complete(void *context, int pending);
75static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
76static void aac_bio_complete(struct aac_command *cm);

--- 21 unchanged lines hidden (view full) ---

98 u_int32_t arg3, u_int32_t *sp);
99static int aac_sync_fib(struct aac_softc *sc, u_int32_t command,
100 u_int32_t xferstate, void *data,
101 u_int16_t datasize, void *result,
102 u_int16_t *resultsize);
103static int aac_enqueue_fib(struct aac_softc *sc, int queue,
104 struct aac_command *cm);
105static int aac_dequeue_fib(struct aac_softc *sc, int queue,
71
72/* Command Processing */
73static void aac_startio(struct aac_softc *sc);
74static void aac_timeout(struct aac_softc *sc);
75static int aac_start(struct aac_command *cm);
76static void aac_complete(void *context, int pending);
77static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
78static void aac_bio_complete(struct aac_command *cm);

--- 21 unchanged lines hidden (view full) ---

100 u_int32_t arg3, u_int32_t *sp);
101static int aac_sync_fib(struct aac_softc *sc, u_int32_t command,
102 u_int32_t xferstate, void *data,
103 u_int16_t datasize, void *result,
104 u_int16_t *resultsize);
105static int aac_enqueue_fib(struct aac_softc *sc, int queue,
106 struct aac_command *cm);
107static int aac_dequeue_fib(struct aac_softc *sc, int queue,
106 u_int32_t *fib_size,
107 struct aac_fib **fib_addr);
108 u_int32_t *fib_size, struct aac_fib **fib_addr);
108static int aac_enqueue_response(struct aac_softc *sc, int queue,
109 struct aac_fib *fib);
110
111/* StrongARM interface */
112static int aac_sa_get_fwstatus(struct aac_softc *sc);
113static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
114static int aac_sa_get_istatus(struct aac_softc *sc);
115static void aac_sa_clear_istatus(struct aac_softc *sc, int mask);
116static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
117 u_int32_t arg0, u_int32_t arg1,
118 u_int32_t arg2, u_int32_t arg3);
119static int aac_sa_get_mailboxstatus(struct aac_softc *sc);
120static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
121
122struct aac_interface aac_sa_interface = {
109static int aac_enqueue_response(struct aac_softc *sc, int queue,
110 struct aac_fib *fib);
111
112/* StrongARM interface */
113static int aac_sa_get_fwstatus(struct aac_softc *sc);
114static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
115static int aac_sa_get_istatus(struct aac_softc *sc);
116static void aac_sa_clear_istatus(struct aac_softc *sc, int mask);
117static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
118 u_int32_t arg0, u_int32_t arg1,
119 u_int32_t arg2, u_int32_t arg3);
120static int aac_sa_get_mailboxstatus(struct aac_softc *sc);
121static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
122
123struct aac_interface aac_sa_interface = {
123 aac_sa_get_fwstatus,
124 aac_sa_qnotify,
125 aac_sa_get_istatus,
126 aac_sa_clear_istatus,
127 aac_sa_set_mailbox,
128 aac_sa_get_mailboxstatus,
129 aac_sa_set_interrupts
124 aac_sa_get_fwstatus,
125 aac_sa_qnotify,
126 aac_sa_get_istatus,
127 aac_sa_clear_istatus,
128 aac_sa_set_mailbox,
129 aac_sa_get_mailboxstatus,
130 aac_sa_set_interrupts
130};
131
131};
132
132/* i960Rx interface */
133/* i960Rx interface */
133static int aac_rx_get_fwstatus(struct aac_softc *sc);
134static void aac_rx_qnotify(struct aac_softc *sc, int qbit);
135static int aac_rx_get_istatus(struct aac_softc *sc);
136static void aac_rx_clear_istatus(struct aac_softc *sc, int mask);
137static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
138 u_int32_t arg0, u_int32_t arg1,
139 u_int32_t arg2, u_int32_t arg3);
140static int aac_rx_get_mailboxstatus(struct aac_softc *sc);
141static void aac_rx_set_interrupts(struct aac_softc *sc, int enable);
142
143struct aac_interface aac_rx_interface = {
134static int aac_rx_get_fwstatus(struct aac_softc *sc);
135static void aac_rx_qnotify(struct aac_softc *sc, int qbit);
136static int aac_rx_get_istatus(struct aac_softc *sc);
137static void aac_rx_clear_istatus(struct aac_softc *sc, int mask);
138static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
139 u_int32_t arg0, u_int32_t arg1,
140 u_int32_t arg2, u_int32_t arg3);
141static int aac_rx_get_mailboxstatus(struct aac_softc *sc);
142static void aac_rx_set_interrupts(struct aac_softc *sc, int enable);
143
144struct aac_interface aac_rx_interface = {
144 aac_rx_get_fwstatus,
145 aac_rx_qnotify,
146 aac_rx_get_istatus,
147 aac_rx_clear_istatus,
148 aac_rx_set_mailbox,
149 aac_rx_get_mailboxstatus,
150 aac_rx_set_interrupts
145 aac_rx_get_fwstatus,
146 aac_rx_qnotify,
147 aac_rx_get_istatus,
148 aac_rx_clear_istatus,
149 aac_rx_set_mailbox,
150 aac_rx_get_mailboxstatus,
151 aac_rx_set_interrupts
151};
152
153/* Debugging and Diagnostics */
154static void aac_describe_controller(struct aac_softc *sc);
155static char *aac_describe_code(struct aac_code_lookup *table,
156 u_int32_t code);
157
158/* Management Interface */
159static d_open_t aac_open;
160static d_close_t aac_close;
161static d_ioctl_t aac_ioctl;
162static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
163static void aac_handle_aif(struct aac_softc *sc,
152};
153
154/* Debugging and Diagnostics */
155static void aac_describe_controller(struct aac_softc *sc);
156static char *aac_describe_code(struct aac_code_lookup *table,
157 u_int32_t code);
158
159/* Management Interface */
160static d_open_t aac_open;
161static d_close_t aac_close;
162static d_ioctl_t aac_ioctl;
163static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
164static void aac_handle_aif(struct aac_softc *sc,
164 struct aac_fib *fib);
165 struct aac_fib *fib);
165static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
166static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
167static int aac_return_aif(struct aac_softc *sc, caddr_t uptr);
168static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
169
170#define AAC_CDEV_MAJOR 150
171
172static struct cdevsw aac_cdevsw = {
166static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
167static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
168static int aac_return_aif(struct aac_softc *sc, caddr_t uptr);
169static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
170
171#define AAC_CDEV_MAJOR 150
172
173static struct cdevsw aac_cdevsw = {
173 aac_open, /* open */
174 aac_close, /* close */
175 noread, /* read */
176 nowrite, /* write */
177 aac_ioctl, /* ioctl */
178 nopoll, /* poll */
179 nommap, /* mmap */
180 nostrategy, /* strategy */
181 "aac", /* name */
182 AAC_CDEV_MAJOR, /* major */
183 nodump, /* dump */
184 nopsize, /* psize */
185 0, /* flags */
174 aac_open, /* open */
175 aac_close, /* close */
176 noread, /* read */
177 nowrite, /* write */
178 aac_ioctl, /* ioctl */
179 nopoll, /* poll */
180 nommap, /* mmap */
181 nostrategy, /* strategy */
182 "aac", /* name */
183 AAC_CDEV_MAJOR, /* major */
184 nodump, /* dump */
185 nopsize, /* psize */
186 0, /* flags */
186#if __FreeBSD_version < 500005
187#if __FreeBSD_version < 500005
187 -1, /* bmaj */
188 -1, /* bmaj */
188#endif
189};
190
191MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
192
193/* sysctl node */
194SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
195
189#endif
190};
191
192MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
193
194/* sysctl node */
195SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
196
196/******************************************************************************
197 ******************************************************************************
198 Device Interface
199 ******************************************************************************
200 ******************************************************************************/
197/*
198 * Device Interface
199 */
201
200
202/******************************************************************************
201/*
203 * Initialise the controller and softc
204 */
205int
206aac_attach(struct aac_softc *sc)
207{
202 * Initialise the controller and softc
203 */
204int
205aac_attach(struct aac_softc *sc)
206{
208 int error, unit;
207 int error, unit;
209
208
210 debug_called(1);
209 debug_called(1);
211
210
212 /*
213 * Initialise per-controller queues.
214 */
215 aac_initq_free(sc);
216 aac_initq_ready(sc);
217 aac_initq_busy(sc);
218 aac_initq_complete(sc);
219 aac_initq_bio(sc);
211 /*
212 * Initialise per-controller queues.
213 */
214 aac_initq_free(sc);
215 aac_initq_ready(sc);
216 aac_initq_busy(sc);
217 aac_initq_complete(sc);
218 aac_initq_bio(sc);
220
221#if __FreeBSD_version >= 500005
219
220#if __FreeBSD_version >= 500005
222 /*
223 * Initialise command-completion task.
224 */
225 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
221 /*
222 * Initialise command-completion task.
223 */
224 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
226#endif
227
225#endif
226
228 /* disable interrupts before we enable anything */
229 AAC_MASK_INTERRUPTS(sc);
227 /* disable interrupts before we enable anything */
228 AAC_MASK_INTERRUPTS(sc);
230
229
231 /* mark controller as suspended until we get ourselves organised */
232 sc->aac_state |= AAC_STATE_SUSPEND;
230 /* mark controller as suspended until we get ourselves organised */
231 sc->aac_state |= AAC_STATE_SUSPEND;
233
232
234 /*
235 * Allocate command structures.
236 */
237 if ((error = aac_alloc_commands(sc)) != 0)
238 return(error);
233 /*
234 * Allocate command structures.
235 */
236 if ((error = aac_alloc_commands(sc)) != 0)
237 return(error);
239
238
240 /*
241 * Initialise the adapter.
242 */
243 if ((error = aac_init(sc)) != 0)
244 return(error);
239 /*
240 * Initialise the adapter.
241 */
242 if ((error = aac_init(sc)) != 0)
243 return(error);
245
244
246 /*
247 * Print a little information about the controller.
248 */
249 aac_describe_controller(sc);
245 /*
246 * Print a little information about the controller.
247 */
248 aac_describe_controller(sc);
250
249
251 /*
252 * Register to probe our containers later.
253 */
254 TAILQ_INIT(&sc->aac_container_tqh);
255 AAC_LOCK_INIT(&sc->aac_container_lock);
250 /*
251 * Register to probe our containers later.
252 */
253 TAILQ_INIT(&sc->aac_container_tqh);
254 AAC_LOCK_INIT(&sc->aac_container_lock);
256
255
257 sc->aac_ich.ich_func = aac_startup;
258 sc->aac_ich.ich_arg = sc;
259 if (config_intrhook_establish(&sc->aac_ich) != 0) {
260 device_printf(sc->aac_dev, "can't establish configuration hook\n");
261 return(ENXIO);
262 }
256 sc->aac_ich.ich_func = aac_startup;
257 sc->aac_ich.ich_arg = sc;
258 if (config_intrhook_establish(&sc->aac_ich) != 0) {
259 device_printf(sc->aac_dev,
260 "can't establish configuration hook\n");
261 return(ENXIO);
262 }
263
263
264 /*
265 * Make the control device.
266 */
267 unit = device_get_unit(sc->aac_dev);
268 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_WHEEL, 0644,
269 "aac%d", unit);
264 /*
265 * Make the control device.
266 */
267 unit = device_get_unit(sc->aac_dev);
268 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_WHEEL, 0644,
269 "aac%d", unit);
270#if __FreeBSD_version > 500005
270#if __FreeBSD_version > 500005
271 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
272 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
271 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
272 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
273#endif
273#endif
274 sc->aac_dev_t->si_drv1 = sc;
274 sc->aac_dev_t->si_drv1 = sc;
275
275
276 /* Create the AIF thread */
276 /* Create the AIF thread */
277#if __FreeBSD_version > 500005
277#if __FreeBSD_version > 500005
278 if (kthread_create((void(*)(void *))aac_host_command, sc, &sc->aifthread,
279 0, "aac%daif", unit))
278 if (kthread_create((void(*)(void *))aac_host_command, sc,
279 &sc->aifthread, 0, "aac%daif", unit))
280#else
280#else
281 if (kthread_create((void(*)(void *))aac_host_command, sc, &sc->aifthread,
282 "aac%daif", unit))
281 if (kthread_create((void(*)(void *))aac_host_command, sc,
282 &sc->aifthread, "aac%daif", unit))
283#endif
283#endif
284 panic("Could not create AIF thread\n");
284 panic("Could not create AIF thread\n");
285
285
286 /* Register the shutdown method to only be called post-dump */
287 if ((EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, sc->aac_dev,
288 SHUTDOWN_PRI_DEFAULT)) == NULL)
286 /* Register the shutdown method to only be called post-dump */
287 if ((EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, sc->aac_dev,
288 SHUTDOWN_PRI_DEFAULT)) == NULL)
289 device_printf(sc->aac_dev, "shutdown event registration failed\n");
290
289 device_printf(sc->aac_dev, "shutdown event registration failed\n");
290
291 return(0);
291 return(0);
292}
293
292}
293
294/******************************************************************************
294/*
295 * Probe for containers, create disks.
296 */
297static void
298aac_startup(void *arg)
299{
295 * Probe for containers, create disks.
296 */
297static void
298aac_startup(void *arg)
299{
300 struct aac_softc *sc = (struct aac_softc *)arg;
301 struct aac_mntinfo mi;
302 struct aac_mntinforesponse mir;
303 struct aac_container *co;
304 device_t child;
305 u_int16_t rsize;
306 int i = 0;
300 struct aac_softc *sc;
301 struct aac_mntinfo mi;
302 struct aac_mntinforesponse mir;
303 u_int16_t rsize;
304 int i = 0;
307
305
308 debug_called(1);
306 debug_called(1);
309
307
310 /* disconnect ourselves from the intrhook chain */
311 config_intrhook_disestablish(&sc->aac_ich);
308 sc = (struct aac_softc *)arg;
312
309
313 /* loop over possible containers */
314 mi.Command = VM_NameServe;
315 mi.MntType = FT_FILESYS;
316 do {
317 /* request information on this container */
318 mi.MntCount = i;
319 rsize = sizeof(mir);
320 if (aac_sync_fib(sc, ContainerCommand, 0, &mi,
321 sizeof(struct aac_mntinfo), &mir, &rsize)) {
322 debug(2, "error probing container %d", i);
323 continue;
324 }
325 /* check response size */
326 if (rsize != sizeof(mir)) {
327 debug(2, "container info response wrong size (%d should be %d)",
328 rsize, sizeof(mir));
329 continue;
330 }
331 /*
332 * Check container volume type for validity. Note that many of the
333 * possible types may never show up.
334 */
335 if ((mir.Status == ST_OK) && (mir.MntTable[0].VolType != CT_NONE)) {
336 MALLOC(co, struct aac_container *, sizeof *co, M_AACBUF, M_NOWAIT);
337 if (co == NULL)
338 panic("Out of memory?!\n");
339 debug(1, "%d: id %x name '%.16s' size %u type %d",
340 i, mir.MntTable[0].ObjectId,
341 mir.MntTable[0].FileSystemName, mir.MntTable[0].Capacity,
342 mir.MntTable[0].VolType);
310 /* disconnect ourselves from the intrhook chain */
311 config_intrhook_disestablish(&sc->aac_ich);
343
312
344 if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL) {
345 device_printf(sc->aac_dev, "device_add_child failed\n");
346 } else {
347 device_set_ivars(child, co);
348 }
349 device_set_desc(child, aac_describe_code(aac_container_types,
350 mir.MntTable[0].VolType));
351 co->co_disk = child;
352 co->co_found = 0;
353 bcopy(&mir.MntTable[0], &co->co_mntobj, sizeof(struct aac_mntobj));
354 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
355 }
356 i++;
357 } while ((i < mir.MntRespCount) && (i < AAC_MAX_CONTAINERS));
313 /* loop over possible containers */
314 mi.Command = VM_NameServe;
315 mi.MntType = FT_FILESYS;
316 do {
317 /* request information on this container */
318 mi.MntCount = i;
319 rsize = sizeof(mir);
320 if (aac_sync_fib(sc, ContainerCommand, 0, &mi,
321 sizeof(struct aac_mntinfo), &mir, &rsize)) {
322 debug(2, "error probing container %d", i);
323 continue;
324 }
325 /* check response size */
326 if (rsize != sizeof(mir)) {
327 debug(2, "container info response wrong size "
328 "(%d should be %d)", rsize, sizeof(mir));
329 continue;
330 }
358
331
359 /* poke the bus to actually attach the child devices */
360 if (bus_generic_attach(sc->aac_dev))
361 device_printf(sc->aac_dev, "bus_generic_attach failed\n");
332 aac_add_container(sc, &mir, 0);
333 i++;
334 } while ((i < mir.MntRespCount) && (i < AAC_MAX_CONTAINERS));
362
335
363 /* mark the controller up */
364 sc->aac_state &= ~AAC_STATE_SUSPEND;
336 /* poke the bus to actually attach the child devices */
337 if (bus_generic_attach(sc->aac_dev))
338 device_printf(sc->aac_dev, "bus_generic_attach failed\n");
365
339
366 /* enable interrupts now */
367 AAC_UNMASK_INTERRUPTS(sc);
340 /* mark the controller up */
341 sc->aac_state &= ~AAC_STATE_SUSPEND;
368
342
369 /* enable the timeout watchdog */
370 timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz);
343 /* enable interrupts now */
344 AAC_UNMASK_INTERRUPTS(sc);
345
346 /* enable the timeout watchdog */
347 timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz);
371}
372
348}
349
373/******************************************************************************
350/*
351 * Create a device to respresent a new container
352 */
353static void
354aac_add_container(struct aac_softc *sc, struct aac_mntinforesponse *mir, int f)
355{
356 struct aac_container *co;
357 device_t child;
358
359 /*
360 * Check container volume type for validity. Note that many of
361 * the possible types may never show up.
362 */
363 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
364 MALLOC(co, struct aac_container *, sizeof *co, M_AACBUF,
365 M_NOWAIT);
366 if (co == NULL)
367 panic("Out of memory?!\n");
368 debug(1, "id %x name '%.16s' size %u type %d",
369 mir->MntTable[0].ObjectId,
370 mir->MntTable[0].FileSystemName,
371 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
372
373 if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL)
374 device_printf(sc->aac_dev, "device_add_child failed\n");
375 else
376 device_set_ivars(child, co);
377 device_set_desc(child, aac_describe_code(aac_container_types,
378 mir->MntTable[0].VolType));
379 co->co_disk = child;
380 co->co_found = f;
381 bcopy(&mir->MntTable[0], &co->co_mntobj,
382 sizeof(struct aac_mntobj));
383 AAC_LOCK_AQUIRE(&sc->aac_container_lock);
384 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
385 AAC_LOCK_RELEASE(&sc->aac_container_lock);
386 }
387}
388
389/*
374 * Free all of the resources associated with (sc)
375 *
376 * Should not be called if the controller is active.
377 */
378void
379aac_free(struct aac_softc *sc)
380{
390 * Free all of the resources associated with (sc)
391 *
392 * Should not be called if the controller is active.
393 */
394void
395aac_free(struct aac_softc *sc)
396{
381 debug_called(1);
397 debug_called(1);
382
398
383 /* remove the control device */
384 if (sc->aac_dev_t != NULL)
385 destroy_dev(sc->aac_dev_t);
399 /* remove the control device */
400 if (sc->aac_dev_t != NULL)
401 destroy_dev(sc->aac_dev_t);
386
402
387 /* throw away any FIB buffers, discard the FIB DMA tag */
388 if (sc->aac_fibs != NULL)
389 aac_free_commands(sc);
390 if (sc->aac_fib_dmat)
391 bus_dma_tag_destroy(sc->aac_fib_dmat);
403 /* throw away any FIB buffers, discard the FIB DMA tag */
404 if (sc->aac_fibs != NULL)
405 aac_free_commands(sc);
406 if (sc->aac_fib_dmat)
407 bus_dma_tag_destroy(sc->aac_fib_dmat);
392
408
393 /* destroy the common area */
394 if (sc->aac_common) {
395 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
396 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
397 sc->aac_common_dmamap);
398 }
399 if (sc->aac_common_dmat)
400 bus_dma_tag_destroy(sc->aac_common_dmat);
409 /* destroy the common area */
410 if (sc->aac_common) {
411 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
412 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
413 sc->aac_common_dmamap);
414 }
415 if (sc->aac_common_dmat)
416 bus_dma_tag_destroy(sc->aac_common_dmat);
401
417
402 /* disconnect the interrupt handler */
403 if (sc->aac_intr)
404 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
405 if (sc->aac_irq != NULL)
406 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
407 sc->aac_irq);
418 /* disconnect the interrupt handler */
419 if (sc->aac_intr)
420 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
421 if (sc->aac_irq != NULL)
422 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
423 sc->aac_irq);
408
424
409 /* destroy data-transfer DMA tag */
410 if (sc->aac_buffer_dmat)
411 bus_dma_tag_destroy(sc->aac_buffer_dmat);
425 /* destroy data-transfer DMA tag */
426 if (sc->aac_buffer_dmat)
427 bus_dma_tag_destroy(sc->aac_buffer_dmat);
412
428
413 /* destroy the parent DMA tag */
414 if (sc->aac_parent_dmat)
415 bus_dma_tag_destroy(sc->aac_parent_dmat);
429 /* destroy the parent DMA tag */
430 if (sc->aac_parent_dmat)
431 bus_dma_tag_destroy(sc->aac_parent_dmat);
416
432
417 /* release the register window mapping */
418 if (sc->aac_regs_resource != NULL)
419 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, sc->aac_regs_rid,
420 sc->aac_regs_resource);
433 /* release the register window mapping */
434 if (sc->aac_regs_resource != NULL)
435 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
436 sc->aac_regs_rid, sc->aac_regs_resource);
421}
422
437}
438
423/******************************************************************************
439/*
424 * Disconnect from the controller completely, in preparation for unload.
425 */
426int
427aac_detach(device_t dev)
428{
440 * Disconnect from the controller completely, in preparation for unload.
441 */
442int
443aac_detach(device_t dev)
444{
429 struct aac_softc *sc = device_get_softc(dev);
445 struct aac_softc *sc;
430#if AAC_BROKEN
446#if AAC_BROKEN
431 int error;
447 int error;
432#endif
433
448#endif
449
434 debug_called(1);
450 debug_called(1);
435
451
436 if (sc->aac_state & AAC_STATE_OPEN)
452 sc = device_get_softc(dev);
453
454 if (sc->aac_state & AAC_STATE_OPEN)
437 return(EBUSY);
438
439#if AAC_BROKEN
455 return(EBUSY);
456
457#if AAC_BROKEN
440 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
441 sc->aifflags |= AAC_AIFFLAGS_EXIT;
442 wakeup(sc->aifthread);
443 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
444 }
458 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
459 sc->aifflags |= AAC_AIFFLAGS_EXIT;
460 wakeup(sc->aifthread);
461 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
462 }
445
463
446 if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
447 panic("Cannot shutdown AIF thread\n");
464 if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
465 panic("Cannot shutdown AIF thread\n");
448
466
449 if ((error = aac_shutdown(dev)))
450 return(error);
467 if ((error = aac_shutdown(dev)))
468 return(error);
451
469
452 aac_free(sc);
470 aac_free(sc);
453
471
454 return(0);
472 return(0);
455#else
473#else
456 return (EBUSY);
474 return (EBUSY);
457#endif
458}
459
475#endif
476}
477
460/******************************************************************************
478/*
461 * Bring the controller down to a dormant state and detach all child devices.
462 *
463 * This function is called before detach or system shutdown.
464 *
465 * Note that we can assume that the bioq on the controller is empty, as we won't
466 * allow shutdown if any device is open.
467 */
468int
469aac_shutdown(device_t dev)
470{
479 * Bring the controller down to a dormant state and detach all child devices.
480 *
481 * This function is called before detach or system shutdown.
482 *
483 * Note that we can assume that the bioq on the controller is empty, as we won't
484 * allow shutdown if any device is open.
485 */
486int
487aac_shutdown(device_t dev)
488{
471 struct aac_softc *sc = device_get_softc(dev);
472 struct aac_close_command cc;
473 int s, i;
489 struct aac_softc *sc;
490 struct aac_close_command cc;
491 int s, i;
474
492
475 debug_called(1);
493 debug_called(1);
476
494
477 s = splbio();
495 sc = device_get_softc(dev);
478
496
479 sc->aac_state |= AAC_STATE_SUSPEND;
497 s = splbio();
480
498
481 /*
482 * Send a Container shutdown followed by a HostShutdown FIB to the
483 * controller to convince it that we don't want to talk to it anymore.
484 * We've been closed and all I/O completed already
485 */
486 device_printf(sc->aac_dev, "shutting down controller...");
499 sc->aac_state |= AAC_STATE_SUSPEND;
487
500
488 cc.Command = VM_CloseAll;
489 cc.ContainerId = 0xffffffff;
490 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), NULL, NULL)) {
491 printf("FAILED.\n");
492 } else {
493 i = 0;
494 /*
495 * XXX Issuing this command to the controller makes it shut down,
496 * but also keeps it from coming back up without a reset of the
497 * PCI bus. This is not desirable if you are just unloading the
498 * driver module with the intent to reload it later.
501 /*
502 * Send a Container shutdown followed by a HostShutdown FIB to the
503 * controller to convince it that we don't want to talk to it anymore.
504 * We've been closed and all I/O completed already
499 */
505 */
500 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, &i,
501 sizeof(i), NULL, NULL)) {
502 printf("FAILED.\n");
503 } else {
504 printf("done.\n");
506 device_printf(sc->aac_dev, "shutting down controller...");
507
508 cc.Command = VM_CloseAll;
509 cc.ContainerId = 0xffffffff;
510 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), NULL, NULL))
511 printf("FAILED.\n");
512 else {
513 i = 0;
514 /*
515 * XXX Issuing this command to the controller makes it shut down
516 * but also keeps it from coming back up without a reset of the
517 * PCI bus. This is not desirable if you are just unloading the
518 * driver module with the intent to reload it later.
519 */
520 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, &i,
521 sizeof(i), NULL, NULL)) {
522 printf("FAILED.\n");
523 } else {
524 printf("done.\n");
525 }
505 }
526 }
506 }
507
527
508 AAC_MASK_INTERRUPTS(sc);
528 AAC_MASK_INTERRUPTS(sc);
509
529
510 splx(s);
511 return(0);
530 splx(s);
531 return(0);
512}
513
532}
533
514/******************************************************************************
534/*
515 * Bring the controller to a quiescent state, ready for system suspend.
516 */
517int
518aac_suspend(device_t dev)
519{
535 * Bring the controller to a quiescent state, ready for system suspend.
536 */
537int
538aac_suspend(device_t dev)
539{
520 struct aac_softc *sc = device_get_softc(dev);
521 int s;
540 struct aac_softc *sc;
541 int s;
522
542
523 debug_called(1);
524 s = splbio();
543 debug_called(1);
525
544
526 sc->aac_state |= AAC_STATE_SUSPEND;
527
528 AAC_MASK_INTERRUPTS(sc);
529 splx(s);
530 return(0);
545 sc = device_get_softc(dev);
546
547 s = splbio();
548
549 sc->aac_state |= AAC_STATE_SUSPEND;
550
551 AAC_MASK_INTERRUPTS(sc);
552 splx(s);
553 return(0);
531}
532
554}
555
533/******************************************************************************
556/*
534 * Bring the controller back to a state ready for operation.
535 */
536int
537aac_resume(device_t dev)
538{
557 * Bring the controller back to a state ready for operation.
558 */
559int
560aac_resume(device_t dev)
561{
539 struct aac_softc *sc = device_get_softc(dev);
562 struct aac_softc *sc;
540
563
541 debug_called(1);
542 sc->aac_state &= ~AAC_STATE_SUSPEND;
543 AAC_UNMASK_INTERRUPTS(sc);
544 return(0);
564 debug_called(1);
565
566 sc = device_get_softc(dev);
567
568 sc->aac_state &= ~AAC_STATE_SUSPEND;
569 AAC_UNMASK_INTERRUPTS(sc);
570 return(0);
545}
546
571}
572
547/*******************************************************************************
573/*
548 * Take an interrupt.
549 */
550void
551aac_intr(void *arg)
552{
574 * Take an interrupt.
575 */
576void
577aac_intr(void *arg)
578{
553 struct aac_softc *sc = (struct aac_softc *)arg;
554 u_int16_t reason;
579 struct aac_softc *sc;
580 u_int16_t reason;
555
581
556 debug_called(2);
582 debug_called(2);
557
583
558 reason = AAC_GET_ISTATUS(sc);
584 sc = (struct aac_softc *)arg;
559
585
560 /* controller wants to talk to the log? Defer it to the AIF thread */
561 if (reason & AAC_DB_PRINTF) {
562 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
563 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
564 sc->aifflags |= AAC_AIFFLAGS_PENDING;
565 wakeup(sc->aifthread);
566 } else
567 aac_print_printf(sc);
568 }
586 reason = AAC_GET_ISTATUS(sc);
569
587
570 /* controller has a message for us? */
571 if (reason & AAC_DB_COMMAND_READY) {
572 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
573 /* XXX What happens if the thread is already awake? */
574 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
575 sc->aifflags |= AAC_AIFFLAGS_PENDING;
576 wakeup(sc->aifthread);
588 /* controller wants to talk to the log? Defer it to the AIF thread */
589 if (reason & AAC_DB_PRINTF) {
590 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
591 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
592 sc->aifflags |= AAC_AIFFLAGS_PENDING;
593 wakeup(sc->aifthread);
594 } else
595 aac_print_printf(sc);
577 }
596 }
578 }
579
580 /* controller has a response for us? */
581 if (reason & AAC_DB_RESPONSE_READY) {
582 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
583 aac_host_response(sc);
584 }
585
597
586 /*
587 * spurious interrupts that we don't use - reset the mask and clear the
588 * interrupts
589 */
590 if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) {
591 AAC_UNMASK_INTERRUPTS(sc);
592 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL |
593 AAC_DB_RESPONSE_NOT_FULL);
594 }
598 /* controller has a message for us? */
599 if (reason & AAC_DB_COMMAND_READY) {
600 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
601 /* XXX What happens if the thread is already awake? */
602 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
603 sc->aifflags |= AAC_AIFFLAGS_PENDING;
604 wakeup(sc->aifthread);
605 }
606 }
607
608 /* controller has a response for us? */
609 if (reason & AAC_DB_RESPONSE_READY) {
610 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
611 aac_host_response(sc);
612 }
613
614 /*
615 * spurious interrupts that we don't use - reset the mask and clear the
616 * interrupts
617 */
618 if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) {
619 AAC_UNMASK_INTERRUPTS(sc);
620 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL |
621 AAC_DB_RESPONSE_NOT_FULL);
622 }
595};
596
623};
624
597/******************************************************************************
598 ******************************************************************************
599 Command Processing
600 ******************************************************************************
601 ******************************************************************************/
625/*
626 * Command Processing
627 */
602
628
603/******************************************************************************
629/*
604 * Start as much queued I/O as possible on the controller
605 */
606static void
607aac_startio(struct aac_softc *sc)
608{
630 * Start as much queued I/O as possible on the controller
631 */
632static void
633aac_startio(struct aac_softc *sc)
634{
609 struct aac_command *cm;
635 struct aac_command *cm;
610
636
611 debug_called(2);
637 debug_called(2);
612
638
613 for(;;) {
614 /* try to get a command that's been put off for lack of resources */
615 cm = aac_dequeue_ready(sc);
639 for (;;) {
640 /*
641 * Try to get a command that's been put off for lack of
642 * resources
643 */
644 cm = aac_dequeue_ready(sc);
616
645
617 /* try to build a command off the bio queue (ignore error return) */
618 if (cm == NULL)
619 aac_bio_command(sc, &cm);
646 /*
647 * Try to build a command off the bio queue (ignore error
648 * return)
649 */
650 if (cm == NULL)
651 aac_bio_command(sc, &cm);
620
652
621 /* nothing to do? */
622 if (cm == NULL)
623 break;
653 /* nothing to do? */
654 if (cm == NULL)
655 break;
624
656
625 /* try to give the command to the controller */
626 if (aac_start(cm) == EBUSY) {
627 /* put it on the ready queue for later */
628 aac_requeue_ready(cm);
629 break;
657 /* try to give the command to the controller */
658 if (aac_start(cm) == EBUSY) {
659 /* put it on the ready queue for later */
660 aac_requeue_ready(cm);
661 break;
662 }
630 }
663 }
631 }
632}
633
664}
665
634/******************************************************************************
666/*
635 * Deliver a command to the controller; allocate controller resources at the
636 * last moment when possible.
637 */
638static int
639aac_start(struct aac_command *cm)
640{
667 * Deliver a command to the controller; allocate controller resources at the
668 * last moment when possible.
669 */
670static int
671aac_start(struct aac_command *cm)
672{
641 struct aac_softc *sc = cm->cm_sc;
642 int error;
673 struct aac_softc *sc;
674 int error;
643
675
644 debug_called(2);
676 debug_called(2);
645
677
646 /* get the command mapped */
647 aac_map_command(cm);
678 sc = cm->cm_sc;
648
679
649 /* fix up the address values in the FIB */
650 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
651 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
680 /* get the command mapped */
681 aac_map_command(cm);
652
682
653 /* save a pointer to the command for speedy reverse-lookup */
654 cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX 64-bit physical
683 /* fix up the address values in the FIB */
684 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
685 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
686
687 /* save a pointer to the command for speedy reverse-lookup */
688 cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX 64-bit physical
655 * address issue */
656
689 * address issue */
690
657 /* put the FIB on the outbound queue */
658 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
659 return(error);
691 /* put the FIB on the outbound queue */
692 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
693 return(error);
660}
661
694}
695
662/******************************************************************************
696/*
663 * Handle notification of one or more FIBs coming from the controller.
664 */
665static void
666aac_host_command(struct aac_softc *sc)
667{
697 * Handle notification of one or more FIBs coming from the controller.
698 */
699static void
700aac_host_command(struct aac_softc *sc)
701{
668 struct aac_fib *fib;
669 u_int32_t fib_size;
670 int size;
702 struct aac_fib *fib;
703 u_int32_t fib_size;
704 int size;
671
705
672 debug_called(2);
706 debug_called(2);
673
707
674 sc->aifflags |= AAC_AIFFLAGS_RUNNING;
708 sc->aifflags |= AAC_AIFFLAGS_RUNNING;
675
709
676 while(!(sc->aifflags & AAC_AIFFLAGS_EXIT)) {
677 if (!(sc->aifflags & AAC_AIFFLAGS_PENDING))
678 tsleep(sc->aifthread, PRIBIO, "aifthd", 15 * hz);
710 while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) {
711 if (!(sc->aifflags & AAC_AIFFLAGS_PENDING))
712 tsleep(sc->aifthread, PRIBIO, "aifthd", 15 * hz);
679
713
680 sc->aifflags &= ~AAC_AIFFLAGS_PENDING;
681 for (;;) {
682 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, &fib))
683 break; /* nothing to do */
714 sc->aifflags &= ~AAC_AIFFLAGS_PENDING;
715 for (;;) {
716 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
717 &fib_size, &fib))
718 break; /* nothing to do */
719
720 AAC_PRINT_FIB(sc, fib);
721
722 switch (fib->Header.Command) {
723 case AifRequest:
724 aac_handle_aif(sc, fib);
725 break;
726 default:
727 device_printf(sc->aac_dev, "unknown command "
728 "from controller\n");
729 break;
730 }
684
731
685 AAC_PRINT_FIB(sc, fib);
732 /* Return the AIF to the controller. */
733 if ((fib->Header.XferState == 0) ||
734 (fib->Header.StructType != AAC_FIBTYPE_TFIB))
735 break;
686
736
687 switch(fib->Header.Command) {
688 case AifRequest:
689 aac_handle_aif(sc, fib);
690 break;
691 default:
692 device_printf(sc->aac_dev, "unknown command from controller\n");
693 break;
694 }
737 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
738 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
739 *(AAC_FSAStatus*)fib->data = ST_OK;
695
740
696 /* Return the AIF to the controller. */
697 if ((fib->Header.XferState == 0) ||
698 (fib->Header.StructType != AAC_FIBTYPE_TFIB))
699 break;
700
701 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
702 if (!(fib->Header.XferState & AAC_FIBSTATE_NORM)) {
703 /*
704 * XXX How to recover from this? If anything goes on
705 * the high priority queue, the controller will panic.
706 * Since it came on the normal priority queue, just
707 * punt and return it there.
708 */
709 device_printf(sc->aac_dev, "Error: Attempted to return "
710 "an AIF not at normal priority\n");
741 /* XXX Compute the Size field? */
742 size = fib->Header.Size;
743 if (size > sizeof(struct aac_fib)) {
744 size = sizeof(struct aac_fib);
745 fib->Header.Size = size;
746 }
747 /*
748 * Since we did not generate this command, it
749 * cannot go through the normal
750 * enqueue->startio chain.
751 */
752 aac_enqueue_response(sc,
753 AAC_ADAP_NORM_RESP_QUEUE,
754 fib);
755 }
711 }
756 }
712 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
713 *(AAC_FSAStatus*)fib->data = ST_OK;
757 aac_print_printf(sc);
714
758
715 /* XXX Compute the Size field? */
716 size = fib->Header.Size;
717 if (size > sizeof(struct aac_fib)) {
718 size = sizeof(struct aac_fib);
719 fib->Header.Size = size;
720 }
721 /*
722 * Since we did not generate this command, it cannot go
723 * through the normal enqueue->startio chain.
724 */
725 aac_enqueue_response(sc, AAC_ADAP_NORM_RESP_QUEUE, fib);
726 }
727 }
759 }
728 aac_print_printf(sc);
760 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
761 wakeup(sc->aac_dev);
729
762
730 }
731 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
732 wakeup(sc->aac_dev);
733
734#if __FreeBSD_version > 500005
763#if __FreeBSD_version > 500005
735 mtx_lock(&Giant);
764 mtx_lock(&Giant);
736#endif
765#endif
737 kthread_exit(0);
766 kthread_exit(0);
738}
739
767}
768
740/******************************************************************************
769/*
741 * Handle notification of one or more FIBs completed by the controller
742 */
743static void
744aac_host_response(struct aac_softc *sc)
745{
770 * Handle notification of one or more FIBs completed by the controller
771 */
772static void
773aac_host_response(struct aac_softc *sc)
774{
746 struct aac_command *cm;
747 struct aac_fib *fib;
748 u_int32_t fib_size;
775 struct aac_command *cm;
776 struct aac_fib *fib;
777 u_int32_t fib_size;
749
778
750 debug_called(2);
779 debug_called(2);
751
780
752 for (;;) {
753 /* look for completed FIBs on our queue */
754 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, &fib))
755 break; /* nothing to do */
781 for (;;) {
782 /* look for completed FIBs on our queue */
783 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
784 &fib))
785 break; /* nothing to do */
756
786
757 /* get the command, unmap and queue for later processing */
758 cm = (struct aac_command *)fib->Header.SenderData;
759 if (cm == NULL) {
760 AAC_PRINT_FIB(sc, fib);
761 } else {
762 aac_remove_busy(cm);
763 aac_unmap_command(cm); /* XXX defer? */
764 aac_enqueue_complete(cm);
787 /* get the command, unmap and queue for later processing */
788 cm = (struct aac_command *)fib->Header.SenderData;
789 if (cm == NULL) {
790 AAC_PRINT_FIB(sc, fib);
791 } else {
792 aac_remove_busy(cm);
793 aac_unmap_command(cm); /* XXX defer? */
794 aac_enqueue_complete(cm);
795 }
765 }
796 }
766 }
767
797
768 /* handle completion processing */
798 /* handle completion processing */
769#if __FreeBSD_version >= 500005
799#if __FreeBSD_version >= 500005
770 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
800 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
771#else
801#else
772 aac_complete(sc, 0);
802 aac_complete(sc, 0);
773#endif
774}
775
803#endif
804}
805
776/******************************************************************************
806/*
777 * Process completed commands.
778 */
779static void
780aac_complete(void *context, int pending)
781{
807 * Process completed commands.
808 */
809static void
810aac_complete(void *context, int pending)
811{
782 struct aac_softc *sc = (struct aac_softc *)context;
783 struct aac_command *cm;
784
785 debug_called(2);
812 struct aac_softc *sc;
813 struct aac_command *cm;
814
815 debug_called(2);
786
816
787 /* pull completed commands off the queue */
788 for (;;) {
789 cm = aac_dequeue_complete(sc);
790 if (cm == NULL)
791 break;
792 cm->cm_flags |= AAC_CMD_COMPLETED;
817 sc = (struct aac_softc *)context;
793
818
794 /* is there a completion handler? */
795 if (cm->cm_complete != NULL) {
796 cm->cm_complete(cm);
797 } else {
798 /* assume that someone is sleeping on this command */
799 wakeup(cm);
819 /* pull completed commands off the queue */
820 for (;;) {
821 cm = aac_dequeue_complete(sc);
822 if (cm == NULL)
823 break;
824 cm->cm_flags |= AAC_CMD_COMPLETED;
825
826 /* is there a completion handler? */
827 if (cm->cm_complete != NULL) {
828 cm->cm_complete(cm);
829 } else {
830 /* assume that someone is sleeping on this command */
831 wakeup(cm);
832 }
800 }
833 }
801 }
802
834
803 /* see if we can start some more I/O */
804 aac_startio(sc);
835 /* see if we can start some more I/O */
836 aac_startio(sc);
805}
806
837}
838
807/******************************************************************************
839/*
808 * Handle a bio submitted from a disk device.
809 */
810void
811aac_submit_bio(struct bio *bp)
812{
840 * Handle a bio submitted from a disk device.
841 */
842void
843aac_submit_bio(struct bio *bp)
844{
813 struct aac_disk *ad = (struct aac_disk *)bp->bio_dev->si_drv1;
814 struct aac_softc *sc = ad->ad_controller;
845 struct aac_disk *ad;
846 struct aac_softc *sc;
815
847
816 debug_called(2);
848 debug_called(2);
817
849
818 /* queue the BIO and try to get some work done */
819 aac_enqueue_bio(sc, bp);
820 aac_startio(sc);
850 ad = (struct aac_disk *)bp->bio_dev->si_drv1;
851 sc = ad->ad_controller;
852
853 /* queue the BIO and try to get some work done */
854 aac_enqueue_bio(sc, bp);
855 aac_startio(sc);
821}
822
856}
857
823/******************************************************************************
858/*
824 * Get a bio and build a command to go with it.
825 */
826static int
827aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
828{
859 * Get a bio and build a command to go with it.
860 */
861static int
862aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
863{
829 struct aac_command *cm;
830 struct aac_fib *fib;
831 struct aac_blockread *br;
832 struct aac_blockwrite *bw;
833 struct aac_disk *ad;
834 struct bio *bp;
864 struct aac_command *cm;
865 struct aac_fib *fib;
866 struct aac_blockread *br;
867 struct aac_blockwrite *bw;
868 struct aac_disk *ad;
869 struct bio *bp;
835
870
836 debug_called(2);
871 debug_called(2);
837
872
838 /* get the resources we will need */
839 cm = NULL;
840 if ((bp = aac_dequeue_bio(sc)) == NULL)
841 goto fail;
842 if (aac_alloc_command(sc, &cm)) /* get a command */
843 goto fail;
873 /* get the resources we will need */
874 cm = NULL;
875 if ((bp = aac_dequeue_bio(sc)) == NULL)
876 goto fail;
877 if (aac_alloc_command(sc, &cm)) /* get a command */
878 goto fail;
844
879
845 /* fill out the command */
846 cm->cm_data = (void *)bp->bio_data;
847 cm->cm_datalen = bp->bio_bcount;
848 cm->cm_complete = aac_bio_complete;
849 cm->cm_private = bp;
850 cm->cm_timestamp = time_second;
851 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
880 /* fill out the command */
881 cm->cm_data = (void *)bp->bio_data;
882 cm->cm_datalen = bp->bio_bcount;
883 cm->cm_complete = aac_bio_complete;
884 cm->cm_private = bp;
885 cm->cm_timestamp = time_second;
886 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
852
887
853 /* build the FIB */
854 fib = cm->cm_fib;
855 fib->Header.XferState =
888 /* build the FIB */
889 fib = cm->cm_fib;
890 fib->Header.XferState =
856 AAC_FIBSTATE_HOSTOWNED |
857 AAC_FIBSTATE_INITIALISED |
891 AAC_FIBSTATE_HOSTOWNED |
892 AAC_FIBSTATE_INITIALISED |
858 AAC_FIBSTATE_FROMHOST |
893 AAC_FIBSTATE_FROMHOST |
859 AAC_FIBSTATE_REXPECTED |
860 AAC_FIBSTATE_NORM;
894 AAC_FIBSTATE_REXPECTED |
895 AAC_FIBSTATE_NORM;
861 fib->Header.Command = ContainerCommand;
862 fib->Header.Size = sizeof(struct aac_fib_header);
896 fib->Header.Command = ContainerCommand;
897 fib->Header.Size = sizeof(struct aac_fib_header);
863
898
864 /* build the read/write request */
865 ad = (struct aac_disk *)bp->bio_dev->si_drv1;
866 if (BIO_IS_READ(bp)) {
867 br = (struct aac_blockread *)&fib->data[0];
868 br->Command = VM_CtBlockRead;
869 br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
870 br->BlockNumber = bp->bio_pblkno;
871 br->ByteCount = bp->bio_bcount;
872 fib->Header.Size += sizeof(struct aac_blockread);
873 cm->cm_sgtable = &br->SgMap;
874 cm->cm_flags |= AAC_CMD_DATAIN;
875 } else {
876 bw = (struct aac_blockwrite *)&fib->data[0];
877 bw->Command = VM_CtBlockWrite;
878 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
879 bw->BlockNumber = bp->bio_pblkno;
880 bw->ByteCount = bp->bio_bcount;
881 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */
882 fib->Header.Size += sizeof(struct aac_blockwrite);
883 cm->cm_flags |= AAC_CMD_DATAOUT;
884 cm->cm_sgtable = &bw->SgMap;
885 }
899 /* build the read/write request */
900 ad = (struct aac_disk *)bp->bio_dev->si_drv1;
901 if (BIO_IS_READ(bp)) {
902 br = (struct aac_blockread *)&fib->data[0];
903 br->Command = VM_CtBlockRead;
904 br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
905 br->BlockNumber = bp->bio_pblkno;
906 br->ByteCount = bp->bio_bcount;
907 fib->Header.Size += sizeof(struct aac_blockread);
908 cm->cm_sgtable = &br->SgMap;
909 cm->cm_flags |= AAC_CMD_DATAIN;
910 } else {
911 bw = (struct aac_blockwrite *)&fib->data[0];
912 bw->Command = VM_CtBlockWrite;
913 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
914 bw->BlockNumber = bp->bio_pblkno;
915 bw->ByteCount = bp->bio_bcount;
916 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */
917 fib->Header.Size += sizeof(struct aac_blockwrite);
918 cm->cm_flags |= AAC_CMD_DATAOUT;
919 cm->cm_sgtable = &bw->SgMap;
920 }
886
921
887 *cmp = cm;
888 return(0);
922 *cmp = cm;
923 return(0);
889
890fail:
924
925fail:
891 if (bp != NULL)
892 aac_enqueue_bio(sc, bp);
893 if (cm != NULL)
894 aac_release_command(cm);
895 return(ENOMEM);
926 if (bp != NULL)
927 aac_enqueue_bio(sc, bp);
928 if (cm != NULL)
929 aac_release_command(cm);
930 return(ENOMEM);
896}
897
931}
932
898/******************************************************************************
933/*
899 * Handle a bio-instigated command that has been completed.
900 */
901static void
902aac_bio_complete(struct aac_command *cm)
903{
934 * Handle a bio-instigated command that has been completed.
935 */
936static void
937aac_bio_complete(struct aac_command *cm)
938{
904 struct aac_blockread_response *brr;
905 struct aac_blockwrite_response *bwr;
906 struct bio *bp;
907 AAC_FSAStatus status;
939 struct aac_blockread_response *brr;
940 struct aac_blockwrite_response *bwr;
941 struct bio *bp;
942 AAC_FSAStatus status;
908
943
909 /* fetch relevant status and then release the command */
910 bp = (struct bio *)cm->cm_private;
911 if (BIO_IS_READ(bp)) {
912 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
913 status = brr->Status;
914 } else {
915 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
916 status = bwr->Status;
917 }
918 aac_release_command(cm);
944 /* fetch relevant status and then release the command */
945 bp = (struct bio *)cm->cm_private;
946 if (BIO_IS_READ(bp)) {
947 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
948 status = brr->Status;
949 } else {
950 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
951 status = bwr->Status;
952 }
953 aac_release_command(cm);
919
954
920 /* fix up the bio based on status */
921 if (status == ST_OK) {
922 bp->bio_resid = 0;
923 } else {
924 bp->bio_error = EIO;
925 bp->bio_flags |= BIO_ERROR;
926 /* pass an error string out to the disk layer */
927 bp->bio_driver1 = aac_describe_code(aac_command_status_table, status);
928 }
929 aac_biodone(bp);
955 /* fix up the bio based on status */
956 if (status == ST_OK) {
957 bp->bio_resid = 0;
958 } else {
959 bp->bio_error = EIO;
960 bp->bio_flags |= BIO_ERROR;
961 /* pass an error string out to the disk layer */
962 bp->bio_driver1 = aac_describe_code(aac_command_status_table,
963 status);
964 }
965 aac_biodone(bp);
930}
931
966}
967
932/******************************************************************************
968/*
933 * Dump a block of data to the controller. If the queue is full, tell the
969 * Dump a block of data to the controller. If the queue is full, tell the
934 * caller to hold off and wait for the queue to drain
970 * caller to hold off and wait for the queue to drain.
935 */
936int
937aac_dump_enqueue(struct aac_disk *ad, u_int32_t lba, void *data, int dumppages)
938{
971 */
972int
973aac_dump_enqueue(struct aac_disk *ad, u_int32_t lba, void *data, int dumppages)
974{
939 struct aac_softc *sc = ad->ad_controller;
940 struct aac_command *cm = NULL;
941 struct aac_fib *fib;
942 struct aac_blockwrite *bw;
975 struct aac_softc *sc;
976 struct aac_command *cm;
977 struct aac_fib *fib;
978 struct aac_blockwrite *bw;
943
979
944 if (aac_alloc_command(sc, &cm))
945 return (EBUSY);
980 sc = ad->ad_controller;
981 cm = NULL;
946
982
947 /* fill out the command */
948 cm->cm_data = data;
949 cm->cm_datalen = dumppages * PAGE_SIZE;
950 cm->cm_complete = NULL;
951 cm->cm_private = NULL;
952 cm->cm_timestamp = time_second;
953 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
983 if (aac_alloc_command(sc, &cm))
984 return (EBUSY);
954
985
955 /* build the FIB */
956 fib = cm->cm_fib;
957 fib->Header.XferState =
986 /* fill out the command */
987 cm->cm_data = data;
988 cm->cm_datalen = dumppages * PAGE_SIZE;
989 cm->cm_complete = NULL;
990 cm->cm_private = NULL;
991 cm->cm_timestamp = time_second;
992 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
993
994 /* build the FIB */
995 fib = cm->cm_fib;
996 fib->Header.XferState =
958 AAC_FIBSTATE_HOSTOWNED |
959 AAC_FIBSTATE_INITIALISED |
997 AAC_FIBSTATE_HOSTOWNED |
998 AAC_FIBSTATE_INITIALISED |
960 AAC_FIBSTATE_FROMHOST |
999 AAC_FIBSTATE_FROMHOST |
961 AAC_FIBSTATE_REXPECTED |
962 AAC_FIBSTATE_NORM;
1000 AAC_FIBSTATE_REXPECTED |
1001 AAC_FIBSTATE_NORM;
963 fib->Header.Command = ContainerCommand;
964 fib->Header.Size = sizeof(struct aac_fib_header);
1002 fib->Header.Command = ContainerCommand;
1003 fib->Header.Size = sizeof(struct aac_fib_header);
965
1004
966 bw = (struct aac_blockwrite *)&fib->data[0];
967 bw->Command = VM_CtBlockWrite;
968 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
969 bw->BlockNumber = lba;
970 bw->ByteCount = dumppages * PAGE_SIZE;
971 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */
972 fib->Header.Size += sizeof(struct aac_blockwrite);
973 cm->cm_flags |= AAC_CMD_DATAOUT;
974 cm->cm_sgtable = &bw->SgMap;
1005 bw = (struct aac_blockwrite *)&fib->data[0];
1006 bw->Command = VM_CtBlockWrite;
1007 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1008 bw->BlockNumber = lba;
1009 bw->ByteCount = dumppages * PAGE_SIZE;
1010 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */
1011 fib->Header.Size += sizeof(struct aac_blockwrite);
1012 cm->cm_flags |= AAC_CMD_DATAOUT;
1013 cm->cm_sgtable = &bw->SgMap;
975
1014
976 return (aac_start(cm));
1015 return (aac_start(cm));
977}
978
1016}
1017
979/******************************************************************************
1018/*
980 * Wait for the card's queue to drain when dumping. Also check for monitor
981 * printf's
982 */
983void
984aac_dump_complete(struct aac_softc *sc)
985{
1019 * Wait for the card's queue to drain when dumping. Also check for monitor
1020 * printf's
1021 */
1022void
1023aac_dump_complete(struct aac_softc *sc)
1024{
986 struct aac_fib *fib;
987 struct aac_command *cm;
988 u_int16_t reason;
989 u_int32_t pi, ci, fib_size;
1025 struct aac_fib *fib;
1026 struct aac_command *cm;
1027 u_int16_t reason;
1028 u_int32_t pi, ci, fib_size;
990
1029
991 do {
992 reason = AAC_GET_ISTATUS(sc);
993 if (reason & AAC_DB_RESPONSE_READY) {
994 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
995 for (;;) {
996 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE,
997 &fib_size, &fib))
998 break;
999 cm = (struct aac_command *)fib->Header.SenderData;
1000 if (cm == NULL) {
1001 AAC_PRINT_FIB(sc, fib);
1002 } else {
1003 aac_remove_busy(cm);
1004 aac_unmap_command(cm);
1005 aac_enqueue_complete(cm);
1006 aac_release_command(cm);
1030 do {
1031 reason = AAC_GET_ISTATUS(sc);
1032 if (reason & AAC_DB_RESPONSE_READY) {
1033 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
1034 for (;;) {
1035 if (aac_dequeue_fib(sc,
1036 AAC_HOST_NORM_RESP_QUEUE,
1037 &fib_size, &fib))
1038 break;
1039 cm = (struct aac_command *)
1040 fib->Header.SenderData;
1041 if (cm == NULL)
1042 AAC_PRINT_FIB(sc, fib);
1043 else {
1044 aac_remove_busy(cm);
1045 aac_unmap_command(cm);
1046 aac_enqueue_complete(cm);
1047 aac_release_command(cm);
1048 }
1049 }
1007 }
1050 }
1008 }
1009 }
1010 if (reason & AAC_DB_PRINTF) {
1011 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
1012 aac_print_printf(sc);
1013 }
1014 pi = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX];
1015 ci = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX];
1016 } while (ci != pi);
1051 if (reason & AAC_DB_PRINTF) {
1052 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
1053 aac_print_printf(sc);
1054 }
1055 pi = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
1056 AAC_PRODUCER_INDEX];
1057 ci = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
1058 AAC_CONSUMER_INDEX];
1059 } while (ci != pi);
1017
1060
1018 return;
1061 return;
1019}
1020
1062}
1063
1021/******************************************************************************
1064/*
1022 * Submit a command to the controller, return when it completes.
1023 */
1024static int
1025aac_wait_command(struct aac_command *cm, int timeout)
1026{
1065 * Submit a command to the controller, return when it completes.
1066 */
1067static int
1068aac_wait_command(struct aac_command *cm, int timeout)
1069{
1027 int s, error = 0;
1070 int s, error = 0;
1028
1071
1029 debug_called(2);
1072 debug_called(2);
1030
1073
1031 /* Put the command on the ready queue and get things going */
1032 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1033 aac_enqueue_ready(cm);
1034 aac_startio(cm->cm_sc);
1035 s = splbio();
1036 while(!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
1037 error = tsleep(cm, PRIBIO | PCATCH, "aacwait", 0);
1038 if ((error == ERESTART) || (error == EINTR))
1039 break;
1040 }
1041 splx(s);
1042 return(error);
1074 /* Put the command on the ready queue and get things going */
1075 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1076 aac_enqueue_ready(cm);
1077 aac_startio(cm->cm_sc);
1078 s = splbio();
1079 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
1080 error = tsleep(cm, PRIBIO | PCATCH, "aacwait", 0);
1081 if ((error == ERESTART) || (error == EINTR))
1082 break;
1083 }
1084 splx(s);
1085 return(error);
1043}
1044
1086}
1087
1045/******************************************************************************
1046 ******************************************************************************
1047 Command Buffer Management
1048 ******************************************************************************
1049 ******************************************************************************/
1088/*
1089 *Command Buffer Management
1090 */
1050
1091
1051/******************************************************************************
1092/*
1052 * Allocate a command.
1053 */
1054static int
1055aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1056{
1093 * Allocate a command.
1094 */
1095static int
1096aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1097{
1057 struct aac_command *cm;
1098 struct aac_command *cm;
1058
1099
1059 debug_called(3);
1100 debug_called(3);
1060
1101
1061 if ((cm = aac_dequeue_free(sc)) == NULL)
1062 return(ENOMEM);
1102 if ((cm = aac_dequeue_free(sc)) == NULL)
1103 return(ENOMEM);
1063
1104
1064 *cmp = cm;
1065 return(0);
1105 *cmp = cm;
1106 return(0);
1066}
1067
1107}
1108
1068/******************************************************************************
1109/*
1069 * Release a command back to the freelist.
1070 */
1071static void
1072aac_release_command(struct aac_command *cm)
1073{
1110 * Release a command back to the freelist.
1111 */
1112static void
1113aac_release_command(struct aac_command *cm)
1114{
1074 debug_called(3);
1115 debug_called(3);
1075
1116
1076 /* (re)initialise the command/FIB */
1077 cm->cm_sgtable = NULL;
1078 cm->cm_flags = 0;
1079 cm->cm_complete = NULL;
1080 cm->cm_private = NULL;
1081 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1082 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1083 cm->cm_fib->Header.Flags = 0;
1084 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1117 /* (re)initialise the command/FIB */
1118 cm->cm_sgtable = NULL;
1119 cm->cm_flags = 0;
1120 cm->cm_complete = NULL;
1121 cm->cm_private = NULL;
1122 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1123 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1124 cm->cm_fib->Header.Flags = 0;
1125 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1085
1126
1086 /*
1087 * These are duplicated in aac_start to cover the case where an
1088 * intermediate stage may have destroyed them. They're left
1089 * initialised here for debugging purposes only.
1090 */
1091 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
1092 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1127 /*
1128 * These are duplicated in aac_start to cover the case where an
1129 * intermediate stage may have destroyed them. They're left
1130 * initialised here for debugging purposes only.
1131 */
1132 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
1133 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1093
1134
1094 aac_enqueue_free(cm);
1135 aac_enqueue_free(cm);
1095}
1096
1136}
1137
1097/******************************************************************************
1138/*
1098 * Map helper for command/FIB allocation.
1099 */
1100static void
1101aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1102{
1139 * Map helper for command/FIB allocation.
1140 */
1141static void
1142aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1143{
1103 struct aac_softc *sc = (struct aac_softc *)arg;
1144 struct aac_softc *sc;
1104
1145
1105 debug_called(3);
1146 sc = (struct aac_softc *)arg;
1106
1147
1107 sc->aac_fibphys = segs[0].ds_addr;
1148 debug_called(3);
1149
1150 sc->aac_fibphys = segs[0].ds_addr;
1108}
1109
1151}
1152
1110/******************************************************************************
1153/*
1111 * Allocate and initialise commands/FIBs for this adapter.
1112 */
1113static int
1114aac_alloc_commands(struct aac_softc *sc)
1115{
1154 * Allocate and initialise commands/FIBs for this adapter.
1155 */
1156static int
1157aac_alloc_commands(struct aac_softc *sc)
1158{
1116 struct aac_command *cm;
1117 int i;
1159 struct aac_command *cm;
1160 int i;
1118
1161
1119 debug_called(1);
1162 debug_called(1);
1120
1163
1121 /* allocate the FIBs in DMAable memory and load them */
1122 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs,
1164 /* allocate the FIBs in DMAable memory and load them */
1165 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs,
1123 BUS_DMA_NOWAIT, &sc->aac_fibmap)) {
1166 BUS_DMA_NOWAIT, &sc->aac_fibmap)) {
1124 return(ENOMEM);
1125 }
1126 bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs,
1127 AAC_FIB_COUNT * sizeof(struct aac_fib),
1128 aac_map_command_helper, sc, 0);
1167 return(ENOMEM);
1168 }
1169 bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs,
1170 AAC_FIB_COUNT * sizeof(struct aac_fib),
1171 aac_map_command_helper, sc, 0);
1129
1172
1130 /* initialise constant fields in the command structure */
1131 for (i = 0; i < AAC_FIB_COUNT; i++) {
1132 cm = &sc->aac_command[i];
1133 cm->cm_sc = sc;
1134 cm->cm_fib = sc->aac_fibs + i;
1135 cm->cm_fibphys = sc->aac_fibphys + (i * sizeof(struct aac_fib));
1173 /* initialise constant fields in the command structure */
1174 for (i = 0; i < AAC_FIB_COUNT; i++) {
1175 cm = &sc->aac_command[i];
1176 cm->cm_sc = sc;
1177 cm->cm_fib = sc->aac_fibs + i;
1178 cm->cm_fibphys = sc->aac_fibphys + (i * sizeof(struct aac_fib));
1136
1179
1137 if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap))
1138 aac_release_command(cm);
1139 }
1140 return(0);
1180 if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap))
1181 aac_release_command(cm);
1182 }
1183 return(0);
1141}
1142
1184}
1185
1143/******************************************************************************
1186/*
1144 * Free FIBs owned by this adapter.
1145 */
1146static void
1147aac_free_commands(struct aac_softc *sc)
1148{
1187 * Free FIBs owned by this adapter.
1188 */
1189static void
1190aac_free_commands(struct aac_softc *sc)
1191{
1149 int i;
1192 int i;
1150
1193
1151 debug_called(1);
1194 debug_called(1);
1152
1195
1153 for (i = 0; i < AAC_FIB_COUNT; i++)
1154 bus_dmamap_destroy(sc->aac_buffer_dmat, sc->aac_command[i].cm_datamap);
1155 bus_dmamap_unload(sc->aac_fib_dmat, sc->aac_fibmap);
1156 bus_dmamem_free(sc->aac_fib_dmat, sc->aac_fibs, sc->aac_fibmap);
1196 for (i = 0; i < AAC_FIB_COUNT; i++)
1197 bus_dmamap_destroy(sc->aac_buffer_dmat,
1198 sc->aac_command[i].cm_datamap);
1199
1200 bus_dmamap_unload(sc->aac_fib_dmat, sc->aac_fibmap);
1201 bus_dmamem_free(sc->aac_fib_dmat, sc->aac_fibs, sc->aac_fibmap);
1157}
1158
1202}
1203
1159/******************************************************************************
1204/*
1160 * Command-mapping helper function - populate this command's s/g table.
1161 */
1162static void
1163aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1164{
1205 * Command-mapping helper function - populate this command's s/g table.
1206 */
1207static void
1208aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1209{
1165 struct aac_command *cm = (struct aac_command *)arg;
1166 struct aac_fib *fib = cm->cm_fib;
1167 struct aac_sg_table *sg;
1168 int i;
1210 struct aac_command *cm;
1211 struct aac_fib *fib;
1212 struct aac_sg_table *sg;
1213 int i;
1169
1214
1170 debug_called(3);
1215 debug_called(3);
1171
1216
1172 /* find the s/g table */
1173 sg = cm->cm_sgtable;
1217 cm = (struct aac_command *)arg;
1218 fib = cm->cm_fib;
1174
1219
1175 /* copy into the FIB */
1176 if (sg != NULL) {
1177 sg->SgCount = nseg;
1178 for (i = 0; i < nseg; i++) {
1179 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1180 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1220 /* find the s/g table */
1221 sg = cm->cm_sgtable;
1222
1223 /* copy into the FIB */
1224 if (sg != NULL) {
1225 sg->SgCount = nseg;
1226 for (i = 0; i < nseg; i++) {
1227 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1228 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1229 }
1230 /* update the FIB size for the s/g count */
1231 fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1181 }
1232 }
1182 /* update the FIB size for the s/g count */
1183 fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1184 }
1185
1186}
1187
1233
1234}
1235
1188/******************************************************************************
1236/*
1189 * Map a command into controller-visible space.
1190 */
1191static void
1192aac_map_command(struct aac_command *cm)
1193{
1237 * Map a command into controller-visible space.
1238 */
1239static void
1240aac_map_command(struct aac_command *cm)
1241{
1194 struct aac_softc *sc = cm->cm_sc;
1242 struct aac_softc *sc;
1195
1243
1196 debug_called(2);
1244 debug_called(2);
1197
1245
1198 /* don't map more than once */
1199 if (cm->cm_flags & AAC_CMD_MAPPED)
1200 return;
1246 sc = cm->cm_sc;
1201
1247
1202 if (cm->cm_datalen != 0) {
1203 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap, cm->cm_data,
1204 cm->cm_datalen, aac_map_command_sg, cm, 0);
1248 /* don't map more than once */
1249 if (cm->cm_flags & AAC_CMD_MAPPED)
1250 return;
1205
1251
1252 if (cm->cm_datalen != 0) {
1253 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1254 cm->cm_data, cm->cm_datalen,
1255 aac_map_command_sg, cm, 0);
1256
1206 if (cm->cm_flags & AAC_CMD_DATAIN)
1257 if (cm->cm_flags & AAC_CMD_DATAIN)
1207 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1208 BUS_DMASYNC_PREREAD);
1258 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1259 BUS_DMASYNC_PREREAD);
1209 if (cm->cm_flags & AAC_CMD_DATAOUT)
1260 if (cm->cm_flags & AAC_CMD_DATAOUT)
1210 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1211 BUS_DMASYNC_PREWRITE);
1212 }
1213 cm->cm_flags |= AAC_CMD_MAPPED;
1261 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1262 BUS_DMASYNC_PREWRITE);
1263 }
1264 cm->cm_flags |= AAC_CMD_MAPPED;
1214}
1215
1265}
1266
1216/******************************************************************************
1267/*
1217 * Unmap a command from controller-visible space.
1218 */
1219static void
1220aac_unmap_command(struct aac_command *cm)
1221{
1268 * Unmap a command from controller-visible space.
1269 */
1270static void
1271aac_unmap_command(struct aac_command *cm)
1272{
1222 struct aac_softc *sc = cm->cm_sc;
1273 struct aac_softc *sc;
1223
1274
1224 debug_called(2);
1275 debug_called(2);
1225
1276
1226 if (!(cm->cm_flags & AAC_CMD_MAPPED))
1227 return;
1277 sc = cm->cm_sc;
1228
1278
1229 if (cm->cm_datalen != 0) {
1230 if (cm->cm_flags & AAC_CMD_DATAIN)
1231 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1232 BUS_DMASYNC_POSTREAD);
1233 if (cm->cm_flags & AAC_CMD_DATAOUT)
1234 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1235 BUS_DMASYNC_POSTWRITE);
1279 if (!(cm->cm_flags & AAC_CMD_MAPPED))
1280 return;
1236
1281
1237 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1238 }
1239 cm->cm_flags &= ~AAC_CMD_MAPPED;
1282 if (cm->cm_datalen != 0) {
1283 if (cm->cm_flags & AAC_CMD_DATAIN)
1284 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1285 BUS_DMASYNC_POSTREAD);
1286 if (cm->cm_flags & AAC_CMD_DATAOUT)
1287 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1288 BUS_DMASYNC_POSTWRITE);
1289
1290 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1291 }
1292 cm->cm_flags &= ~AAC_CMD_MAPPED;
1240}
1241
1293}
1294
1242/******************************************************************************
1243 ******************************************************************************
1244 Hardware Interface
1245 ******************************************************************************
1246 ******************************************************************************/
1295/*
1296 * Hardware Interface
1297 */
1247
1298
1248/******************************************************************************
1299/*
1249 * Initialise the adapter.
1250 */
1251static void
1252aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1253{
1300 * Initialise the adapter.
1301 */
1302static void
1303aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1304{
1254 struct aac_softc *sc = (struct aac_softc *)arg;
1305 struct aac_softc *sc;
1255
1306
1256 debug_called(1);
1307 debug_called(1);
1257
1308
1258 sc->aac_common_busaddr = segs[0].ds_addr;
1309 sc = (struct aac_softc *)arg;
1310
1311 sc->aac_common_busaddr = segs[0].ds_addr;
1259}
1260
1261static int
1262aac_init(struct aac_softc *sc)
1263{
1312}
1313
1314static int
1315aac_init(struct aac_softc *sc)
1316{
1264 struct aac_adapter_init *ip;
1265 time_t then;
1266 u_int32_t code;
1267 u_int8_t *qaddr;
1317 struct aac_adapter_init *ip;
1318 time_t then;
1319 u_int32_t code;
1320 u_int8_t *qaddr;
1268
1321
1269 debug_called(1);
1322 debug_called(1);
1270
1323
1271 /*
1272 * First wait for the adapter to come ready.
1273 */
1274 then = time_second;
1275 do {
1276 code = AAC_GET_FWSTATUS(sc);
1277 if (code & AAC_SELF_TEST_FAILED) {
1278 device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1279 return(ENXIO);
1324 /*
1325 * First wait for the adapter to come ready.
1326 */
1327 then = time_second;
1328 do {
1329 code = AAC_GET_FWSTATUS(sc);
1330 if (code & AAC_SELF_TEST_FAILED) {
1331 device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1332 return(ENXIO);
1333 }
1334 if (code & AAC_KERNEL_PANIC) {
1335 device_printf(sc->aac_dev,
1336 "FATAL: controller kernel panic\n");
1337 return(ENXIO);
1338 }
1339 if (time_second > (then + AAC_BOOT_TIMEOUT)) {
1340 device_printf(sc->aac_dev,
1341 "FATAL: controller not coming ready, "
1342 "status %x\n", code);
1343 return(ENXIO);
1344 }
1345 } while (!(code & AAC_UP_AND_RUNNING));
1346
1347 /*
1348 * Create DMA tag for the common structure and allocate it.
1349 */
1350 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
1351 1, 0, /* algnmnt, boundary */
1352 BUS_SPACE_MAXADDR, /* lowaddr */
1353 BUS_SPACE_MAXADDR, /* highaddr */
1354 NULL, NULL, /* filter, filterarg */
1355 sizeof(struct aac_common), /* maxsize */
1356 1, /* nsegments */
1357 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1358 0, /* flags */
1359 &sc->aac_common_dmat)) {
1360 device_printf(sc->aac_dev,
1361 "can't allocate common structure DMA tag\n");
1362 return(ENOMEM);
1280 }
1363 }
1281 if (code & AAC_KERNEL_PANIC) {
1282 device_printf(sc->aac_dev, "FATAL: controller kernel panic\n");
1283 return(ENXIO);
1364 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1365 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1366 device_printf(sc->aac_dev, "can't allocate common structure\n");
1367 return(ENOMEM);
1284 }
1368 }
1285 if (time_second > (then + AAC_BOOT_TIMEOUT)) {
1286 device_printf(sc->aac_dev, "FATAL: controller not coming ready, "
1287 "status %x\n", code);
1288 return(ENXIO);
1289 }
1290 } while (!(code & AAC_UP_AND_RUNNING));
1369 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1370 sc->aac_common, sizeof(*sc->aac_common), aac_common_map,
1371 sc, 0);
1372 bzero(sc->aac_common, sizeof(*sc->aac_common));
1373
1374 /*
1375 * Fill in the init structure. This tells the adapter about the
1376 * physical location of various important shared data structures.
1377 */
1378 ip = &sc->aac_common->ac_init;
1379 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1291
1380
1292 /*
1293 * Create DMA tag for the common structure and allocate it.
1294 */
1295 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
1296 1, 0, /* algnmnt, boundary */
1297 BUS_SPACE_MAXADDR, /* lowaddr */
1298 BUS_SPACE_MAXADDR, /* highaddr */
1299 NULL, NULL, /* filter, filterarg */
1300 sizeof(struct aac_common), 1,/* maxsize, nsegments */
1301 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1302 0, /* flags */
1303 &sc->aac_common_dmat)) {
1304 device_printf(sc->aac_dev, "can't allocate common structure DMA tag\n");
1305 return(ENOMEM);
1306 }
1307 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1308 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1309 device_printf(sc->aac_dev, "can't allocate common structure\n");
1310 return(ENOMEM);
1311 }
1312 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap, sc->aac_common,
1313 sizeof(*sc->aac_common), aac_common_map, sc, 0);
1314 bzero(sc->aac_common, sizeof(*sc->aac_common));
1315
1316 /*
1317 * Fill in the init structure. This tells the adapter about the physical
1318 * location of various important shared data structures.
1319 */
1320 ip = &sc->aac_common->ac_init;
1321 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1381 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1382 offsetof(struct aac_common, ac_fibs);
1383 ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0];
1384 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1385 ip->AdapterFibAlign = sizeof(struct aac_fib);
1322
1386
1323 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1324 offsetof(struct aac_common, ac_fibs);
1325 ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0];
1326 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1327 ip->AdapterFibAlign = sizeof(struct aac_fib);
1387 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1388 offsetof(struct aac_common, ac_printf);
1389 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1328
1390
1329 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1330 offsetof(struct aac_common, ac_printf);
1331 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1391 ip->HostPhysMemPages = 0; /* not used? */
1392 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1332
1393
1333 ip->HostPhysMemPages = 0; /* not used? */
1334 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1394 /*
1395 * Initialise FIB queues. Note that it appears that the layout of the
1396 * indexes and the segmentation of the entries may be mandated by the
1397 * adapter, which is only told about the base of the queue index fields.
1398 *
1399 * The initial values of the indices are assumed to inform the adapter
1400 * of the sizes of the respective queues, and theoretically it could
1401 * work out the entire layout of the queue structures from this. We
1402 * take the easy route and just lay this area out like everyone else
1403 * does.
1404 *
1405 * The Linux driver uses a much more complex scheme whereby several
1406 * header records are kept for each queue. We use a couple of generic
1407 * list manipulation functions which 'know' the size of each list by
1408 * virtue of a table.
1409 */
1410 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1411 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1412 sc->aac_queues = (struct aac_queue_table *)qaddr;
1413 ip->CommHeaderAddress = sc->aac_common_busaddr +
1414 ((u_int32_t)sc->aac_queues -
1415 (u_int32_t)sc->aac_common);
1416 bzero(sc->aac_queues, sizeof(struct aac_queue_table));
1335
1417
1336 /*
1337 * Initialise FIB queues. Note that it appears that the layout of the
1338 * indexes and the segmentation of the entries may be mandated by the
1339 * adapter, which is only told about the base of the queue index fields.
1340 *
1341 * The initial values of the indices are assumed to inform the adapter
1342 * of the sizes of the respective queues, and theoretically it could work
1343 * out the entire layout of the queue structures from this. We take the
1344 * easy route and just lay this area out like everyone else does.
1345 *
1346 * The Linux driver uses a much more complex scheme whereby several header
1347 * records are kept for each queue. We use a couple of generic list
1348 * manipulation functions which 'know' the size of each list by virtue of a
1349 * table.
1350 */
1351 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1352 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1353 sc->aac_queues = (struct aac_queue_table *)qaddr;
1354 ip->CommHeaderAddress = sc->aac_common_busaddr + ((u_int32_t)sc->aac_queues
1355 - (u_int32_t)sc->aac_common);
1356 bzero(sc->aac_queues, sizeof(struct aac_queue_table));
1357
1358 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1418 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1359 AAC_HOST_NORM_CMD_ENTRIES;
1419 AAC_HOST_NORM_CMD_ENTRIES;
1360 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1420 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1361 AAC_HOST_NORM_CMD_ENTRIES;
1421 AAC_HOST_NORM_CMD_ENTRIES;
1362 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1422 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1363 AAC_HOST_HIGH_CMD_ENTRIES;
1423 AAC_HOST_HIGH_CMD_ENTRIES;
1364 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1424 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1365 AAC_HOST_HIGH_CMD_ENTRIES;
1425 AAC_HOST_HIGH_CMD_ENTRIES;
1366 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1426 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1367 AAC_ADAP_NORM_CMD_ENTRIES;
1427 AAC_ADAP_NORM_CMD_ENTRIES;
1368 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1428 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1369 AAC_ADAP_NORM_CMD_ENTRIES;
1429 AAC_ADAP_NORM_CMD_ENTRIES;
1370 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1430 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1371 AAC_ADAP_HIGH_CMD_ENTRIES;
1431 AAC_ADAP_HIGH_CMD_ENTRIES;
1372 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1432 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1373 AAC_ADAP_HIGH_CMD_ENTRIES;
1433 AAC_ADAP_HIGH_CMD_ENTRIES;
1374 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] =
1434 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1375 AAC_HOST_NORM_RESP_ENTRIES;
1435 AAC_HOST_NORM_RESP_ENTRIES;
1376 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] =
1436 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1377 AAC_HOST_NORM_RESP_ENTRIES;
1437 AAC_HOST_NORM_RESP_ENTRIES;
1378 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] =
1438 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1379 AAC_HOST_HIGH_RESP_ENTRIES;
1439 AAC_HOST_HIGH_RESP_ENTRIES;
1380 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] =
1440 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1381 AAC_HOST_HIGH_RESP_ENTRIES;
1441 AAC_HOST_HIGH_RESP_ENTRIES;
1382 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] =
1442 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1383 AAC_ADAP_NORM_RESP_ENTRIES;
1443 AAC_ADAP_NORM_RESP_ENTRIES;
1384 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] =
1444 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1385 AAC_ADAP_NORM_RESP_ENTRIES;
1445 AAC_ADAP_NORM_RESP_ENTRIES;
1386 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] =
1446 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1387 AAC_ADAP_HIGH_RESP_ENTRIES;
1447 AAC_ADAP_HIGH_RESP_ENTRIES;
1388 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] =
1448 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1389 AAC_ADAP_HIGH_RESP_ENTRIES;
1449 AAC_ADAP_HIGH_RESP_ENTRIES;
1390 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1450 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1391 &sc->aac_queues->qt_HostNormCmdQueue[0];
1451 &sc->aac_queues->qt_HostNormCmdQueue[0];
1392 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1452 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1393 &sc->aac_queues->qt_HostHighCmdQueue[0];
1453 &sc->aac_queues->qt_HostHighCmdQueue[0];
1394 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1454 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1395 &sc->aac_queues->qt_AdapNormCmdQueue[0];
1455 &sc->aac_queues->qt_AdapNormCmdQueue[0];
1396 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1456 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1397 &sc->aac_queues->qt_AdapHighCmdQueue[0];
1457 &sc->aac_queues->qt_AdapHighCmdQueue[0];
1398 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1458 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1399 &sc->aac_queues->qt_HostNormRespQueue[0];
1459 &sc->aac_queues->qt_HostNormRespQueue[0];
1400 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1460 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1401 &sc->aac_queues->qt_HostHighRespQueue[0];
1461 &sc->aac_queues->qt_HostHighRespQueue[0];
1402 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1462 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1403 &sc->aac_queues->qt_AdapNormRespQueue[0];
1463 &sc->aac_queues->qt_AdapNormRespQueue[0];
1404 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1464 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1405 &sc->aac_queues->qt_AdapHighRespQueue[0];
1406
1465 &sc->aac_queues->qt_AdapHighRespQueue[0];
1466
1407 /*
1408 * Do controller-type-specific initialisation
1409 */
1410 switch (sc->aac_hwif) {
1411 case AAC_HWIF_I960RX:
1412 AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1413 break;
1414 }
1467 /*
1468 * Do controller-type-specific initialisation
1469 */
1470 switch (sc->aac_hwif) {
1471 case AAC_HWIF_I960RX:
1472 AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1473 break;
1474 }
1415
1475
1416 /*
1417 * Give the init structure to the controller.
1418 */
1419 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1420 sc->aac_common_busaddr + offsetof(struct aac_common,
1421 ac_init), 0, 0, 0, NULL)) {
1422 device_printf(sc->aac_dev, "error establishing init structure\n");
1423 return(EIO);
1424 }
1476 /*
1477 * Give the init structure to the controller.
1478 */
1479 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1480 sc->aac_common_busaddr +
1481 offsetof(struct aac_common, ac_init), 0, 0, 0,
1482 NULL)) {
1483 device_printf(sc->aac_dev,
1484 "error establishing init structure\n");
1485 return(EIO);
1486 }
1425
1487
1426 return(0);
1488 return(0);
1427}
1428
1489}
1490
1429/******************************************************************************
1491/*
1430 * Send a synchronous command to the controller and wait for a result.
1431 */
1432static int
1433aac_sync_command(struct aac_softc *sc, u_int32_t command,
1434 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1435 u_int32_t *sp)
1436{
1492 * Send a synchronous command to the controller and wait for a result.
1493 */
1494static int
1495aac_sync_command(struct aac_softc *sc, u_int32_t command,
1496 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1497 u_int32_t *sp)
1498{
1437 time_t then;
1438 u_int32_t status;
1499 time_t then;
1500 u_int32_t status;
1439
1501
1440 debug_called(3);
1502 debug_called(3);
1441
1503
1442 /* populate the mailbox */
1443 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1504 /* populate the mailbox */
1505 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1444
1506
1445 /* ensure the sync command doorbell flag is cleared */
1446 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1507 /* ensure the sync command doorbell flag is cleared */
1508 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1447
1509
1448 /* then set it to signal the adapter */
1449 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1510 /* then set it to signal the adapter */
1511 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1450
1512
1451 /* spin waiting for the command to complete */
1452 then = time_second;
1453 do {
1454 if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
1455 debug(2, "timed out");
1456 return(EIO);
1457 }
1458 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1513 /* spin waiting for the command to complete */
1514 then = time_second;
1515 do {
1516 if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
1517 debug(2, "timed out");
1518 return(EIO);
1519 }
1520 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1459
1521
1460 /* clear the completion flag */
1461 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1522 /* clear the completion flag */
1523 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1462
1524
1463 /* get the command status */
1464 status = AAC_GET_MAILBOXSTATUS(sc);
1465 if (sp != NULL)
1466 *sp = status;
1467 return(0);
1525 /* get the command status */
1526 status = AAC_GET_MAILBOXSTATUS(sc);
1527 if (sp != NULL)
1528 *sp = status;
1529 return(0);
1468}
1469
1530}
1531
1470/******************************************************************************
1532/*
1471 * Send a synchronous FIB to the controller and wait for a result.
1472 */
1473static int
1474aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1533 * Send a synchronous FIB to the controller and wait for a result.
1534 */
1535static int
1536aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1475 void *data, u_int16_t datasize,
1476 void *result, u_int16_t *resultsize)
1537 void *data, u_int16_t datasize,
1538 void *result, u_int16_t *resultsize)
1477{
1539{
1478 struct aac_fib *fib = &sc->aac_common->ac_sync_fib;
1540 struct aac_fib *fib;
1479
1541
1480 debug_called(3);
1542 debug_called(3);
1481
1543
1482 if (datasize > AAC_FIB_DATASIZE)
1483 return(EINVAL);
1544 fib = &sc->aac_common->ac_sync_fib;
1484
1545
1485 /*
1486 * Set up the sync FIB
1487 */
1488 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | AAC_FIBSTATE_INITIALISED |
1489 AAC_FIBSTATE_EMPTY;
1490 fib->Header.XferState |= xferstate;
1491 fib->Header.Command = command;
1492 fib->Header.StructType = AAC_FIBTYPE_TFIB;
1493 fib->Header.Size = sizeof(struct aac_fib) + datasize;
1494 fib->Header.SenderSize = sizeof(struct aac_fib);
1495 fib->Header.SenderFibAddress = (u_int32_t)fib;
1496 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1497 offsetof(struct aac_common, ac_sync_fib);
1546 if (datasize > AAC_FIB_DATASIZE)
1547 return(EINVAL);
1498
1548
1499 /*
1500 * Copy in data.
1501 */
1502 if (data != NULL) {
1503 KASSERT(datasize <= sizeof(fib->data),
1504 ("aac_sync_fib: datasize to large"));
1505 bcopy(data, fib->data, datasize);
1506 fib->Header.XferState |= AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM;
1507 }
1549 /*
1550 * Set up the sync FIB
1551 */
1552 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1553 AAC_FIBSTATE_INITIALISED |
1554 AAC_FIBSTATE_EMPTY;
1555 fib->Header.XferState |= xferstate;
1556 fib->Header.Command = command;
1557 fib->Header.StructType = AAC_FIBTYPE_TFIB;
1558 fib->Header.Size = sizeof(struct aac_fib) + datasize;
1559 fib->Header.SenderSize = sizeof(struct aac_fib);
1560 fib->Header.SenderFibAddress = (u_int32_t)fib;
1561 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1562 offsetof(struct aac_common,
1563 ac_sync_fib);
1508
1564
1509 /*
1510 * Give the FIB to the controller, wait for a response.
1511 */
1512 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fib->Header.ReceiverFibAddress,
1513 0, 0, 0, NULL)) {
1514 debug(2, "IO error");
1515 return(EIO);
1516 }
1565 /*
1566 * Copy in data.
1567 */
1568 if (data != NULL) {
1569 KASSERT(datasize <= sizeof(fib->data),
1570 ("aac_sync_fib: datasize to large"));
1571 bcopy(data, fib->data, datasize);
1572 fib->Header.XferState |= AAC_FIBSTATE_FROMHOST |
1573 AAC_FIBSTATE_NORM;
1574 }
1517
1575
1518 /*
1519 * Copy out the result
1520 */
1521 if (result != NULL) {
1522 u_int copysize;
1576 /*
1577 * Give the FIB to the controller, wait for a response.
1578 */
1579 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1580 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1581 debug(2, "IO error");
1582 return(EIO);
1583 }
1523
1584
1524 copysize = fib->Header.Size - sizeof(struct aac_fib_header);
1525 if (copysize > *resultsize)
1526 copysize = *resultsize;
1527 *resultsize = fib->Header.Size - sizeof(struct aac_fib_header);
1528 bcopy(fib->data, result, copysize);
1529 }
1530 return(0);
1585 /*
1586 * Copy out the result
1587 */
1588 if (result != NULL) {
1589 u_int copysize;
1590
1591 copysize = fib->Header.Size - sizeof(struct aac_fib_header);
1592 if (copysize > *resultsize)
1593 copysize = *resultsize;
1594 *resultsize = fib->Header.Size - sizeof(struct aac_fib_header);
1595 bcopy(fib->data, result, copysize);
1596 }
1597 return(0);
1531}
1532
1598}
1599
1533/******************************************************************************
1600/*
1534 * Adapter-space FIB queue manipulation
1535 *
1536 * Note that the queue implementation here is a little funky; neither the PI or
1537 * CI will ever be zero. This behaviour is a controller feature.
1538 */
1539static struct {
1601 * Adapter-space FIB queue manipulation
1602 *
1603 * Note that the queue implementation here is a little funky; neither the PI or
1604 * CI will ever be zero. This behaviour is a controller feature.
1605 */
1606static struct {
1540 int size;
1541 int notify;
1607 int size;
1608 int notify;
1542} aac_qinfo[] = {
1609} aac_qinfo[] = {
1543 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
1544 {AAC_HOST_HIGH_CMD_ENTRIES, 0},
1545 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
1546 {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
1547 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
1548 {AAC_HOST_HIGH_RESP_ENTRIES, 0},
1549 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
1550 {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
1610 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
1611 {AAC_HOST_HIGH_CMD_ENTRIES, 0},
1612 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
1613 {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
1614 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
1615 {AAC_HOST_HIGH_RESP_ENTRIES, 0},
1616 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
1617 {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
1551};
1552
1553/*
1554 * Atomically insert an entry into the nominated queue, returns 0 on success or
1555 * EBUSY if the queue is full.
1556 *
1557 * Note: it would be more efficient to defer notifying the controller in
1618};
1619
1620/*
1621 * Atomically insert an entry into the nominated queue, returns 0 on success or
1622 * EBUSY if the queue is full.
1623 *
1624 * Note: it would be more efficient to defer notifying the controller in
1558 * the case where we may be inserting several entries in rapid succession, * but implementing this usefully may be difficult (it would involve a
1559 * separate queue/notify interface).
1625 * the case where we may be inserting several entries in rapid succession,
1626 * but implementing this usefully may be difficult (it would involve a
1627 * separate queue/notify interface).
1560 */
1561static int
1562aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1563{
1628 */
1629static int
1630aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1631{
1564 u_int32_t pi, ci;
1565 int s, error;
1566 u_int32_t fib_size;
1567 u_int32_t fib_addr;
1632 u_int32_t pi, ci;
1633 int s, error;
1634 u_int32_t fib_size;
1635 u_int32_t fib_addr;
1568
1636
1569 debug_called(3);
1637 debug_called(3);
1570
1638
1571 fib_size = cm->cm_fib->Header.Size;
1572 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1639 fib_size = cm->cm_fib->Header.Size;
1640 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1573
1641
1574 s = splbio();
1642 s = splbio();
1575
1643
1576 /* get the producer/consumer indices */
1577 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1578 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1644 /* get the producer/consumer indices */
1645 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1646 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1579
1647
1580 /* wrap the queue? */
1581 if (pi >= aac_qinfo[queue].size)
1582 pi = 0;
1648 /* wrap the queue? */
1649 if (pi >= aac_qinfo[queue].size)
1650 pi = 0;
1583
1651
1584 /* check for queue full */
1585 if ((pi + 1) == ci) {
1586 error = EBUSY;
1587 goto out;
1588 }
1652 /* check for queue full */
1653 if ((pi + 1) == ci) {
1654 error = EBUSY;
1655 goto out;
1656 }
1589
1657
1590 /* populate queue entry */
1591 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1592 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1658 /* populate queue entry */
1659 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1660 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1593
1661
1594 /* update producer index */
1595 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1662 /* update producer index */
1663 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1596
1664
1597 /*
1598 * To avoid a race with its completion interrupt, place this command on the
1599 * busy queue prior to advertising it to the controller.
1600 */
1601 aac_enqueue_busy(cm);
1665 /*
1666 * To avoid a race with its completion interrupt, place this command on
1667 * the busy queue prior to advertising it to the controller.
1668 */
1669 aac_enqueue_busy(cm);
1602
1670
1603 /* notify the adapter if we know how */
1604 if (aac_qinfo[queue].notify != 0)
1605 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1671 /* notify the adapter if we know how */
1672 if (aac_qinfo[queue].notify != 0)
1673 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1606
1674
1607 error = 0;
1675 error = 0;
1608
1609out:
1676
1677out:
1610 splx(s);
1611 return(error);
1678 splx(s);
1679 return(error);
1612}
1613
1614/*
1615 * Atomically remove one entry from the nominated queue, returns 0 on
1616 * success or ENOENT if the queue is empty.
1617 */
1618static int
1619aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1620 struct aac_fib **fib_addr)
1621{
1680}
1681
1682/*
1683 * Atomically remove one entry from the nominated queue, returns 0 on
1684 * success or ENOENT if the queue is empty.
1685 */
1686static int
1687aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1688 struct aac_fib **fib_addr)
1689{
1622 u_int32_t pi, ci;
1623 int s, error;
1624 int notify;
1690 u_int32_t pi, ci;
1691 int s, error;
1692 int notify;
1625
1693
1626 debug_called(3);
1694 debug_called(3);
1627
1695
1628 s = splbio();
1696 s = splbio();
1629
1697
1630 /* get the producer/consumer indices */
1631 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1632 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1698 /* get the producer/consumer indices */
1699 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1700 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1633
1701
1634 /* check for queue empty */
1635 if (ci == pi) {
1636 error = ENOENT;
1637 goto out;
1638 }
1639
1640 notify = 0;
1641 if (ci == pi + 1)
1642 notify++;
1702 /* check for queue empty */
1703 if (ci == pi) {
1704 error = ENOENT;
1705 goto out;
1706 }
1707
1708 notify = 0;
1709 if (ci == pi + 1)
1710 notify++;
1643
1711
1644 /* wrap the queue? */
1645 if (ci >= aac_qinfo[queue].size)
1646 ci = 0;
1712 /* wrap the queue? */
1713 if (ci >= aac_qinfo[queue].size)
1714 ci = 0;
1647
1715
1648 /* fetch the entry */
1649 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1650 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] + ci)->aq_fib_addr;
1716 /* fetch the entry */
1717 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1718 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] +
1719 ci)->aq_fib_addr;
1651
1720
1652 /* update consumer index */
1653 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1721 /* update consumer index */
1722 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1654
1723
1655 /* if we have made the queue un-full, notify the adapter */
1656 if (notify && (aac_qinfo[queue].notify != 0))
1657 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1658 error = 0;
1724 /* if we have made the queue un-full, notify the adapter */
1725 if (notify && (aac_qinfo[queue].notify != 0))
1726 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1727 error = 0;
1659
1660out:
1728
1729out:
1661 splx(s);
1662 return(error);
1730 splx(s);
1731 return(error);
1663}
1664
1732}
1733
1665/******************************************************************************
1734/*
1666 * Put our response to an Adapter Initialed Fib on the response queue
1667 */
1668static int
1669aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1670{
1735 * Put our response to an Adapter Initialed Fib on the response queue
1736 */
1737static int
1738aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1739{
1671 u_int32_t pi, ci;
1672 int s, error;
1673 u_int32_t fib_size;
1674 u_int32_t fib_addr;
1740 u_int32_t pi, ci;
1741 int s, error;
1742 u_int32_t fib_size;
1743 u_int32_t fib_addr;
1675
1744
1676 debug_called(1);
1745 debug_called(1);
1677
1746
1678 /* Tell the adapter where the FIB is */
1679 fib_size = fib->Header.Size;
1680 fib_addr = fib->Header.SenderFibAddress;
1681 fib->Header.ReceiverFibAddress = fib_addr;
1747 /* Tell the adapter where the FIB is */
1748 fib_size = fib->Header.Size;
1749 fib_addr = fib->Header.SenderFibAddress;
1750 fib->Header.ReceiverFibAddress = fib_addr;
1682
1751
1683 s = splbio();
1752 s = splbio();
1684
1753
1685 /* get the producer/consumer indices */
1686 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1687 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1754 /* get the producer/consumer indices */
1755 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1756 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1688
1757
1689 /* wrap the queue? */
1690 if (pi >= aac_qinfo[queue].size)
1691 pi = 0;
1758 /* wrap the queue? */
1759 if (pi >= aac_qinfo[queue].size)
1760 pi = 0;
1692
1761
1693 /* check for queue full */
1694 if ((pi + 1) == ci) {
1695 error = EBUSY;
1696 goto out;
1697 }
1762 /* check for queue full */
1763 if ((pi + 1) == ci) {
1764 error = EBUSY;
1765 goto out;
1766 }
1698
1767
1699 /* populate queue entry */
1700 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1701 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1768 /* populate queue entry */
1769 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1770 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1702
1771
1703 /* update producer index */
1704 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1772 /* update producer index */
1773 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1705
1774
1706 /* notify the adapter if we know how */
1707 if (aac_qinfo[queue].notify != 0)
1708 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1775 /* notify the adapter if we know how */
1776 if (aac_qinfo[queue].notify != 0)
1777 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1709
1778
1710 error = 0;
1779 error = 0;
1711
1712out:
1780
1781out:
1713 splx(s);
1714 return(error);
1782 splx(s);
1783 return(error);
1715}
1716
1784}
1785
1717/******************************************************************************
1786/*
1718 * Check for commands that have been outstanding for a suspiciously long time,
1719 * and complain about them.
1720 */
1721static void
1722aac_timeout(struct aac_softc *sc)
1723{
1787 * Check for commands that have been outstanding for a suspiciously long time,
1788 * and complain about them.
1789 */
1790static void
1791aac_timeout(struct aac_softc *sc)
1792{
1724 int s;
1725 struct aac_command *cm;
1726 time_t deadline;
1793 int s;
1794 struct aac_command *cm;
1795 time_t deadline;
1727
1728#if 0
1796
1797#if 0
1729 /* simulate an interrupt to handle possibly-missed interrupts */
1730 /*
1731 * XXX This was done to work around another bug which has since been
1732 * fixed. It is dangerous anyways because you don't want multiple
1733 * threads in the interrupt handler at the same time! If calling
1734 * is deamed neccesary in the future, proper mutexes must be used.
1735 */
1736 s = splbio();
1737 aac_intr(sc);
1738 splx(s);
1798 /* simulate an interrupt to handle possibly-missed interrupts */
1799 /*
1800 * XXX This was done to work around another bug which has since been
1801 * fixed. It is dangerous anyways because you don't want multiple
1802 * threads in the interrupt handler at the same time! If calling
1803 * is deamed neccesary in the future, proper mutexes must be used.
1804 */
1805 s = splbio();
1806 aac_intr(sc);
1807 splx(s);
1739
1808
1740 /* kick the I/O queue to restart it in the case of deadlock */
1741 aac_startio(sc);
1809 /* kick the I/O queue to restart it in the case of deadlock */
1810 aac_startio(sc);
1742#endif
1743
1811#endif
1812
1744 /* traverse the busy command list, bitch about late commands once only */
1745 deadline = time_second - AAC_CMD_TIMEOUT;
1746 s = splbio();
1747 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1748 if ((cm->cm_timestamp < deadline)
1749 /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
1750 cm->cm_flags |= AAC_CMD_TIMEDOUT;
1751 device_printf(sc->aac_dev, "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
1752 cm, (int)(time_second - cm->cm_timestamp));
1753 AAC_PRINT_FIB(sc, cm->cm_fib);
1813 /*
1814 * traverse the busy command list, bitch about late commands once
1815 * only.
1816 */
1817 deadline = time_second - AAC_CMD_TIMEOUT;
1818 s = splbio();
1819 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1820 if ((cm->cm_timestamp < deadline)
1821 /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
1822 cm->cm_flags |= AAC_CMD_TIMEDOUT;
1823 device_printf(sc->aac_dev,
1824 "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
1825 cm, (int)(time_second-cm->cm_timestamp));
1826 AAC_PRINT_FIB(sc, cm->cm_fib);
1827 }
1754 }
1828 }
1755 }
1756 splx(s);
1829 splx(s);
1757
1830
1758 /* reset the timer for next time */
1759 timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz);
1760 return;
1831 /* reset the timer for next time */
1832 timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz);
1833 return;
1761}
1762
1834}
1835
1763/******************************************************************************
1764 ******************************************************************************
1765 Interface Function Vectors
1766 ******************************************************************************
1767 ******************************************************************************/
1836/*
1837 * Interface Function Vectors
1838 */
1768
1839
1769/******************************************************************************
1840/*
1770 * Read the current firmware status word.
1771 */
1772static int
1773aac_sa_get_fwstatus(struct aac_softc *sc)
1774{
1841 * Read the current firmware status word.
1842 */
1843static int
1844aac_sa_get_fwstatus(struct aac_softc *sc)
1845{
1775 debug_called(3);
1846 debug_called(3);
1776
1847
1777 return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1848 return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1778}
1779
1780static int
1781aac_rx_get_fwstatus(struct aac_softc *sc)
1782{
1849}
1850
1851static int
1852aac_rx_get_fwstatus(struct aac_softc *sc)
1853{
1783 debug_called(3);
1854 debug_called(3);
1784
1855
1785 return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1856 return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1786}
1787
1857}
1858
1788/******************************************************************************
1859/*
1789 * Notify the controller of a change in a given queue
1790 */
1791
1792static void
1793aac_sa_qnotify(struct aac_softc *sc, int qbit)
1794{
1860 * Notify the controller of a change in a given queue
1861 */
1862
1863static void
1864aac_sa_qnotify(struct aac_softc *sc, int qbit)
1865{
1795 debug_called(3);
1866 debug_called(3);
1796
1867
1797 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1868 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1798}
1799
1800static void
1801aac_rx_qnotify(struct aac_softc *sc, int qbit)
1802{
1869}
1870
1871static void
1872aac_rx_qnotify(struct aac_softc *sc, int qbit)
1873{
1803 debug_called(3);
1874 debug_called(3);
1804
1875
1805 AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1876 AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1806}
1807
1877}
1878
1808/******************************************************************************
1879/*
1809 * Get the interrupt reason bits
1810 */
1811static int
1812aac_sa_get_istatus(struct aac_softc *sc)
1813{
1880 * Get the interrupt reason bits
1881 */
1882static int
1883aac_sa_get_istatus(struct aac_softc *sc)
1884{
1814 debug_called(3);
1885 debug_called(3);
1815
1886
1816 return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1887 return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1817}
1818
1819static int
1820aac_rx_get_istatus(struct aac_softc *sc)
1821{
1888}
1889
1890static int
1891aac_rx_get_istatus(struct aac_softc *sc)
1892{
1822 debug_called(3);
1893 debug_called(3);
1823
1894
1824 return(AAC_GETREG4(sc, AAC_RX_ODBR));
1895 return(AAC_GETREG4(sc, AAC_RX_ODBR));
1825}
1826
1896}
1897
1827/******************************************************************************
1898/*
1828 * Clear some interrupt reason bits
1829 */
1830static void
1831aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1832{
1899 * Clear some interrupt reason bits
1900 */
1901static void
1902aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1903{
1833 debug_called(3);
1904 debug_called(3);
1834
1905
1835 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1906 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1836}
1837
1838static void
1839aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1840{
1907}
1908
1909static void
1910aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1911{
1841 debug_called(3);
1912 debug_called(3);
1842
1913
1843 AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1914 AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1844}
1845
1915}
1916
1846/******************************************************************************
1917/*
1847 * Populate the mailbox and set the command word
1848 */
1849static void
1850aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
1851 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1852{
1918 * Populate the mailbox and set the command word
1919 */
1920static void
1921aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
1922 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1923{
1853 debug_called(4);
1924 debug_called(4);
1854
1925
1855 AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1856 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1857 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1858 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1859 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1926 AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1927 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1928 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1929 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1930 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1860}
1861
1862static void
1863aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
1864 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1865{
1931}
1932
1933static void
1934aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
1935 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1936{
1866 debug_called(4);
1937 debug_called(4);
1867
1938
1868 AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1869 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1870 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1871 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1872 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1939 AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1940 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1941 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1942 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1943 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1873}
1874
1944}
1945
1875/******************************************************************************
1946/*
1876 * Fetch the immediate command status word
1877 */
1878static int
1879aac_sa_get_mailboxstatus(struct aac_softc *sc)
1880{
1947 * Fetch the immediate command status word
1948 */
1949static int
1950aac_sa_get_mailboxstatus(struct aac_softc *sc)
1951{
1881 debug_called(4);
1952 debug_called(4);
1882
1953
1883 return(AAC_GETREG4(sc, AAC_SA_MAILBOX));
1954 return(AAC_GETREG4(sc, AAC_SA_MAILBOX));
1884}
1885
1886static int
1887aac_rx_get_mailboxstatus(struct aac_softc *sc)
1888{
1955}
1956
1957static int
1958aac_rx_get_mailboxstatus(struct aac_softc *sc)
1959{
1889 debug_called(4);
1960 debug_called(4);
1890
1961
1891 return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
1962 return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
1892}
1893
1963}
1964
1894/******************************************************************************
1965/*
1895 * Set/clear interrupt masks
1896 */
1897static void
1898aac_sa_set_interrupts(struct aac_softc *sc, int enable)
1899{
1966 * Set/clear interrupt masks
1967 */
1968static void
1969aac_sa_set_interrupts(struct aac_softc *sc, int enable)
1970{
1900 debug(2, "%sable interrupts", enable ? "en" : "dis");
1971 debug(2, "%sable interrupts", enable ? "en" : "dis");
1901
1972
1902 if (enable) {
1903 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
1904 } else {
1905 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
1906 }
1973 if (enable) {
1974 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
1975 } else {
1976 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
1977 }
1907}
1908
1909static void
1910aac_rx_set_interrupts(struct aac_softc *sc, int enable)
1911{
1978}
1979
1980static void
1981aac_rx_set_interrupts(struct aac_softc *sc, int enable)
1982{
1912 debug(2, "%sable interrupts", enable ? "en" : "dis");
1983 debug(2, "%sable interrupts", enable ? "en" : "dis");
1913
1984
1914 if (enable) {
1915 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
1916 } else {
1917 AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
1918 }
1985 if (enable) {
1986 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
1987 } else {
1988 AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
1989 }
1919}
1920
1990}
1991
1921/******************************************************************************
1922 ******************************************************************************
1923 Debugging and Diagnostics
1924 ******************************************************************************
1925 ******************************************************************************/
1992/*
1993 * Debugging and Diagnostics
1994 */
1926
1995
1927/******************************************************************************
1996/*
1928 * Print some information about the controller.
1929 */
1930static void
1931aac_describe_controller(struct aac_softc *sc)
1932{
1997 * Print some information about the controller.
1998 */
1999static void
2000aac_describe_controller(struct aac_softc *sc)
2001{
1933 u_int8_t buf[AAC_FIB_DATASIZE]; /* XXX really a bit big
1934 * for the stack */
1935 u_int16_t bufsize;
1936 struct aac_adapter_info *info;
1937 u_int8_t arg;
2002 u_int8_t buf[AAC_FIB_DATASIZE]; /* XXX really a bit big
2003 * for the stack */
2004 u_int16_t bufsize;
2005 struct aac_adapter_info *info;
2006 u_int8_t arg;
1938
2007
1939 debug_called(2);
2008 debug_called(2);
1940
2009
1941 arg = 0;
1942 bufsize = sizeof(buf);
1943 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf,
1944 &bufsize)) {
1945 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
1946 return;
1947 }
1948 if (bufsize != sizeof(*info)) {
1949 device_printf(sc->aac_dev, "RequestAdapterInfo returned wrong data "
1950 "size (%d != %d)\n", bufsize, sizeof(*info));
1951 /*return;*/
1952 }
1953 info = (struct aac_adapter_info *)&buf[0];
2010 arg = 0;
2011 bufsize = sizeof(buf);
2012 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf,
2013 &bufsize)) {
2014 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2015 return;
2016 }
2017 if (bufsize != sizeof(*info)) {
2018 device_printf(sc->aac_dev,
2019 "RequestAdapterInfo returned wrong data size "
2020 "(%d != %d)\n", bufsize, sizeof(*info));
2021 /*return;*/
2022 }
2023 info = (struct aac_adapter_info *)&buf[0];
1954
2024
1955 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
1956 aac_describe_code(aac_cpu_variant, info->CpuVariant),
1957 info->ClockSpeed, info->BufferMem / (1024 * 1024),
1958 aac_describe_code(aac_battery_platform, info->batteryPlatform));
2025 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
2026 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2027 info->ClockSpeed, info->BufferMem / (1024 * 1024),
2028 aac_describe_code(aac_battery_platform,
2029 info->batteryPlatform));
1959
2030
1960 /* save the kernel revision structure for later use */
1961 sc->aac_revision = info->KernelRevision;
1962 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
1963 info->KernelRevision.external.comp.major,
1964 info->KernelRevision.external.comp.minor,
1965 info->KernelRevision.external.comp.dash,
1966 info->KernelRevision.buildNumber,
1967 (u_int32_t)(info->SerialNumber & 0xffffff));
2031 /* save the kernel revision structure for later use */
2032 sc->aac_revision = info->KernelRevision;
2033 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2034 info->KernelRevision.external.comp.major,
2035 info->KernelRevision.external.comp.minor,
2036 info->KernelRevision.external.comp.dash,
2037 info->KernelRevision.buildNumber,
2038 (u_int32_t)(info->SerialNumber & 0xffffff));
1968}
1969
2039}
2040
1970/******************************************************************************
2041/*
1971 * Look up a text description of a numeric error code and return a pointer to
1972 * same.
1973 */
1974static char *
1975aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
1976{
2042 * Look up a text description of a numeric error code and return a pointer to
2043 * same.
2044 */
2045static char *
2046aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2047{
1977 int i;
2048 int i;
1978
2049
1979 for (i = 0; table[i].string != NULL; i++)
1980 if (table[i].code == code)
1981 return(table[i].string);
1982 return(table[i + 1].string);
2050 for (i = 0; table[i].string != NULL; i++)
2051 if (table[i].code == code)
2052 return(table[i].string);
2053 return(table[i + 1].string);
1983}
1984
2054}
2055
1985/*****************************************************************************
1986 *****************************************************************************
1987 Management Interface
1988 *****************************************************************************
1989 *****************************************************************************/
2056/*
2057 * Management Interface
2058 */
1990
1991static int
1992aac_open(dev_t dev, int flags, int fmt, struct proc *p)
1993{
2059
2060static int
2061aac_open(dev_t dev, int flags, int fmt, struct proc *p)
2062{
1994 struct aac_softc *sc = dev->si_drv1;
2063 struct aac_softc *sc;
1995
2064
1996 debug_called(2);
2065 debug_called(2);
1997
2066
1998 /* Check to make sure the device isn't already open */
1999 if (sc->aac_state & AAC_STATE_OPEN) {
2000 return EBUSY;
2001 }
2002 sc->aac_state |= AAC_STATE_OPEN;
2067 sc = dev->si_drv1;
2003
2068
2004 return 0;
2069 /* Check to make sure the device isn't already open */
2070 if (sc->aac_state & AAC_STATE_OPEN) {
2071 return EBUSY;
2072 }
2073 sc->aac_state |= AAC_STATE_OPEN;
2074
2075 return 0;
2005}
2006
2007static int
2008aac_close(dev_t dev, int flags, int fmt, struct proc *p)
2009{
2076}
2077
2078static int
2079aac_close(dev_t dev, int flags, int fmt, struct proc *p)
2080{
2010 struct aac_softc *sc = dev->si_drv1;
2081 struct aac_softc *sc;
2011
2082
2012 debug_called(2);
2083 debug_called(2);
2013
2084
2014 /* Mark this unit as no longer open */
2015 sc->aac_state &= ~AAC_STATE_OPEN;
2085 sc = dev->si_drv1;
2016
2086
2017 return 0;
2087 /* Mark this unit as no longer open */
2088 sc->aac_state &= ~AAC_STATE_OPEN;
2089
2090 return 0;
2018}
2019
2020static int
2021aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
2022{
2091}
2092
2093static int
2094aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
2095{
2023 union aac_statrequest *as = (union aac_statrequest *)arg;
2024 struct aac_softc *sc = dev->si_drv1;
2025 int error = 0;
2026 int i;
2096 union aac_statrequest *as;
2097 struct aac_softc *sc;
2098 int error = 0;
2099 int i;
2027
2100
2028 debug_called(2);
2101 debug_called(2);
2029
2102
2030 switch (cmd) {
2031 case AACIO_STATS:
2032 switch (as->as_item) {
2033 case AACQ_FREE:
2034 case AACQ_BIO:
2035 case AACQ_READY:
2036 case AACQ_BUSY:
2037 case AACQ_COMPLETE:
2038 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2039 sizeof(struct aac_qstat));
2040 break;
2041 default:
2042 error = ENOENT;
2043 break;
2044 }
2103 as = (union aac_statrequest *)arg;
2104 sc = dev->si_drv1;
2105
2106 switch (cmd) {
2107 case AACIO_STATS:
2108 switch (as->as_item) {
2109 case AACQ_FREE:
2110 case AACQ_BIO:
2111 case AACQ_READY:
2112 case AACQ_BUSY:
2113 case AACQ_COMPLETE:
2114 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2115 sizeof(struct aac_qstat));
2116 break;
2117 default:
2118 error = ENOENT;
2119 break;
2120 }
2045 break;
2046
2121 break;
2122
2047 case FSACTL_SENDFIB:
2048 arg = *(caddr_t*)arg;
2049 case FSACTL_LNX_SENDFIB:
2050 debug(1, "FSACTL_SENDFIB");
2051 error = aac_ioctl_sendfib(sc, arg);
2052 break;
2053 case FSACTL_AIF_THREAD:
2054 case FSACTL_LNX_AIF_THREAD:
2055 debug(1, "FSACTL_AIF_THREAD");
2056 error = EINVAL;
2057 break;
2058 case FSACTL_OPEN_GET_ADAPTER_FIB:
2059 arg = *(caddr_t*)arg;
2060 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2061 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
2062 /*
2063 * Pass the caller out an AdapterFibContext.
2064 *
2065 * Note that because we only support one opener, we
2066 * basically ignore this. Set the caller's context to a magic
2067 * number just in case.
2068 *
2069 * The Linux code hands the driver a pointer into kernel space,
2070 * and then trusts it when the caller hands it back. Aiee!
2071 * Here, we give it the proc pointer of the per-adapter aif thread.
2072 * It's only used as a sanity check in other calls.
2073 */
2074 i = (int)sc->aifthread;
2075 error = copyout(&i, arg, sizeof(i));
2076 break;
2077 case FSACTL_GET_NEXT_ADAPTER_FIB:
2078 arg = *(caddr_t*)arg;
2079 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2080 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
2081 error = aac_getnext_aif(sc, arg);
2082 break;
2083 case FSACTL_CLOSE_GET_ADAPTER_FIB:
2084 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2085 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2086 /* don't do anything here */
2087 break;
2088 case FSACTL_MINIPORT_REV_CHECK:
2089 arg = *(caddr_t*)arg;
2090 case FSACTL_LNX_MINIPORT_REV_CHECK:
2091 debug(1, "FSACTL_MINIPORT_REV_CHECK");
2092 error = aac_rev_check(sc, arg);
2093 break;
2094 case FSACTL_QUERY_DISK:
2095 arg = *(caddr_t*)arg;
2096 case FSACTL_LNX_QUERY_DISK:
2097 debug(1, "FSACTL_QUERY_DISK");
2098 error = aac_query_disk(sc, arg);
2099 break;
2100 case FSACTL_DELETE_DISK:
2101 case FSACTL_LNX_DELETE_DISK:
2102 error = 0;
2103 break;
2104 default:
2105 device_printf(sc->aac_dev, "unsupported cmd 0x%lx\n", cmd);
2106 error = EINVAL;
2107 break;
2108 }
2109 return(error);
2123 case FSACTL_SENDFIB:
2124 arg = *(caddr_t*)arg;
2125 case FSACTL_LNX_SENDFIB:
2126 debug(1, "FSACTL_SENDFIB");
2127 error = aac_ioctl_sendfib(sc, arg);
2128 break;
2129 case FSACTL_AIF_THREAD:
2130 case FSACTL_LNX_AIF_THREAD:
2131 debug(1, "FSACTL_AIF_THREAD");
2132 error = EINVAL;
2133 break;
2134 case FSACTL_OPEN_GET_ADAPTER_FIB:
2135 arg = *(caddr_t*)arg;
2136 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2137 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
2138 /*
2139 * Pass the caller out an AdapterFibContext.
2140 *
2141 * Note that because we only support one opener, we
2142 * basically ignore this. Set the caller's context to a magic
2143 * number just in case.
2144 *
2145 * The Linux code hands the driver a pointer into kernel space,
2146 * and then trusts it when the caller hands it back. Aiee!
2147 * Here, we give it the proc pointer of the per-adapter aif
2148 * thread. It's only used as a sanity check in other calls.
2149 */
2150 i = (int)sc->aifthread;
2151 error = copyout(&i, arg, sizeof(i));
2152 break;
2153 case FSACTL_GET_NEXT_ADAPTER_FIB:
2154 arg = *(caddr_t*)arg;
2155 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2156 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
2157 error = aac_getnext_aif(sc, arg);
2158 break;
2159 case FSACTL_CLOSE_GET_ADAPTER_FIB:
2160 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2161 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2162 /* don't do anything here */
2163 break;
2164 case FSACTL_MINIPORT_REV_CHECK:
2165 arg = *(caddr_t*)arg;
2166 case FSACTL_LNX_MINIPORT_REV_CHECK:
2167 debug(1, "FSACTL_MINIPORT_REV_CHECK");
2168 error = aac_rev_check(sc, arg);
2169 break;
2170 case FSACTL_QUERY_DISK:
2171 arg = *(caddr_t*)arg;
2172 case FSACTL_LNX_QUERY_DISK:
2173 debug(1, "FSACTL_QUERY_DISK");
2174 error = aac_query_disk(sc, arg);
2175 break;
2176 case FSACTL_DELETE_DISK:
2177 case FSACTL_LNX_DELETE_DISK:
2178 /*
2179 * We don't trust the underland to tell us when to delete a
2180 * container, rather we rely on an AIF coming from the
2181 * controller
2182 */
2183 error = 0;
2184 break;
2185 default:
2186 device_printf(sc->aac_dev, "unsupported cmd 0x%lx\n", cmd);
2187 error = EINVAL;
2188 break;
2189 }
2190 return(error);
2110}
2111
2191}
2192
2112/******************************************************************************
2193/*
2113 * Send a FIB supplied from userspace
2114 */
2115static int
2116aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2117{
2194 * Send a FIB supplied from userspace
2195 */
2196static int
2197aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2198{
2118 struct aac_command *cm;
2119 int size, error;
2199 struct aac_command *cm;
2200 int size, error;
2120
2201
2121 debug_called(2);
2202 debug_called(2);
2122
2203
2123 cm = NULL;
2204 cm = NULL;
2124
2205
2125 /*
2126 * Get a command
2127 */
2128 if (aac_alloc_command(sc, &cm)) {
2129 error = EBUSY;
2130 goto out;
2131 }
2206 /*
2207 * Get a command
2208 */
2209 if (aac_alloc_command(sc, &cm)) {
2210 error = EBUSY;
2211 goto out;
2212 }
2132
2213
2133 /*
2134 * Fetch the FIB header, then re-copy to get data as well.
2135 */
2136 if ((error = copyin(ufib, cm->cm_fib, sizeof(struct aac_fib_header))) != 0)
2137 goto out;
2138 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2139 if (size > sizeof(struct aac_fib)) {
2140 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n", size,
2141 sizeof(struct aac_fib));
2142 size = sizeof(struct aac_fib);
2143 }
2144 if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
2145 goto out;
2146 cm->cm_fib->Header.Size = size;
2147 cm->cm_timestamp = time_second;
2214 /*
2215 * Fetch the FIB header, then re-copy to get data as well.
2216 */
2217 if ((error = copyin(ufib, cm->cm_fib,
2218 sizeof(struct aac_fib_header))) != 0)
2219 goto out;
2220 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2221 if (size > sizeof(struct aac_fib)) {
2222 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
2223 size, sizeof(struct aac_fib));
2224 size = sizeof(struct aac_fib);
2225 }
2226 if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
2227 goto out;
2228 cm->cm_fib->Header.Size = size;
2229 cm->cm_timestamp = time_second;
2148
2230
2149 /*
2150 * Pass the FIB to the controller, wait for it to complete.
2151 */
2152 if ((error = aac_wait_command(cm, 30)) != 0) /* XXX user timeout? */
2153 goto out;
2231 /*
2232 * Pass the FIB to the controller, wait for it to complete.
2233 */
2234 if ((error = aac_wait_command(cm, 30)) != 0) /* XXX user timeout? */
2235 goto out;
2154
2236
2155 /*
2156 * Copy the FIB and data back out to the caller.
2157 */
2158 size = cm->cm_fib->Header.Size;
2159 if (size > sizeof(struct aac_fib)) {
2160 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n", size,
2161 sizeof(struct aac_fib));
2162 size = sizeof(struct aac_fib);
2163 }
2164 error = copyout(cm->cm_fib, ufib, size);
2237 /*
2238 * Copy the FIB and data back out to the caller.
2239 */
2240 size = cm->cm_fib->Header.Size;
2241 if (size > sizeof(struct aac_fib)) {
2242 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
2243 size, sizeof(struct aac_fib));
2244 size = sizeof(struct aac_fib);
2245 }
2246 error = copyout(cm->cm_fib, ufib, size);
2165
2166out:
2247
2248out:
2167 if (cm != NULL) {
2168 aac_release_command(cm);
2169 }
2170 return(error);
2249 if (cm != NULL) {
2250 aac_release_command(cm);
2251 }
2252 return(error);
2171}
2172
2253}
2254
2173/******************************************************************************
2255/*
2174 * Handle an AIF sent to us by the controller; queue it for later reference.
2175 * If the queue fills up, then drop the older entries.
2176 */
2177static void
2178aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
2179{
2256 * Handle an AIF sent to us by the controller; queue it for later reference.
2257 * If the queue fills up, then drop the older entries.
2258 */
2259static void
2260aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
2261{
2180 device_t child;
2181 struct aac_aif_command *aif;
2182 struct aac_container *co, *co_next;
2183 struct aac_mntinfo mi;
2184 struct aac_mntinforesponse mir;
2185 u_int16_t rsize;
2186 int next, s, found;
2187 int added = 0, i = 0;
2262 struct aac_aif_command *aif;
2263 struct aac_container *co, *co_next;
2264 struct aac_mntinfo mi;
2265 struct aac_mntinforesponse mir;
2266 u_int16_t rsize;
2267 int next, s, found;
2268 int added = 0, i = 0;
2188
2269
2189 debug_called(2);
2270 debug_called(2);
2190
2271
2191 aif = (struct aac_aif_command*)&fib->data[0];
2192 aac_print_aif(sc, aif);
2272 aif = (struct aac_aif_command*)&fib->data[0];
2273 aac_print_aif(sc, aif);
2193
2274
2194 /* Is it an event that we should care about? */
2195 switch (aif->command) {
2196 case AifCmdEventNotify:
2197 switch (aif->data.EN.type) {
2198 case AifEnAddContainer:
2199 case AifEnDeleteContainer:
2200 /*
2201 * A container was added or deleted, but the message doesn't tell us
2202 * anything else! Re-enumerate the containers and sort things out.
2203 */
2204 mi.Command = VM_NameServe;
2205 mi.MntType = FT_FILESYS;
2206 do {
2207 /*
2208 * Ask the controller for its containers one at a time.
2209 * XXX What if the controller's list changes midway through
2210 * this enumaration?
2211 * XXX This should be done async.
2212 */
2213 mi.MntCount = i;
2214 rsize = sizeof(mir);
2215 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi),
2216 &mir, &rsize)) {
2217 debug(2, "Error probing container %d\n", i);
2218 continue;
2219 }
2220 if (rsize != sizeof(mir)) {
2221 debug(2, "Container response size too large\n");
2222 continue;
2223 }
2224 /*
2225 * Check the container against our list. co->co_found
2226 * was already set to 0 in a previous run.
2227 */
2228 if ((mir.Status == ST_OK) && (mir.MntTable[0].VolType !=
2229 CT_NONE)) {
2230 found = 0;
2231 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
2232 if (co->co_mntobj.ObjectId ==
2233 mir.MntTable[0].ObjectId) {
2234 co->co_found = 1;
2235 found = 1;
2236 break;
2275 /* Is it an event that we should care about? */
2276 switch (aif->command) {
2277 case AifCmdEventNotify:
2278 switch (aif->data.EN.type) {
2279 case AifEnAddContainer:
2280 case AifEnDeleteContainer:
2281 /*
2282 * A container was added or deleted, but the message
2283 * doesn't tell us anything else! Re-enumerate the
2284 * containers and sort things out.
2285 */
2286 mi.Command = VM_NameServe;
2287 mi.MntType = FT_FILESYS;
2288 do {
2289 /*
2290 * Ask the controller for its containers one at
2291 * a time.
2292 * XXX What if the controller's list changes
2293 * midway through this enumaration?
2294 * XXX This should be done async.
2295 */
2296 mi.MntCount = i;
2297 rsize = sizeof(mir);
2298 if (aac_sync_fib(sc, ContainerCommand, 0, &mi,
2299 sizeof(mi), &mir, &rsize)) {
2300 debug(2, "Error probing container %d\n",
2301 i);
2302 continue;
2303 }
2304 if (rsize != sizeof(mir)) {
2305 debug(2, "Container response size too "
2306 "large\n");
2307 continue;
2308 }
2309 /*
2310 * Check the container against our list.
2311 * co->co_found was already set to 0 in a
2312 * previous run.
2313 */
2314 if ((mir.Status == ST_OK) &&
2315 (mir.MntTable[0].VolType != CT_NONE)) {
2316 found = 0;
2317 TAILQ_FOREACH(co,
2318 &sc->aac_container_tqh,
2319 co_link) {
2320 if (co->co_mntobj.ObjectId ==
2321 mir.MntTable[0].ObjectId) {
2322 co->co_found = 1;
2323 found = 1;
2324 break;
2325 }
2326 }
2327 /*
2328 * If the container matched, continue
2329 * in the list.
2330 */
2331 if (found) {
2332 i++;
2333 continue;
2334 }
2335
2336 /*
2337 * This is a new container. Do all the
2338 * appropriate things to set it up. */
2339 aac_add_container(sc, &mir, 1);
2340 added = 1;
2341 }
2342 i++;
2343 } while ((i < mir.MntRespCount) &&
2344 (i < AAC_MAX_CONTAINERS));
2345
2346 /*
2347 * Go through our list of containers and see which ones
2348 * were not marked 'found'. Since the controller didn't
2349 * list them they must have been deleted. Do the
2350 * appropriate steps to destroy the device. Also reset
2351 * the co->co_found field.
2352 */
2353 co = TAILQ_FIRST(&sc->aac_container_tqh);
2354 while (co != NULL) {
2355 if (co->co_found == 0) {
2356 device_delete_child(sc->aac_dev,
2357 co->co_disk);
2358 co_next = TAILQ_NEXT(co, co_link);
2359 AAC_LOCK_AQUIRE(&sc->
2360 aac_container_lock);
2361 TAILQ_REMOVE(&sc->aac_container_tqh, co,
2362 co_link);
2363 AAC_LOCK_RELEASE(&sc->
2364 aac_container_lock);
2365 FREE(co, M_AACBUF);
2366 co = co_next;
2367 } else {
2368 co->co_found = 0;
2369 co = TAILQ_NEXT(co, co_link);
2370 }
2237 }
2371 }
2238 }
2239 /* If the container matched, continue on in the list */
2240 if (found) {
2241 i++;
2242 continue;
2243 }
2244
2372
2245 /*
2246 * This is a new container. Do all the appropriate things
2247 * to set it up.
2248 */
2249 MALLOC(co, struct aac_container *, sizeof *co, M_AACBUF,
2250 M_WAITOK);
2251 if ((child = device_add_child(sc->aac_dev, NULL, -1)) ==
2252 NULL) {
2253 device_printf(sc->aac_dev, "device_add_child failed\n");
2254 } else {
2255 device_set_ivars(child, co);
2256 }
2257 device_set_desc(child,
2258 aac_describe_code(aac_container_types,
2259 mir.MntTable[0].VolType));
2260 co->co_disk = child;
2261 co->co_found = 1;
2262 bcopy(&mir.MntTable[0], &co->co_mntobj,
2263 sizeof(struct aac_mntobj));
2264 AAC_LOCK_AQUIRE(&sc->aac_container_lock);
2265 TAILQ_INSERT_HEAD(&sc->aac_container_tqh, co, co_link);
2266 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2267 added = 1;
2268 }
2269 i++;
2270 } while ((i < mir.MntRespCount) && (i < AAC_MAX_CONTAINERS));
2373 /* Attach the newly created containers */
2374 if (added)
2375 bus_generic_attach(sc->aac_dev);
2376
2377 break;
2271
2378
2272 /*
2273 * Go through our list of containers and see which ones were
2274 * not marked 'found'. Since the controller didn't list them
2275 * they must have been deleted. Do the appropriate steps to
2276 * destroy the device. Also reset the co->co_found field.
2277 */
2278 co = TAILQ_FIRST(&sc->aac_container_tqh);
2279 while (co != NULL) {
2280 if (co->co_found == 0) {
2281 device_delete_child(sc->aac_dev, co->co_disk);
2282 co_next = TAILQ_NEXT(co, co_link);
2283 AAC_LOCK_AQUIRE(&sc->aac_container_lock);
2284 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
2285 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2286 FREE(co, M_AACBUF);
2287 co = co_next;
2288 } else {
2289 co->co_found = 0;
2290 co = TAILQ_NEXT(co, co_link);
2379 default:
2380 break;
2291 }
2381 }
2292 }
2293
2382
2294 /* Attach the newly created containers */
2295 if (added)
2296 bus_generic_attach(sc->aac_dev);
2297
2298 break;
2299
2300 default:
2383 default:
2301 break;
2384 break;
2302 }
2303
2385 }
2386
2304 default:
2305 break;
2306 }
2307
2308 /* Copy the AIF data to the AIF queue for ioctl retrieval */
2309 s = splbio();
2310 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
2311 if (next != sc->aac_aifq_tail) {
2312 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
2387 /* Copy the AIF data to the AIF queue for ioctl retrieval */
2388 s = splbio();
2389 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
2390 if (next != sc->aac_aifq_tail) {
2391 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
2313 sc->aac_aifq_head = next;
2314 if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
2392 sc->aac_aifq_head = next;
2393 if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
2315 wakeup(sc->aac_aifq);
2316 }
2317 splx(s);
2394 wakeup(sc->aac_aifq);
2395 }
2396 splx(s);
2318
2397
2319 return;
2398 return;
2320}
2321
2399}
2400
2322/******************************************************************************
2323 ******************************************************************************
2324 Linux Management Interface
2325 ******************************************************************************
2326 ******************************************************************************/
2401/*
2402 * Linux Management Interface
2403 * This is soon to be removed!
2404 */
2327
2328#ifdef AAC_COMPAT_LINUX
2329
2330#include <sys/proc.h>
2331#include <machine/../linux/linux.h>
2332#include <machine/../linux/linux_proto.h>
2333#include <compat/linux/linux_ioctl.h>
2334
2405
2406#ifdef AAC_COMPAT_LINUX
2407
2408#include <sys/proc.h>
2409#include <machine/../linux/linux.h>
2410#include <machine/../linux/linux_proto.h>
2411#include <compat/linux/linux_ioctl.h>
2412
2413/* There are multiple ioctl number ranges that need to be handled */
2335#define AAC_LINUX_IOCTL_MIN 0x0000
2336#define AAC_LINUX_IOCTL_MAX 0x21ff
2337
2338static linux_ioctl_function_t aac_linux_ioctl;
2339static struct linux_ioctl_handler aac_handler = {aac_linux_ioctl,
2340 AAC_LINUX_IOCTL_MIN,
2341 AAC_LINUX_IOCTL_MAX};
2342
2343SYSINIT (aac_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
2344 linux_ioctl_register_handler, &aac_handler);
2345SYSUNINIT(aac_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
2346 linux_ioctl_unregister_handler, &aac_handler);
2347
2348MODULE_DEPEND(aac, linux, 1, 1, 1);
2349
2350static int
2351aac_linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
2352{
2414#define AAC_LINUX_IOCTL_MIN 0x0000
2415#define AAC_LINUX_IOCTL_MAX 0x21ff
2416
2417static linux_ioctl_function_t aac_linux_ioctl;
2418static struct linux_ioctl_handler aac_handler = {aac_linux_ioctl,
2419 AAC_LINUX_IOCTL_MIN,
2420 AAC_LINUX_IOCTL_MAX};
2421
2422SYSINIT (aac_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
2423 linux_ioctl_register_handler, &aac_handler);
2424SYSUNINIT(aac_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
2425 linux_ioctl_unregister_handler, &aac_handler);
2426
2427MODULE_DEPEND(aac, linux, 1, 1, 1);
2428
2429static int
2430aac_linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
2431{
2353 struct file *fp = p->p_fd->fd_ofiles[args->fd];
2354 u_long cmd = args->cmd;
2432 struct file *fp;
2433 u_long cmd;
2355
2434
2356 debug_called(2);
2357 /*
2358 * Pass the ioctl off to our standard handler.
2359 */
2360 return(fo_ioctl(fp, cmd, (caddr_t)args->arg, p));
2435 debug_called(2);
2436
2437 fp = p->p_fd->fd_ofiles[args->fd];
2438 cmd = args->cmd;
2439
2440 /*
2441 * Pass the ioctl off to our standard handler.
2442 */
2443 return(fo_ioctl(fp, cmd, (caddr_t)args->arg, p));
2361}
2362
2363#endif
2364
2444}
2445
2446#endif
2447
2365/******************************************************************************
2448/*
2366 * Return the Revision of the driver to userspace and check to see if the
2367 * userspace app is possibly compatible. This is extremely bogus since
2368 * our driver doesn't follow Adaptec's versioning system. Cheat by just
2369 * returning what the card reported.
2370 */
2371static int
2372aac_rev_check(struct aac_softc *sc, caddr_t udata)
2373{
2449 * Return the Revision of the driver to userspace and check to see if the
2450 * userspace app is possibly compatible. This is extremely bogus since
2451 * our driver doesn't follow Adaptec's versioning system. Cheat by just
2452 * returning what the card reported.
2453 */
2454static int
2455aac_rev_check(struct aac_softc *sc, caddr_t udata)
2456{
2374 struct aac_rev_check rev_check;
2375 struct aac_rev_check_resp rev_check_resp;
2376 int error = 0;
2457 struct aac_rev_check rev_check;
2458 struct aac_rev_check_resp rev_check_resp;
2459 int error = 0;
2377
2460
2378 debug_called(2);
2461 debug_called(2);
2379
2462
2380 /*
2381 * Copyin the revision struct from userspace
2382 */
2383 if ((error = copyin(udata, (caddr_t)&rev_check,
2463 /*
2464 * Copyin the revision struct from userspace
2465 */
2466 if ((error = copyin(udata, (caddr_t)&rev_check,
2384 sizeof(struct aac_rev_check))) != 0) {
2467 sizeof(struct aac_rev_check))) != 0) {
2385 return error;
2386 }
2468 return error;
2469 }
2387
2470
2388 debug(2, "Userland revision= %d\n", rev_check.callingRevision.buildNumber);
2471 debug(2, "Userland revision= %d\n",
2472 rev_check.callingRevision.buildNumber);
2389
2473
2390 /*
2391 * Doctor up the response struct.
2392 */
2393 rev_check_resp.possiblyCompatible = 1;
2394 rev_check_resp.adapterSWRevision.external.ul = sc->aac_revision.external.ul;
2395 rev_check_resp.adapterSWRevision.buildNumber = sc->aac_revision.buildNumber;
2474 /*
2475 * Doctor up the response struct.
2476 */
2477 rev_check_resp.possiblyCompatible = 1;
2478 rev_check_resp.adapterSWRevision.external.ul =
2479 sc->aac_revision.external.ul;
2480 rev_check_resp.adapterSWRevision.buildNumber =
2481 sc->aac_revision.buildNumber;
2396
2482
2397 return(copyout((caddr_t)&rev_check_resp, udata,
2398 sizeof(struct aac_rev_check_resp)));
2483 return(copyout((caddr_t)&rev_check_resp, udata,
2484 sizeof(struct aac_rev_check_resp)));
2399}
2400
2485}
2486
2401/******************************************************************************
2487/*
2402 * Pass the caller the next AIF in their queue
2403 */
2404static int
2405aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
2406{
2488 * Pass the caller the next AIF in their queue
2489 */
2490static int
2491aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
2492{
2407 struct get_adapter_fib_ioctl agf;
2408 int error, s;
2493 struct get_adapter_fib_ioctl agf;
2494 int error, s;
2409
2495
2410 debug_called(2);
2496 debug_called(2);
2411
2497
2412 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
2498 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
2413
2499
2414 /*
2415 * Check the magic number that we gave the caller.
2416 */
2417 if (agf.AdapterFibContext != (int)sc->aifthread) {
2418 error = EFAULT;
2419 } else {
2420
2421 s = splbio();
2422 error = aac_return_aif(sc, agf.AifFib);
2423
2424 if ((error == EAGAIN) && (agf.Wait)) {
2425 sc->aac_state |= AAC_STATE_AIF_SLEEPER;
2426 while (error == EAGAIN) {
2427 error = tsleep(sc->aac_aifq, PRIBIO | PCATCH, "aacaif", 0);
2428 if (error == 0)
2500 /*
2501 * Check the magic number that we gave the caller.
2502 */
2503 if (agf.AdapterFibContext != (int)sc->aifthread) {
2504 error = EFAULT;
2505 } else {
2506
2507 s = splbio();
2429 error = aac_return_aif(sc, agf.AifFib);
2508 error = aac_return_aif(sc, agf.AifFib);
2509
2510 if ((error == EAGAIN) && (agf.Wait)) {
2511 sc->aac_state |= AAC_STATE_AIF_SLEEPER;
2512 while (error == EAGAIN) {
2513 error = tsleep(sc->aac_aifq, PRIBIO |
2514 PCATCH, "aacaif", 0);
2515 if (error == 0)
2516 error = aac_return_aif(sc,
2517 agf.AifFib);
2518 }
2519 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
2520 }
2521 splx(s);
2430 }
2522 }
2431 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
2432 }
2433 splx(s);
2434 }
2523 }
2435 }
2436 return(error);
2524 return(error);
2437}
2438
2525}
2526
2439/******************************************************************************
2527/*
2440 * Hand the next AIF off the top of the queue out to userspace.
2441 */
2442static int
2443aac_return_aif(struct aac_softc *sc, caddr_t uptr)
2444{
2528 * Hand the next AIF off the top of the queue out to userspace.
2529 */
2530static int
2531aac_return_aif(struct aac_softc *sc, caddr_t uptr)
2532{
2445 int error, s;
2533 int error, s;
2446
2534
2447 debug_called(2);
2535 debug_called(2);
2448
2536
2449 s = splbio();
2450 if (sc->aac_aifq_tail == sc->aac_aifq_head) {
2451 error = EAGAIN;
2452 } else {
2453 error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr,
2454 sizeof(struct aac_aif_command));
2455 if (error)
2456 printf("aac_return_aif: copyout returned %d\n", error);
2457 if (!error)
2458 sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH;
2459 }
2460 splx(s);
2461 return(error);
2537 s = splbio();
2538 if (sc->aac_aifq_tail == sc->aac_aifq_head) {
2539 error = EAGAIN;
2540 } else {
2541 error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr,
2542 sizeof(struct aac_aif_command));
2543 if (error)
2544 printf("aac_return_aif: copyout returned %d\n", error);
2545 if (!error)
2546 sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) %
2547 AAC_AIFQ_LENGTH;
2548 }
2549 splx(s);
2550 return(error);
2462}
2463
2551}
2552
2464/******************************************************************************
2553/*
2465 * Give the userland some information about the container. The AAC arch
2466 * expects the driver to be a SCSI passthrough type driver, so it expects
2467 * the containers to have b:t:l numbers. Fake it.
2468 */
2469static int
2470aac_query_disk(struct aac_softc *sc, caddr_t uptr)
2471{
2554 * Give the userland some information about the container. The AAC arch
2555 * expects the driver to be a SCSI passthrough type driver, so it expects
2556 * the containers to have b:t:l numbers. Fake it.
2557 */
2558static int
2559aac_query_disk(struct aac_softc *sc, caddr_t uptr)
2560{
2472 struct aac_query_disk query_disk;
2473 struct aac_container *co;
2474 struct aac_disk *disk = NULL;
2475 int error, id;
2561 struct aac_query_disk query_disk;
2562 struct aac_container *co;
2563 struct aac_disk *disk;
2564 int error, id;
2476
2565
2477 debug_called(2);
2566 debug_called(2);
2478
2567
2479 error = copyin(uptr, (caddr_t)&query_disk, sizeof(struct aac_query_disk));
2480 if (error)
2481 return (error);
2568 disk = NULL;
2482
2569
2483 id = query_disk.ContainerNumber;
2484 if (id == -1)
2485 return (EINVAL);
2570 error = copyin(uptr, (caddr_t)&query_disk,
2571 sizeof(struct aac_query_disk));
2572 if (error)
2573 return (error);
2486
2574
2487 AAC_LOCK_AQUIRE(&sc->aac_container_lock);
2488 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
2489 if (co->co_mntobj.ObjectId == id)
2490 break;
2491 }
2575 id = query_disk.ContainerNumber;
2576 if (id == -1)
2577 return (EINVAL);
2492
2578
2493 if (co == NULL) {
2494 query_disk.Valid = 0;
2495 query_disk.Locked = 0;
2496 query_disk.Deleted = 1; /* XXX is this right? */
2497 } else {
2498 disk = device_get_softc(co->co_disk);
2499 query_disk.Valid = 1;
2500 query_disk.Locked = (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
2501 query_disk.Deleted = 0;
2502 query_disk.Bus = 0;
2503 query_disk.Target = disk->unit;
2504 query_disk.Lun = 0;
2505 query_disk.UnMapped = 0;
2506 bcopy(disk->ad_dev_t->si_name, &query_disk.diskDeviceName[0], 10);
2507 }
2508 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2579 AAC_LOCK_AQUIRE(&sc->aac_container_lock);
2580 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
2581 if (co->co_mntobj.ObjectId == id)
2582 break;
2583 }
2509
2584
2510 error = copyout((caddr_t)&query_disk, uptr, sizeof(struct aac_query_disk));
2585 if (co == NULL) {
2586 query_disk.Valid = 0;
2587 query_disk.Locked = 0;
2588 query_disk.Deleted = 1; /* XXX is this right? */
2589 } else {
2590 disk = device_get_softc(co->co_disk);
2591 query_disk.Valid = 1;
2592 query_disk.Locked =
2593 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
2594 query_disk.Deleted = 0;
2595 query_disk.Bus = 0;
2596 query_disk.Target = disk->unit;
2597 query_disk.Lun = 0;
2598 query_disk.UnMapped = 0;
2599 bcopy(disk->ad_dev_t->si_name,
2600 &query_disk.diskDeviceName[0], 10);
2601 }
2602 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2511
2603
2512 return (error);
2604 error = copyout((caddr_t)&query_disk, uptr,
2605 sizeof(struct aac_query_disk));
2606
2607 return (error);
2513}
2514
2608}
2609