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 |