aac.c (173264) | aac.c (174385) |
---|---|
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 --- 14 unchanged lines hidden (view full) --- 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 30#include <sys/cdefs.h> | 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 --- 14 unchanged lines hidden (view full) --- 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 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/aac/aac.c 173264 2007-11-01 20:45:29Z emaste $"); | 31__FBSDID("$FreeBSD: head/sys/dev/aac/aac.c 174385 2007-12-07 00:22:23Z emaste $"); |
32 33/* 34 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 35 */ 36#define AAC_DRIVER_VERSION 0x02000000 37#define AAC_DRIVERNAME "aac" 38 39#include "opt_aac.h" --- 171 unchanged lines hidden (view full) --- 211static d_open_t aac_open; 212static d_close_t aac_close; 213static d_ioctl_t aac_ioctl; 214static d_poll_t aac_poll; 215static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib); 216static void aac_handle_aif(struct aac_softc *sc, 217 struct aac_fib *fib); 218static int aac_rev_check(struct aac_softc *sc, caddr_t udata); | 32 33/* 34 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 35 */ 36#define AAC_DRIVER_VERSION 0x02000000 37#define AAC_DRIVERNAME "aac" 38 39#include "opt_aac.h" --- 171 unchanged lines hidden (view full) --- 211static d_open_t aac_open; 212static d_close_t aac_close; 213static d_ioctl_t aac_ioctl; 214static d_poll_t aac_poll; 215static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib); 216static void aac_handle_aif(struct aac_softc *sc, 217 struct aac_fib *fib); 218static int aac_rev_check(struct aac_softc *sc, caddr_t udata); |
219static int aac_open_aif(struct aac_softc *sc, caddr_t arg); 220static int aac_close_aif(struct aac_softc *sc, caddr_t arg); |
|
219static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg); | 221static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg); |
220static int aac_return_aif(struct aac_softc *sc, caddr_t uptr); | 222static int aac_return_aif(struct aac_softc *sc, 223 struct aac_fib_context *ctx, caddr_t uptr); |
221static int aac_query_disk(struct aac_softc *sc, caddr_t uptr); 222static int aac_get_pci_info(struct aac_softc *sc, caddr_t uptr); 223static void aac_ioctl_event(struct aac_softc *sc, 224 struct aac_event *event, void *arg); 225 226static struct cdevsw aac_cdevsw = { 227 .d_version = D_VERSION, 228 .d_flags = D_NEEDGIANT, --- 49 unchanged lines hidden (view full) --- 278 * Initialize locks 279 */ 280 mtx_init(&sc->aac_aifq_lock, "AAC AIF lock", NULL, MTX_DEF); 281 mtx_init(&sc->aac_io_lock, "AAC I/O lock", NULL, MTX_DEF); 282 mtx_init(&sc->aac_container_lock, "AAC container lock", NULL, MTX_DEF); 283 TAILQ_INIT(&sc->aac_container_tqh); 284 TAILQ_INIT(&sc->aac_ev_cmfree); 285 | 224static int aac_query_disk(struct aac_softc *sc, caddr_t uptr); 225static int aac_get_pci_info(struct aac_softc *sc, caddr_t uptr); 226static void aac_ioctl_event(struct aac_softc *sc, 227 struct aac_event *event, void *arg); 228 229static struct cdevsw aac_cdevsw = { 230 .d_version = D_VERSION, 231 .d_flags = D_NEEDGIANT, --- 49 unchanged lines hidden (view full) --- 281 * Initialize locks 282 */ 283 mtx_init(&sc->aac_aifq_lock, "AAC AIF lock", NULL, MTX_DEF); 284 mtx_init(&sc->aac_io_lock, "AAC I/O lock", NULL, MTX_DEF); 285 mtx_init(&sc->aac_container_lock, "AAC container lock", NULL, MTX_DEF); 286 TAILQ_INIT(&sc->aac_container_tqh); 287 TAILQ_INIT(&sc->aac_ev_cmfree); 288 |
286 /* Initialize the local AIF queue pointers */ 287 sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH; 288 | |
289 /* 290 * Initialise the adapter. 291 */ 292 if ((error = aac_init(sc)) != 0) 293 return(error); 294 295 /* 296 * Allocate and connect our interrupt. --- 2522 unchanged lines hidden (view full) --- 2819static int 2820aac_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) 2821{ 2822 struct aac_softc *sc; 2823 2824 debug_called(2); 2825 2826 sc = dev->si_drv1; | 289 /* 290 * Initialise the adapter. 291 */ 292 if ((error = aac_init(sc)) != 0) 293 return(error); 294 295 /* 296 * Allocate and connect our interrupt. --- 2522 unchanged lines hidden (view full) --- 2819static int 2820aac_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) 2821{ 2822 struct aac_softc *sc; 2823 2824 debug_called(2); 2825 2826 sc = dev->si_drv1; |
2827 2828 /* Check to make sure the device isn't already open */ 2829 if (sc->aac_state & AAC_STATE_OPEN) { 2830 return EBUSY; 2831 } | 2827 sc->aac_open_cnt++; |
2832 sc->aac_state |= AAC_STATE_OPEN; 2833 2834 return 0; 2835} 2836 2837static int 2838aac_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) 2839{ 2840 struct aac_softc *sc; 2841 2842 debug_called(2); 2843 2844 sc = dev->si_drv1; | 2828 sc->aac_state |= AAC_STATE_OPEN; 2829 2830 return 0; 2831} 2832 2833static int 2834aac_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) 2835{ 2836 struct aac_softc *sc; 2837 2838 debug_called(2); 2839 2840 sc = dev->si_drv1; |
2845 | 2841 sc->aac_open_cnt--; |
2846 /* Mark this unit as no longer open */ | 2842 /* Mark this unit as no longer open */ |
2847 sc->aac_state &= ~AAC_STATE_OPEN; | 2843 if (sc->aac_open_cnt == 0) 2844 sc->aac_state &= ~AAC_STATE_OPEN; |
2848 2849 return 0; 2850} 2851 2852static int 2853aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) 2854{ 2855 union aac_statrequest *as; 2856 struct aac_softc *sc; 2857 int error = 0; | 2845 2846 return 0; 2847} 2848 2849static int 2850aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) 2851{ 2852 union aac_statrequest *as; 2853 struct aac_softc *sc; 2854 int error = 0; |
2858 uint32_t cookie; | |
2859 2860 debug_called(2); 2861 2862 as = (union aac_statrequest *)arg; 2863 sc = dev->si_drv1; 2864 2865 switch (cmd) { 2866 case AACIO_STATS: --- 21 unchanged lines hidden (view full) --- 2888 case FSACTL_LNX_AIF_THREAD: 2889 debug(1, "FSACTL_AIF_THREAD"); 2890 error = EINVAL; 2891 break; 2892 case FSACTL_OPEN_GET_ADAPTER_FIB: 2893 arg = *(caddr_t*)arg; 2894 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB: 2895 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB"); | 2855 2856 debug_called(2); 2857 2858 as = (union aac_statrequest *)arg; 2859 sc = dev->si_drv1; 2860 2861 switch (cmd) { 2862 case AACIO_STATS: --- 21 unchanged lines hidden (view full) --- 2884 case FSACTL_LNX_AIF_THREAD: 2885 debug(1, "FSACTL_AIF_THREAD"); 2886 error = EINVAL; 2887 break; 2888 case FSACTL_OPEN_GET_ADAPTER_FIB: 2889 arg = *(caddr_t*)arg; 2890 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB: 2891 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB"); |
2896 /* 2897 * Pass the caller out an AdapterFibContext. 2898 * 2899 * Note that because we only support one opener, we 2900 * basically ignore this. Set the caller's context to a magic 2901 * number just in case. 2902 * 2903 * The Linux code hands the driver a pointer into kernel space, 2904 * and then trusts it when the caller hands it back. Aiee! 2905 * Here, we give it the proc pointer of the per-adapter aif 2906 * thread. It's only used as a sanity check in other calls. 2907 */ 2908 cookie = (uint32_t)(uintptr_t)sc->aifthread; 2909 error = copyout(&cookie, arg, sizeof(cookie)); | 2892 error = aac_open_aif(sc, arg); |
2910 break; 2911 case FSACTL_GET_NEXT_ADAPTER_FIB: 2912 arg = *(caddr_t*)arg; 2913 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB: 2914 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB"); 2915 error = aac_getnext_aif(sc, arg); 2916 break; 2917 case FSACTL_CLOSE_GET_ADAPTER_FIB: | 2893 break; 2894 case FSACTL_GET_NEXT_ADAPTER_FIB: 2895 arg = *(caddr_t*)arg; 2896 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB: 2897 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB"); 2898 error = aac_getnext_aif(sc, arg); 2899 break; 2900 case FSACTL_CLOSE_GET_ADAPTER_FIB: |
2901 arg = *(caddr_t*)arg; |
|
2918 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB: 2919 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB"); | 2902 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB: 2903 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB"); |
2920 /* don't do anything here */ | 2904 error = aac_close_aif(sc, arg); |
2921 break; 2922 case FSACTL_MINIPORT_REV_CHECK: 2923 arg = *(caddr_t*)arg; 2924 case FSACTL_LNX_MINIPORT_REV_CHECK: 2925 debug(1, "FSACTL_MINIPORT_REV_CHECK"); 2926 error = aac_rev_check(sc, arg); 2927 break; 2928 case FSACTL_QUERY_DISK: --- 31 unchanged lines hidden (view full) --- 2960 struct aac_softc *sc; 2961 int revents; 2962 2963 sc = dev->si_drv1; 2964 revents = 0; 2965 2966 mtx_lock(&sc->aac_aifq_lock); 2967 if ((poll_events & (POLLRDNORM | POLLIN)) != 0) { | 2905 break; 2906 case FSACTL_MINIPORT_REV_CHECK: 2907 arg = *(caddr_t*)arg; 2908 case FSACTL_LNX_MINIPORT_REV_CHECK: 2909 debug(1, "FSACTL_MINIPORT_REV_CHECK"); 2910 error = aac_rev_check(sc, arg); 2911 break; 2912 case FSACTL_QUERY_DISK: --- 31 unchanged lines hidden (view full) --- 2944 struct aac_softc *sc; 2945 int revents; 2946 2947 sc = dev->si_drv1; 2948 revents = 0; 2949 2950 mtx_lock(&sc->aac_aifq_lock); 2951 if ((poll_events & (POLLRDNORM | POLLIN)) != 0) { |
2968 if (sc->aac_aifq_tail != sc->aac_aifq_head) | 2952 if (sc->aifq_idx != 0 || sc->aifq_filled) |
2969 revents |= poll_events & (POLLIN | POLLRDNORM); 2970 } 2971 mtx_unlock(&sc->aac_aifq_lock); 2972 2973 if (revents == 0) { 2974 if (poll_events & (POLLIN | POLLRDNORM)) 2975 selrecord(td, &sc->rcv_select); 2976 } --- 109 unchanged lines hidden (view full) --- 3086 * Handle an AIF sent to us by the controller; queue it for later reference. 3087 * If the queue fills up, then drop the older entries. 3088 */ 3089static void 3090aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) 3091{ 3092 struct aac_aif_command *aif; 3093 struct aac_container *co, *co_next; | 2953 revents |= poll_events & (POLLIN | POLLRDNORM); 2954 } 2955 mtx_unlock(&sc->aac_aifq_lock); 2956 2957 if (revents == 0) { 2958 if (poll_events & (POLLIN | POLLRDNORM)) 2959 selrecord(td, &sc->rcv_select); 2960 } --- 109 unchanged lines hidden (view full) --- 3070 * Handle an AIF sent to us by the controller; queue it for later reference. 3071 * If the queue fills up, then drop the older entries. 3072 */ 3073static void 3074aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) 3075{ 3076 struct aac_aif_command *aif; 3077 struct aac_container *co, *co_next; |
3078 struct aac_fib_context *ctx; |
|
3094 struct aac_mntinfo *mi; 3095 struct aac_mntinforesp *mir = NULL; 3096 u_int16_t rsize; | 3079 struct aac_mntinfo *mi; 3080 struct aac_mntinforesp *mir = NULL; 3081 u_int16_t rsize; |
3097 int next, found; | 3082 int next, current, found; |
3098 int count = 0, added = 0, i = 0; 3099 3100 debug_called(2); 3101 3102 aif = (struct aac_aif_command*)&fib->data[0]; 3103 aac_print_aif(sc, aif); 3104 3105 /* Is it an event that we should care about? */ --- 114 unchanged lines hidden (view full) --- 3220 } 3221 3222 default: 3223 break; 3224 } 3225 3226 /* Copy the AIF data to the AIF queue for ioctl retrieval */ 3227 mtx_lock(&sc->aac_aifq_lock); | 3083 int count = 0, added = 0, i = 0; 3084 3085 debug_called(2); 3086 3087 aif = (struct aac_aif_command*)&fib->data[0]; 3088 aac_print_aif(sc, aif); 3089 3090 /* Is it an event that we should care about? */ --- 114 unchanged lines hidden (view full) --- 3205 } 3206 3207 default: 3208 break; 3209 } 3210 3211 /* Copy the AIF data to the AIF queue for ioctl retrieval */ 3212 mtx_lock(&sc->aac_aifq_lock); |
3228 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH; 3229 if (next != sc->aac_aifq_tail) { 3230 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command)); 3231 sc->aac_aifq_head = next; 3232 3233 /* On the off chance that someone is sleeping for an aif... */ 3234 if (sc->aac_state & AAC_STATE_AIF_SLEEPER) 3235 wakeup(sc->aac_aifq); 3236 /* Wakeup any poll()ers */ 3237 selwakeuppri(&sc->rcv_select, PRIBIO); | 3213 current = sc->aifq_idx; 3214 next = (current + 1) % AAC_AIFQ_LENGTH; 3215 if (next == 0) 3216 sc->aifq_filled = 1; 3217 bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib)); 3218 /* modify AIF contexts */ 3219 if (sc->aifq_filled) { 3220 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { 3221 if (next == ctx->ctx_idx) 3222 ctx->ctx_wrap = 1; 3223 else if (current == ctx->ctx_idx && ctx->ctx_wrap) 3224 ctx->ctx_idx = next; 3225 } |
3238 } | 3226 } |
3227 sc->aifq_idx = next; 3228 /* On the off chance that someone is sleeping for an aif... */ 3229 if (sc->aac_state & AAC_STATE_AIF_SLEEPER) 3230 wakeup(sc->aac_aifq); 3231 /* Wakeup any poll()ers */ 3232 selwakeuppri(&sc->rcv_select, PRIBIO); |
|
3239 mtx_unlock(&sc->aac_aifq_lock); 3240 3241 return; 3242} 3243 3244/* 3245 * Return the Revision of the driver to userspace and check to see if the 3246 * userspace app is possibly compatible. This is extremely bogus since --- 29 unchanged lines hidden (view full) --- 3276 rev_check_resp.adapterSWRevision.buildNumber = 3277 sc->aac_revision.buildNumber; 3278 3279 return(copyout((caddr_t)&rev_check_resp, udata, 3280 sizeof(struct aac_rev_check_resp))); 3281} 3282 3283/* | 3233 mtx_unlock(&sc->aac_aifq_lock); 3234 3235 return; 3236} 3237 3238/* 3239 * Return the Revision of the driver to userspace and check to see if the 3240 * userspace app is possibly compatible. This is extremely bogus since --- 29 unchanged lines hidden (view full) --- 3270 rev_check_resp.adapterSWRevision.buildNumber = 3271 sc->aac_revision.buildNumber; 3272 3273 return(copyout((caddr_t)&rev_check_resp, udata, 3274 sizeof(struct aac_rev_check_resp))); 3275} 3276 3277/* |
3278 * Pass the fib context to the caller 3279 */ 3280static int 3281aac_open_aif(struct aac_softc *sc, caddr_t arg) 3282{ 3283 struct aac_fib_context *fibctx, *ctx; 3284 int error = 0; 3285 3286 debug_called(2); 3287 3288 fibctx = malloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO); 3289 if (fibctx == NULL) 3290 return (ENOMEM); 3291 3292 mtx_lock(&sc->aac_aifq_lock); 3293 /* all elements are already 0, add to queue */ 3294 if (sc->fibctx == NULL) 3295 sc->fibctx = fibctx; 3296 else { 3297 for (ctx = sc->fibctx; ctx->next; ctx = ctx->next) 3298 ; 3299 ctx->next = fibctx; 3300 fibctx->prev = ctx; 3301 } 3302 3303 /* evaluate unique value */ 3304 fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff); 3305 ctx = sc->fibctx; 3306 while (ctx != fibctx) { 3307 if (ctx->unique == fibctx->unique) { 3308 fibctx->unique++; 3309 ctx = sc->fibctx; 3310 } else { 3311 ctx = ctx->next; 3312 } 3313 } 3314 mtx_unlock(&sc->aac_aifq_lock); 3315 3316 error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t)); 3317 if (error) 3318 aac_close_aif(sc, (caddr_t)ctx); 3319 return error; 3320} 3321 3322/* 3323 * Close the caller's fib context 3324 */ 3325static int 3326aac_close_aif(struct aac_softc *sc, caddr_t arg) 3327{ 3328 struct aac_fib_context *ctx; 3329 3330 debug_called(2); 3331 3332 mtx_lock(&sc->aac_aifq_lock); 3333 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { 3334 if (ctx->unique == *(uint32_t *)&arg) { 3335 if (ctx == sc->fibctx) 3336 sc->fibctx = NULL; 3337 else { 3338 ctx->prev->next = ctx->next; 3339 if (ctx->next) 3340 ctx->next->prev = ctx->prev; 3341 } 3342 break; 3343 } 3344 } 3345 mtx_unlock(&sc->aac_aifq_lock); 3346 if (ctx) 3347 free(ctx, M_AACBUF); 3348 3349 return 0; 3350} 3351 3352/* |
|
3284 * Pass the caller the next AIF in their queue 3285 */ 3286static int 3287aac_getnext_aif(struct aac_softc *sc, caddr_t arg) 3288{ 3289 struct get_adapter_fib_ioctl agf; | 3353 * Pass the caller the next AIF in their queue 3354 */ 3355static int 3356aac_getnext_aif(struct aac_softc *sc, caddr_t arg) 3357{ 3358 struct get_adapter_fib_ioctl agf; |
3359 struct aac_fib_context *ctx; |
|
3290 int error; 3291 3292 debug_called(2); 3293 3294 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) { | 3360 int error; 3361 3362 debug_called(2); 3363 3364 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) { |
3365 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { 3366 if (agf.AdapterFibContext == ctx->unique) 3367 break; 3368 } 3369 if (!ctx) 3370 return (EFAULT); |
|
3295 | 3371 |
3296 /* 3297 * Check the magic number that we gave the caller. 3298 */ 3299 if (agf.AdapterFibContext != (int)(uintptr_t)sc->aifthread) { 3300 error = EFAULT; 3301 } else { 3302 error = aac_return_aif(sc, agf.AifFib); 3303 if ((error == EAGAIN) && (agf.Wait)) { 3304 sc->aac_state |= AAC_STATE_AIF_SLEEPER; 3305 while (error == EAGAIN) { 3306 error = tsleep(sc->aac_aifq, PRIBIO | 3307 PCATCH, "aacaif", 0); 3308 if (error == 0) 3309 error = aac_return_aif(sc, 3310 agf.AifFib); 3311 } 3312 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER; | 3372 error = aac_return_aif(sc, ctx, agf.AifFib); 3373 if (error == EAGAIN && agf.Wait) { 3374 debug(2, "aac_getnext_aif(): waiting for AIF"); 3375 sc->aac_state |= AAC_STATE_AIF_SLEEPER; 3376 while (error == EAGAIN) { 3377 error = tsleep(sc->aac_aifq, PRIBIO | 3378 PCATCH, "aacaif", 0); 3379 if (error == 0) 3380 error = aac_return_aif(sc, ctx, agf.AifFib); |
3313 } | 3381 } |
3382 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER; |
|
3314 } 3315 } 3316 return(error); 3317} 3318 3319/* 3320 * Hand the next AIF off the top of the queue out to userspace. 3321 */ 3322static int | 3383 } 3384 } 3385 return(error); 3386} 3387 3388/* 3389 * Hand the next AIF off the top of the queue out to userspace. 3390 */ 3391static int |
3323aac_return_aif(struct aac_softc *sc, caddr_t uptr) | 3392aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr) |
3324{ | 3393{ |
3325 int next, error; | 3394 int current, error; |
3326 3327 debug_called(2); 3328 3329 mtx_lock(&sc->aac_aifq_lock); | 3395 3396 debug_called(2); 3397 3398 mtx_lock(&sc->aac_aifq_lock); |
3330 if (sc->aac_aifq_tail == sc->aac_aifq_head) { | 3399 current = ctx->ctx_idx; 3400 if (current == sc->aifq_idx && !ctx->ctx_wrap) { 3401 /* empty */ |
3331 mtx_unlock(&sc->aac_aifq_lock); 3332 return (EAGAIN); 3333 } | 3402 mtx_unlock(&sc->aac_aifq_lock); 3403 return (EAGAIN); 3404 } |
3334 3335 next = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH; 3336 error = copyout(&sc->aac_aifq[next], uptr, 3337 sizeof(struct aac_aif_command)); | 3405 error = 3406 copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib)); |
3338 if (error) 3339 device_printf(sc->aac_dev, 3340 "aac_return_aif: copyout returned %d\n", error); | 3407 if (error) 3408 device_printf(sc->aac_dev, 3409 "aac_return_aif: copyout returned %d\n", error); |
3341 else 3342 sc->aac_aifq_tail = next; 3343 | 3410 else { 3411 ctx->ctx_wrap = 0; 3412 ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH; 3413 } |
3344 mtx_unlock(&sc->aac_aifq_lock); 3345 return(error); 3346} 3347 3348static int 3349aac_get_pci_info(struct aac_softc *sc, caddr_t uptr) 3350{ 3351 struct aac_pci_info { --- 188 unchanged lines hidden --- | 3414 mtx_unlock(&sc->aac_aifq_lock); 3415 return(error); 3416} 3417 3418static int 3419aac_get_pci_info(struct aac_softc *sc, caddr_t uptr) 3420{ 3421 struct aac_pci_info { --- 188 unchanged lines hidden --- |