Deleted Added
full compact
amr.c (152817) amr.c (153409)
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * Copyright (c) 2005 Scott Long
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57
58#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * Copyright (c) 2005 Scott Long
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57
58#include <sys/cdefs.h>
59__FBSDID("$FreeBSD: head/sys/dev/amr/amr.c 152817 2005-11-26 07:30:09Z scottl $");
59__FBSDID("$FreeBSD: head/sys/dev/amr/amr.c 153409 2005-12-14 03:26:49Z scottl $");
60
61/*
62 * Driver for the AMI MegaRaid family of controllers.
63 */
64
65#include <sys/param.h>
66#include <sys/systm.h>
67#include <sys/malloc.h>
68#include <sys/kernel.h>
60
61/*
62 * Driver for the AMI MegaRaid family of controllers.
63 */
64
65#include <sys/param.h>
66#include <sys/systm.h>
67#include <sys/malloc.h>
68#include <sys/kernel.h>
69#include <sys/proc.h>
70#include <sys/sysctl.h>
69
70#include <sys/bio.h>
71#include <sys/bus.h>
72#include <sys/conf.h>
73#include <sys/stat.h>
74
75#include <machine/bus.h>
71
72#include <sys/bio.h>
73#include <sys/bus.h>
74#include <sys/conf.h>
75#include <sys/stat.h>
76
77#include <machine/bus.h>
78#include <machine/cpu.h>
76#include <machine/resource.h>
77#include <sys/rman.h>
78
79#include <dev/pci/pcireg.h>
80#include <dev/pci/pcivar.h>
81
82#include <dev/amr/amrio.h>
83#include <dev/amr/amrreg.h>
84#include <dev/amr/amrvar.h>
85#define AMR_DEFINE_TABLES
86#include <dev/amr/amr_tables.h>
87
88/*
89 * The CAM interface appears to be completely broken. Disable it.
90 */
91#ifndef AMR_ENABLE_CAM
92#define AMR_ENABLE_CAM 0
93#endif
94
79#include <machine/resource.h>
80#include <sys/rman.h>
81
82#include <dev/pci/pcireg.h>
83#include <dev/pci/pcivar.h>
84
85#include <dev/amr/amrio.h>
86#include <dev/amr/amrreg.h>
87#include <dev/amr/amrvar.h>
88#define AMR_DEFINE_TABLES
89#include <dev/amr/amr_tables.h>
90
91/*
92 * The CAM interface appears to be completely broken. Disable it.
93 */
94#ifndef AMR_ENABLE_CAM
95#define AMR_ENABLE_CAM 0
96#endif
97
98SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD, 0, "AMR driver parameters");
99
95static d_open_t amr_open;
96static d_close_t amr_close;
97static d_ioctl_t amr_ioctl;
98
99static struct cdevsw amr_cdevsw = {
100 .d_version = D_VERSION,
101 .d_flags = D_NEEDGIANT,
102 .d_open = amr_open,

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

110 */
111static void amr_startup(void *arg);
112
113/*
114 * Command wrappers
115 */
116static int amr_query_controller(struct amr_softc *sc);
117static void *amr_enquiry(struct amr_softc *sc, size_t bufsize,
100static d_open_t amr_open;
101static d_close_t amr_close;
102static d_ioctl_t amr_ioctl;
103
104static struct cdevsw amr_cdevsw = {
105 .d_version = D_VERSION,
106 .d_flags = D_NEEDGIANT,
107 .d_open = amr_open,

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

115 */
116static void amr_startup(void *arg);
117
118/*
119 * Command wrappers
120 */
121static int amr_query_controller(struct amr_softc *sc);
122static void *amr_enquiry(struct amr_softc *sc, size_t bufsize,
118 u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual);
123 u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual, int *status);
119static void amr_completeio(struct amr_command *ac);
120static int amr_support_ext_cdb(struct amr_softc *sc);
121
122/*
123 * Command buffer allocation.
124 */
125static void amr_alloccmd_cluster(struct amr_softc *sc);
126static void amr_freecmd_cluster(struct amr_command_cluster *acc);
127
128/*
129 * Command processing.
130 */
131static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
132static int amr_wait_command(struct amr_command *ac) __unused;
124static void amr_completeio(struct amr_command *ac);
125static int amr_support_ext_cdb(struct amr_softc *sc);
126
127/*
128 * Command buffer allocation.
129 */
130static void amr_alloccmd_cluster(struct amr_softc *sc);
131static void amr_freecmd_cluster(struct amr_command_cluster *acc);
132
133/*
134 * Command processing.
135 */
136static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
137static int amr_wait_command(struct amr_command *ac) __unused;
133static int amr_getslot(struct amr_command *ac);
134static int amr_mapcmd(struct amr_command *ac);
135static void amr_unmapcmd(struct amr_command *ac);
136static int amr_start(struct amr_command *ac);
137static int amr_start1(struct amr_softc *sc, struct amr_command *ac);
138static void amr_complete(void *context, int pending);
139static void amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
138static int amr_mapcmd(struct amr_command *ac);
139static void amr_unmapcmd(struct amr_command *ac);
140static int amr_start(struct amr_command *ac);
141static int amr_start1(struct amr_softc *sc, struct amr_command *ac);
142static void amr_complete(void *context, int pending);
143static void amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
144static void amr_setup_dma64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
140static void amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
141
142/*
143 * Status monitoring
144 */
145static void amr_periodic(void *data);
146
147/*

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

167 */
168static void amr_describe_controller(struct amr_softc *sc);
169#ifdef AMR_DEBUG
170#if 0
171static void amr_printcommand(struct amr_command *ac);
172#endif
173#endif
174
145static void amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
146
147/*
148 * Status monitoring
149 */
150static void amr_periodic(void *data);
151
152/*

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

172 */
173static void amr_describe_controller(struct amr_softc *sc);
174#ifdef AMR_DEBUG
175#if 0
176static void amr_printcommand(struct amr_command *ac);
177#endif
178#endif
179
180static void amr_init_sysctl(struct amr_softc *sc);
181
175/********************************************************************************
176 ********************************************************************************
177 Inline Glue
178 ********************************************************************************
179 ********************************************************************************/
180
181/********************************************************************************
182 ********************************************************************************

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

227 /*
228 * Quiz controller for features and limits.
229 */
230 if (amr_query_controller(sc))
231 return(ENXIO);
232
233 debug(2, "controller query complete");
234
182/********************************************************************************
183 ********************************************************************************
184 Inline Glue
185 ********************************************************************************
186 ********************************************************************************/
187
188/********************************************************************************
189 ********************************************************************************

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

234 /*
235 * Quiz controller for features and limits.
236 */
237 if (amr_query_controller(sc))
238 return(ENXIO);
239
240 debug(2, "controller query complete");
241
242 /*
243 * Setup sysctls.
244 */
245 amr_init_sysctl(sc);
246
235#if AMR_ENABLE_CAM != 0
236 /*
237 * Attach our 'real' SCSI channels to CAM.
238 */
239 if (amr_cam_attach(sc))
240 return(ENXIO);
241 debug(2, "CAM attach done");
242#endif

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

277{
278 struct amr_softc *sc = (struct amr_softc *)arg;
279 struct amr_logdrive *dr;
280 int i, error;
281
282 debug_called(1);
283
284 /* pull ourselves off the intrhook chain */
247#if AMR_ENABLE_CAM != 0
248 /*
249 * Attach our 'real' SCSI channels to CAM.
250 */
251 if (amr_cam_attach(sc))
252 return(ENXIO);
253 debug(2, "CAM attach done");
254#endif

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

289{
290 struct amr_softc *sc = (struct amr_softc *)arg;
291 struct amr_logdrive *dr;
292 int i, error;
293
294 debug_called(1);
295
296 /* pull ourselves off the intrhook chain */
285 config_intrhook_disestablish(&sc->amr_ich);
297 if (sc->amr_ich.ich_func)
298 config_intrhook_disestablish(&sc->amr_ich);
299 sc->amr_ich.ich_func = NULL;
286
287 /* get up-to-date drive information */
288 if (amr_query_controller(sc)) {
289 device_printf(sc->amr_dev, "can't scan controller for drives\n");
290 return;
291 }
292
293 /* iterate over available drives */

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

323 /*
324 * Start the timeout routine.
325 */
326/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/
327
328 return;
329}
330
300
301 /* get up-to-date drive information */
302 if (amr_query_controller(sc)) {
303 device_printf(sc->amr_dev, "can't scan controller for drives\n");
304 return;
305 }
306
307 /* iterate over available drives */

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

337 /*
338 * Start the timeout routine.
339 */
340/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/
341
342 return;
343}
344
345static void
346amr_init_sysctl(struct amr_softc *sc)
347{
348
349 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
350 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
351 OID_AUTO, "allow_volume_configure", CTLFLAG_RW, &sc->amr_allow_vol_config, 0,
352 "");
353}
354
355
331/*******************************************************************************
332 * Free resources associated with a controller instance
333 */
334void
335amr_free(struct amr_softc *sc)
336{
337 struct amr_command_cluster *acc;
338

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

349 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
350 amr_freecmd_cluster(acc);
351 }
352
353 /* destroy control device */
354 if( sc->amr_dev_t != (struct cdev *)NULL)
355 destroy_dev(sc->amr_dev_t);
356
356/*******************************************************************************
357 * Free resources associated with a controller instance
358 */
359void
360amr_free(struct amr_softc *sc)
361{
362 struct amr_command_cluster *acc;
363

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

374 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
375 amr_freecmd_cluster(acc);
376 }
377
378 /* destroy control device */
379 if( sc->amr_dev_t != (struct cdev *)NULL)
380 destroy_dev(sc->amr_dev_t);
381
357 if (mtx_initialized(&sc->amr_io_lock))
358 mtx_destroy(&sc->amr_io_lock);
382 if (mtx_initialized(&sc->amr_hw_lock))
383 mtx_destroy(&sc->amr_hw_lock);
384
385 if (mtx_initialized(&sc->amr_list_lock))
386 mtx_destroy(&sc->amr_list_lock);
359}
360
361/*******************************************************************************
362 * Receive a bio structure from a child device and queue it on a particular
363 * disk resource, then poke the disk resource to start as much work as it can.
364 */
365int
366amr_submit_bio(struct amr_softc *sc, struct bio *bio)
367{
368 debug_called(2);
369
387}
388
389/*******************************************************************************
390 * Receive a bio structure from a child device and queue it on a particular
391 * disk resource, then poke the disk resource to start as much work as it can.
392 */
393int
394amr_submit_bio(struct amr_softc *sc, struct bio *bio)
395{
396 debug_called(2);
397
370 mtx_lock(&sc->amr_io_lock);
398 mtx_lock(&sc->amr_list_lock);
371 amr_enqueue_bio(sc, bio);
372 amr_startio(sc);
399 amr_enqueue_bio(sc, bio);
400 amr_startio(sc);
373 mtx_unlock(&sc->amr_io_lock);
401 mtx_unlock(&sc->amr_list_lock);
374 return(0);
375}
376
377/********************************************************************************
378 * Accept an open operation on the control device.
379 */
380static int
381amr_open(struct cdev *dev, int flags, int fmt, d_thread_t *td)
382{
383 int unit = minor(dev);
384 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
385
386 debug_called(1);
387
388 sc->amr_state |= AMR_STATE_OPEN;
389 return(0);
390}
391
402 return(0);
403}
404
405/********************************************************************************
406 * Accept an open operation on the control device.
407 */
408static int
409amr_open(struct cdev *dev, int flags, int fmt, d_thread_t *td)
410{
411 int unit = minor(dev);
412 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
413
414 debug_called(1);
415
416 sc->amr_state |= AMR_STATE_OPEN;
417 return(0);
418}
419
420#ifdef LSI
421static int
422amr_del_ld(struct amr_softc *sc, int drv_no, int status)
423{
424
425 debug_called(1);
426
427 sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
428 sc->amr_state &= ~AMR_STATE_LD_DELETE;
429 sc->amr_state |= AMR_STATE_REMAP_LD;
430 debug(1, "State Set");
431
432 if (!status) {
433 debug(1, "disk begin destroyed %d",drv_no);
434 if (--amr_disks_registered == 0)
435 cdevsw_remove(&amrddisk_cdevsw);
436 debug(1, "disk begin destroyed success");
437 }
438 return 0;
439}
440
441static int
442amr_prepare_ld_delete(struct amr_softc *sc)
443{
444
445 debug_called(1);
446 if (sc->ld_del_supported == 0)
447 return(ENOIOCTL);
448
449 sc->amr_state |= AMR_STATE_QUEUE_FRZN;
450 sc->amr_state |= AMR_STATE_LD_DELETE;
451
452 /* 5 minutes for the all the commands to be flushed.*/
453 tsleep((void *)&sc->ld_del_supported, PCATCH | PRIBIO,"delete_logical_drv",hz * 60 * 1);
454 if ( sc->amr_busyslots )
455 return(ENOIOCTL);
456
457 return 0;
458}
459#endif
460
392/********************************************************************************
393 * Accept the last close on the control device.
394 */
395static int
396amr_close(struct cdev *dev, int flags, int fmt, d_thread_t *td)
397{
398 int unit = minor(dev);
399 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
400
401 debug_called(1);
402
403 sc->amr_state &= ~AMR_STATE_OPEN;
404 return (0);
405}
406
407/********************************************************************************
408 * Handle controller-specific control operations.
409 */
461/********************************************************************************
462 * Accept the last close on the control device.
463 */
464static int
465amr_close(struct cdev *dev, int flags, int fmt, d_thread_t *td)
466{
467 int unit = minor(dev);
468 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
469
470 debug_called(1);
471
472 sc->amr_state &= ~AMR_STATE_OPEN;
473 return (0);
474}
475
476/********************************************************************************
477 * Handle controller-specific control operations.
478 */
479static void
480amr_rescan_drives(struct cdev *dev)
481{
482 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
483 int i, error = 0;
484
485 sc->amr_state |= AMR_STATE_REMAP_LD;
486 while (sc->amr_busyslots) {
487 device_printf(sc->amr_dev, "idle controller\n");
488 amr_done(sc);
489 }
490
491 /* mark ourselves as in-shutdown */
492 sc->amr_state |= AMR_STATE_SHUTDOWN;
493
494 /* flush controller */
495 device_printf(sc->amr_dev, "flushing cache...");
496 printf("%s\n", amr_flush(sc) ? "failed" : "done");
497
498 /* delete all our child devices */
499 for(i = 0 ; i < AMR_MAXLD; i++) {
500 if(sc->amr_drive[i].al_disk != 0) {
501 if((error = device_delete_child(sc->amr_dev,
502 sc->amr_drive[i].al_disk)) != 0)
503 goto shutdown_out;
504
505 sc->amr_drive[i].al_disk = 0;
506 }
507 }
508
509shutdown_out:
510 amr_startup(sc);
511}
512
513int
514amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag,
515 d_thread_t *td)
516{
517 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
518 struct amr_command *ac;
519 struct amr_mailbox *mb;
520 struct amr_linux_ioctl ali;
521 void *dp, *temp;
522 int error;
523 int adapter, len, ac_flags = 0;
524 int logical_drives_changed = 0;
525 u_int32_t linux_version = 0x02100000;
526 u_int8_t status;
527 struct amr_passthrough *ap; /* 60 bytes */
528
529 error = 0;
530 dp = NULL;
531 ac = NULL;
532 ap = NULL;
533
534 copyin(addr, &ali, sizeof(ali));
535 switch (ali.ui.fcs.opcode) {
536 case 0x82:
537 switch(ali.ui.fcs.subopcode) {
538 case 'e':
539 copyout(&linux_version, (void *)(uintptr_t)ali.data,
540 sizeof(linux_version));
541 error = 0;
542 break;
543
544 case 'm':
545 copyout(&sc->amr_linux_no_adapters, (void *)(uintptr_t)ali.data,
546 sizeof(sc->amr_linux_no_adapters));
547 td->td_retval[0] = sc->amr_linux_no_adapters;
548 error = 0;
549 break;
550
551 default:
552 printf("Unknown subopcode\n");
553 error = ENOIOCTL;
554 break;
555 }
556 break;
557
558 case 0x80:
559 case 0x81:
560 if (ali.ui.fcs.opcode == 0x80)
561 len = max(ali.outlen, ali.inlen);
562 else
563 len = ali.ui.fcs.length;
564
565 adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
566
567 ap = malloc(sizeof(struct amr_passthrough),
568 M_DEVBUF, M_WAITOK | M_ZERO);
569
570 mb = (void *)&ali.mbox[0];
571
572 if ((ali.mbox[0] == FC_DEL_LOGDRV && ali.mbox[2] == OP_DEL_LOGDRV) || /* delete */
573 (ali.mbox[0] == AMR_CMD_CONFIG && ali.mbox[2] == 0x0d)) { /* create */
574 if (sc->amr_allow_vol_config == 0) {
575 error = EPERM;
576 break;
577 }
578 logical_drives_changed = 1;
579 }
580
581 if (ali.mbox[0] == AMR_CMD_PASS) {
582 error = copyin((void *)(uintptr_t)mb->mb_physaddr, ap,
583 sizeof(struct amr_passthrough));
584 if (error)
585 break;
586
587 if (ap->ap_data_transfer_length)
588 dp = malloc(ap->ap_data_transfer_length, M_DEVBUF,
589 M_WAITOK | M_ZERO);
590
591 if (ali.inlen) {
592 error = copyin((void *)(uintptr_t)ap->ap_data_transfer_address,
593 dp, ap->ap_data_transfer_length);
594 if (error)
595 break;
596 }
597
598 mtx_lock(&sc->amr_list_lock);
599 while ((ac = amr_alloccmd(sc)) == NULL)
600 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
601 mtx_unlock(&sc->amr_list_lock);
602
603 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB_DATAIN|AMR_CMD_CCB_DATAOUT;
604 bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
605 ac->ac_mailbox.mb_command = AMR_CMD_PASS;
606 ac->ac_flags = ac_flags;
607
608 ac->ac_data = ap;
609 ac->ac_length = sizeof(struct amr_passthrough);
610 ac->ac_ccb_data = dp;
611 ac->ac_ccb_length = ap->ap_data_transfer_length;
612 temp = (void *)(uintptr_t)ap->ap_data_transfer_address;
613
614 error = amr_wait_command(ac);
615 if (error)
616 break;
617
618 status = ac->ac_status;
619 error = copyout(&status, &((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_scsi_status, sizeof(status));
620 if (error)
621 break;
622
623 if (ali.outlen) {
624 error = copyout(dp, temp, ap->ap_data_transfer_length);
625 if (error)
626 break;
627 }
628 error = copyout(ap->ap_request_sense_area, ((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_request_sense_area, ap->ap_request_sense_length);
629 if (error)
630 break;
631
632 error = 0;
633 break;
634 } else if (ali.mbox[0] == AMR_CMD_PASS_64) {
635 printf("No AMR_CMD_PASS_64\n");
636 error = ENOIOCTL;
637 break;
638 } else if (ali.mbox[0] == AMR_CMD_EXTPASS) {
639 printf("No AMR_CMD_EXTPASS\n");
640 error = ENOIOCTL;
641 break;
642 } else {
643 if (len)
644 dp = malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
645
646 if (ali.inlen) {
647 error = copyin((void *)(uintptr_t)mb->mb_physaddr, dp, len);
648 if (error)
649 break;
650 }
651
652 mtx_lock(&sc->amr_list_lock);
653 while ((ac = amr_alloccmd(sc)) == NULL)
654 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
655 mtx_unlock(&sc->amr_list_lock);
656
657 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
658 bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
659 bcopy(&ali.mbox[0], &ac->ac_mailbox, sizeof(ali.mbox));
660
661 ac->ac_length = len;
662 ac->ac_data = dp;
663 ac->ac_flags = ac_flags;
664
665 error = amr_wait_command(ac);
666 if (error)
667 break;
668
669 status = ac->ac_status;
670 error = copyout(&status, &((struct amr_mailbox *)&((struct amr_linux_ioctl *)addr)->mbox[0])->mb_status, sizeof(status));
671 if (ali.outlen) {
672 error = copyout(dp, (void *)(uintptr_t)mb->mb_physaddr, len);
673 if (error)
674 break;
675 }
676
677 error = 0;
678 if (logical_drives_changed)
679 amr_rescan_drives(dev);
680 break;
681 }
682 break;
683
684 default:
685 debug(1, "unknown linux ioctl 0x%lx", cmd);
686 printf("unknown linux ioctl 0x%lx\n", cmd);
687 error = ENOIOCTL;
688 break;
689 }
690
691 /*
692 * At this point, we know that there is a lock held and that these
693 * objects have been allocated.
694 */
695 mtx_lock(&sc->amr_list_lock);
696 if (ac != NULL)
697 amr_releasecmd(ac);
698 mtx_unlock(&sc->amr_list_lock);
699 if (dp != NULL)
700 free(dp, M_DEVBUF);
701 if (ap != NULL)
702 free(ap, M_DEVBUF);
703 return(error);
704}
705
410static int
411amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td)
412{
413 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
414 union {
415 void *_p;
416 struct amr_user_ioctl *au;
417#ifdef AMR_IO_COMMAND32
418 struct amr_user_ioctl32 *au32;
419#endif
420 int *result;
421 } arg;
422 struct amr_command *ac;
423 struct amr_mailbox_ioctl *mbi;
424 void *dp, *au_buffer;
425 unsigned long au_length;
426 unsigned char *au_cmd;
427 int *au_statusp, au_direction;
706static int
707amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td)
708{
709 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
710 union {
711 void *_p;
712 struct amr_user_ioctl *au;
713#ifdef AMR_IO_COMMAND32
714 struct amr_user_ioctl32 *au32;
715#endif
716 int *result;
717 } arg;
718 struct amr_command *ac;
719 struct amr_mailbox_ioctl *mbi;
720 void *dp, *au_buffer;
721 unsigned long au_length;
722 unsigned char *au_cmd;
723 int *au_statusp, au_direction;
428 int error;
724 int error, ac_flags = 0;
429 struct amr_passthrough *ap; /* 60 bytes */
725 struct amr_passthrough *ap; /* 60 bytes */
726 int logical_drives_changed = 0;
430
431 debug_called(1);
432
433 arg._p = (void *)addr;
434
727
728 debug_called(1);
729
730 arg._p = (void *)addr;
731
732 error = 0;
733 dp = NULL;
734 ac = NULL;
735 ap = NULL;
736
435 switch(cmd) {
436
437 case AMR_IO_VERSION:
438 debug(1, "AMR_IO_VERSION");
439 *arg.result = AMR_IO_VERSION_NUMBER;
440 return(0);
441
442#ifdef AMR_IO_COMMAND32

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

459 debug(1, "AMR_IO_COMMAND 0x%x", arg.au->au_cmd[0]);
460 au_cmd = arg.au->au_cmd;
461 au_buffer = (void *)arg.au->au_buffer;
462 au_length = arg.au->au_length;
463 au_direction = arg.au->au_direction;
464 au_statusp = &arg.au->au_status;
465 break;
466
737 switch(cmd) {
738
739 case AMR_IO_VERSION:
740 debug(1, "AMR_IO_VERSION");
741 *arg.result = AMR_IO_VERSION_NUMBER;
742 return(0);
743
744#ifdef AMR_IO_COMMAND32

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

761 debug(1, "AMR_IO_COMMAND 0x%x", arg.au->au_cmd[0]);
762 au_cmd = arg.au->au_cmd;
763 au_buffer = (void *)arg.au->au_buffer;
764 au_length = arg.au->au_length;
765 au_direction = arg.au->au_direction;
766 au_statusp = &arg.au->au_status;
767 break;
768
769 case 0xc0046d00:
770 case 0xc06e6d00: /* Linux emulation */
771 return amr_linux_ioctl_int(dev, cmd, addr, flag, td);
772 break;
773
467 default:
468 debug(1, "unknown ioctl 0x%lx", cmd);
469 return(ENOIOCTL);
470 }
471
774 default:
775 debug(1, "unknown ioctl 0x%lx", cmd);
776 return(ENOIOCTL);
777 }
778
472 error = 0;
473 dp = NULL;
474 ac = NULL;
475 ap = NULL;
779 if ((au_cmd[0] == FC_DEL_LOGDRV && au_cmd[1] == OP_DEL_LOGDRV) || /* delete */
780 (au_cmd[0] == AMR_CMD_CONFIG && au_cmd[1] == 0x0d)) { /* create */
781 if (sc->amr_allow_vol_config == 0) {
782 error = EPERM;
783 goto out;
784 }
785 logical_drives_changed = 1;
786#ifdef LSI
787 if ((error = amr_prepare_ld_delete(sc)) != 0)
788 return (error);
789#endif
790 }
476
791
477 /* Logical Drive not supported by the driver */
478 if (au_cmd[0] == 0xa4 && au_cmd[1] == 0x1c)
479 return (ENOIOCTL);
480
481 /* handle inbound data buffer */
482 if (au_length != 0 && au_cmd[0] != 0x06) {
792 /* handle inbound data buffer */
793 if (au_length != 0 && au_cmd[0] != 0x06) {
483 dp = malloc(au_length, M_DEVBUF, M_WAITOK|M_ZERO);
484
794 if ((dp = malloc(au_length, M_DEVBUF, M_WAITOK|M_ZERO)) == NULL) {
795 error = ENOMEM;
796 goto out;
797 }
485 if ((error = copyin(au_buffer, dp, au_length)) != 0) {
486 free(dp, M_DEVBUF);
487 return (error);
488 }
489 debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp);
490 }
491
492 /* Allocate this now before the mutex gets held */
493 if (au_cmd[0] == AMR_CMD_PASS)
494 ap = malloc(sizeof(struct amr_passthrough), M_DEVBUF, M_WAITOK|M_ZERO);
495
798 if ((error = copyin(au_buffer, dp, au_length)) != 0) {
799 free(dp, M_DEVBUF);
800 return (error);
801 }
802 debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp);
803 }
804
805 /* Allocate this now before the mutex gets held */
806 if (au_cmd[0] == AMR_CMD_PASS)
807 ap = malloc(sizeof(struct amr_passthrough), M_DEVBUF, M_WAITOK|M_ZERO);
808
496 mtx_lock(&sc->amr_io_lock);
497 if ((ac = amr_alloccmd(sc)) == NULL) {
498 error = ENOMEM;
499 goto out;
500 }
809 mtx_lock(&sc->amr_list_lock);
810 while ((ac = amr_alloccmd(sc)) == NULL)
811 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
812 mtx_unlock(&sc->amr_list_lock);
501
502 /* handle SCSI passthrough command */
503 if (au_cmd[0] == AMR_CMD_PASS) {
504 int len;
505
506 /* copy cdb */
507 len = au_cmd[2];
508 ap->ap_cdb_length = len;

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

517 ap->ap_scsi_id = au_cmd[len + 6];
518 ap->ap_request_sense_length = 14;
519 ap->ap_data_transfer_length = au_length;
520 /* XXX what about the request-sense area? does the caller want it? */
521
522 /* build command */
523 ac->ac_data = ap;
524 ac->ac_length = sizeof(struct amr_passthrough);
813
814 /* handle SCSI passthrough command */
815 if (au_cmd[0] == AMR_CMD_PASS) {
816 int len;
817
818 /* copy cdb */
819 len = au_cmd[2];
820 ap->ap_cdb_length = len;

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

829 ap->ap_scsi_id = au_cmd[len + 6];
830 ap->ap_request_sense_length = 14;
831 ap->ap_data_transfer_length = au_length;
832 /* XXX what about the request-sense area? does the caller want it? */
833
834 /* build command */
835 ac->ac_data = ap;
836 ac->ac_length = sizeof(struct amr_passthrough);
525 ac->ac_flags |= AMR_CMD_DATAOUT;
526 ac->ac_ccb_data = dp;
527 ac->ac_ccb_length = au_length;
837 ac->ac_ccb_data = dp;
838 ac->ac_ccb_length = au_length;
528 if (au_direction & AMR_IO_READ)
529 ac->ac_flags |= AMR_CMD_CCB_DATAIN;
530 if (au_direction & AMR_IO_WRITE)
531 ac->ac_flags |= AMR_CMD_CCB_DATAOUT;
532
533 ac->ac_mailbox.mb_command = AMR_CMD_PASS;
839
840 ac->ac_mailbox.mb_command = AMR_CMD_PASS;
841 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB_DATAIN|AMR_CMD_CCB_DATAOUT;
534
535 } else {
536 /* direct command to controller */
537 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
538
539 /* copy pertinent mailbox items */
540 mbi->mb_command = au_cmd[0];
541 mbi->mb_channel = au_cmd[1];
542 mbi->mb_param = au_cmd[2];
543 mbi->mb_pad[0] = au_cmd[3];
544 mbi->mb_drive = au_cmd[4];
545
546 /* build the command */
547 ac->ac_data = dp;
548 ac->ac_length = au_length;
842
843 } else {
844 /* direct command to controller */
845 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
846
847 /* copy pertinent mailbox items */
848 mbi->mb_command = au_cmd[0];
849 mbi->mb_channel = au_cmd[1];
850 mbi->mb_param = au_cmd[2];
851 mbi->mb_pad[0] = au_cmd[3];
852 mbi->mb_drive = au_cmd[4];
853
854 /* build the command */
855 ac->ac_data = dp;
856 ac->ac_length = au_length;
549 if (au_direction & AMR_IO_READ)
550 ac->ac_flags |= AMR_CMD_DATAIN;
551 if (au_direction & AMR_IO_WRITE)
552 ac->ac_flags |= AMR_CMD_DATAOUT;
857 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
553 }
554
858 }
859
860 ac->ac_flags = ac_flags;
861
555 /* run the command */
556 if ((error = amr_wait_command(ac)) != 0)
557 goto out;
558
559 /* copy out data and set status */
560 if (au_length != 0) {
862 /* run the command */
863 if ((error = amr_wait_command(ac)) != 0)
864 goto out;
865
866 /* copy out data and set status */
867 if (au_length != 0) {
561 mtx_unlock(&sc->amr_io_lock);
562 error = copyout(dp, au_buffer, au_length);
868 error = copyout(dp, au_buffer, au_length);
563 mtx_lock(&sc->amr_io_lock);
564 }
565 debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer);
566 if (dp != NULL)
567 debug(2, "%16d", (int)dp);
568 *au_statusp = ac->ac_status;
569
570out:
571 /*
572 * At this point, we know that there is a lock held and that these
573 * objects have been allocated.
574 */
869 }
870 debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer);
871 if (dp != NULL)
872 debug(2, "%16d", (int)dp);
873 *au_statusp = ac->ac_status;
874
875out:
876 /*
877 * At this point, we know that there is a lock held and that these
878 * objects have been allocated.
879 */
880 mtx_lock(&sc->amr_list_lock);
575 if (ac != NULL)
576 amr_releasecmd(ac);
881 if (ac != NULL)
882 amr_releasecmd(ac);
577 mtx_unlock(&sc->amr_io_lock);
883 mtx_unlock(&sc->amr_list_lock);
578 if (dp != NULL)
579 free(dp, M_DEVBUF);
580 if (ap != NULL)
581 free(ap, M_DEVBUF);
884 if (dp != NULL)
885 free(dp, M_DEVBUF);
886 if (ap != NULL)
887 free(ap, M_DEVBUF);
888
889#ifndef LSI
890 if (logical_drives_changed)
891 amr_rescan_drives(dev);
892#endif
893
582 return(error);
583}
584
585/********************************************************************************
586 ********************************************************************************
587 Status Monitoring
588 ********************************************************************************
589 ********************************************************************************/

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

618 */
619static int
620amr_query_controller(struct amr_softc *sc)
621{
622 struct amr_enquiry3 *aex;
623 struct amr_prodinfo *ap;
624 struct amr_enquiry *ae;
625 int ldrv;
894 return(error);
895}
896
897/********************************************************************************
898 ********************************************************************************
899 Status Monitoring
900 ********************************************************************************
901 ********************************************************************************/

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

930 */
931static int
932amr_query_controller(struct amr_softc *sc)
933{
934 struct amr_enquiry3 *aex;
935 struct amr_prodinfo *ap;
936 struct amr_enquiry *ae;
937 int ldrv;
938 int status;
626
939
627 mtx_lock(&sc->amr_io_lock);
628
629 /*
630 * If we haven't found the real limit yet, let us have a couple of commands in
631 * order to be able to probe.
632 */
633 if (sc->amr_maxio == 0)
634 sc->amr_maxio = 2;
635
636 /*

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

641 if(sc->support_ext_cdb) {
642 debug(2,"supports extended CDBs.");
643 }
644
645 /*
646 * Try to issue an ENQUIRY3 command
647 */
648 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
940 /*
941 * If we haven't found the real limit yet, let us have a couple of commands in
942 * order to be able to probe.
943 */
944 if (sc->amr_maxio == 0)
945 sc->amr_maxio = 2;
946
947 /*

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

952 if(sc->support_ext_cdb) {
953 debug(2,"supports extended CDBs.");
954 }
955
956 /*
957 * Try to issue an ENQUIRY3 command
958 */
959 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
649 AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) {
960 AMR_CONFIG_ENQ3_SOLICITED_FULL, &status)) != NULL) {
650
651 /*
652 * Fetch current state of logical drives.
653 */
654 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
655 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv];
656 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv];
657 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
658 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
659 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
660 }
661 free(aex, M_DEVBUF);
662
663 /*
664 * Get product info for channel count.
665 */
961
962 /*
963 * Fetch current state of logical drives.
964 */
965 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
966 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv];
967 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv];
968 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
969 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
970 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
971 }
972 free(aex, M_DEVBUF);
973
974 /*
975 * Get product info for channel count.
976 */
666 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) {
977 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0, &status)) == NULL) {
667 device_printf(sc->amr_dev, "can't obtain product data from controller\n");
978 device_printf(sc->amr_dev, "can't obtain product data from controller\n");
668 mtx_unlock(&sc->amr_io_lock);
669 return(1);
670 }
671 sc->amr_maxdrives = 40;
672 sc->amr_maxchan = ap->ap_nschan;
673 sc->amr_maxio = ap->ap_maxio;
674 sc->amr_type |= AMR_TYPE_40LD;
675 free(ap, M_DEVBUF);
676
979 return(1);
980 }
981 sc->amr_maxdrives = 40;
982 sc->amr_maxchan = ap->ap_nschan;
983 sc->amr_maxio = ap->ap_maxio;
984 sc->amr_type |= AMR_TYPE_40LD;
985 free(ap, M_DEVBUF);
986
987 ap = amr_enquiry(sc, 0, FC_DEL_LOGDRV, OP_SUP_DEL_LOGDRV, 0, &status);
988 free(ap, M_DEVBUF);
989 if (!status) {
990 sc->amr_ld_del_supported = 1;
991 device_printf(sc->amr_dev, "delete logical drives supported by controller\n");
992 }
677 } else {
678
679 /* failed, try the 8LD ENQUIRY commands */
993 } else {
994
995 /* failed, try the 8LD ENQUIRY commands */
680 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) == NULL) {
681 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) == NULL) {
996 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0, &status)) == NULL) {
997 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0, &status)) == NULL) {
682 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
998 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
683 mtx_unlock(&sc->amr_io_lock);
684 return(1);
685 }
686 ae->ae_signature = 0;
687 }
688
689 /*
690 * Fetch current state of logical drives.
691 */

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

710 sc->amr_drive[ldrv].al_size = 0xffffffff;
711
712 /*
713 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust
714 * the controller's reported value, and lockups have been seen when we do.
715 */
716 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
717
999 return(1);
1000 }
1001 ae->ae_signature = 0;
1002 }
1003
1004 /*
1005 * Fetch current state of logical drives.
1006 */

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

1025 sc->amr_drive[ldrv].al_size = 0xffffffff;
1026
1027 /*
1028 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust
1029 * the controller's reported value, and lockups have been seen when we do.
1030 */
1031 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
1032
718 mtx_unlock(&sc->amr_io_lock);
719 return(0);
720}
721
722/********************************************************************************
723 * Run a generic enquiry-style command.
724 */
725static void *
1033 return(0);
1034}
1035
1036/********************************************************************************
1037 * Run a generic enquiry-style command.
1038 */
1039static void *
726amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual)
1040amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual, int *status)
727{
728 struct amr_command *ac;
729 void *result;
730 u_int8_t *mbox;
731 int error;
732
733 debug_called(1);
734
735 error = 1;
736 result = NULL;
737
738 /* get ourselves a command buffer */
1041{
1042 struct amr_command *ac;
1043 void *result;
1044 u_int8_t *mbox;
1045 int error;
1046
1047 debug_called(1);
1048
1049 error = 1;
1050 result = NULL;
1051
1052 /* get ourselves a command buffer */
739 if ((ac = amr_alloccmd(sc)) == NULL)
1053 mtx_lock(&sc->amr_list_lock);
1054 ac = amr_alloccmd(sc);
1055 mtx_unlock(&sc->amr_list_lock);
1056 if (ac == NULL)
740 goto out;
741 /* allocate the response structure */
742 if ((result = malloc(bufsize, M_DEVBUF, M_ZERO|M_NOWAIT)) == NULL)
743 goto out;
744 /* set command flags */
745
746 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN;
747
748 /* point the command at our data */
749 ac->ac_data = result;
750 ac->ac_length = bufsize;
751
752 /* build the command proper */
753 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
754 mbox[0] = cmd;
755 mbox[2] = cmdsub;
756 mbox[3] = cmdqual;
1057 goto out;
1058 /* allocate the response structure */
1059 if ((result = malloc(bufsize, M_DEVBUF, M_ZERO|M_NOWAIT)) == NULL)
1060 goto out;
1061 /* set command flags */
1062
1063 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN;
1064
1065 /* point the command at our data */
1066 ac->ac_data = result;
1067 ac->ac_length = bufsize;
1068
1069 /* build the command proper */
1070 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
1071 mbox[0] = cmd;
1072 mbox[2] = cmdsub;
1073 mbox[3] = cmdqual;
1074 *status = 0;
757
758 /* can't assume that interrupts are going to work here, so play it safe */
759 if (sc->amr_poll_command(ac))
760 goto out;
761 error = ac->ac_status;
1075
1076 /* can't assume that interrupts are going to work here, so play it safe */
1077 if (sc->amr_poll_command(ac))
1078 goto out;
1079 error = ac->ac_status;
1080 *status = ac->ac_status;
762
763 out:
1081
1082 out:
1083 mtx_lock(&sc->amr_list_lock);
764 if (ac != NULL)
765 amr_releasecmd(ac);
1084 if (ac != NULL)
1085 amr_releasecmd(ac);
1086 mtx_unlock(&sc->amr_list_lock);
766 if ((error != 0) && (result != NULL)) {
767 free(result, M_DEVBUF);
768 result = NULL;
769 }
770 return(result);
771}
772
773/********************************************************************************
774 * Flush the controller's internal cache, return status.
775 */
776int
777amr_flush(struct amr_softc *sc)
778{
779 struct amr_command *ac;
780 int error;
781
782 /* get ourselves a command buffer */
783 error = 1;
1087 if ((error != 0) && (result != NULL)) {
1088 free(result, M_DEVBUF);
1089 result = NULL;
1090 }
1091 return(result);
1092}
1093
1094/********************************************************************************
1095 * Flush the controller's internal cache, return status.
1096 */
1097int
1098amr_flush(struct amr_softc *sc)
1099{
1100 struct amr_command *ac;
1101 int error;
1102
1103 /* get ourselves a command buffer */
1104 error = 1;
784 mtx_lock(&sc->amr_io_lock);
785 if ((ac = amr_alloccmd(sc)) == NULL)
1105 mtx_lock(&sc->amr_list_lock);
1106 ac = amr_alloccmd(sc);
1107 mtx_unlock(&sc->amr_list_lock);
1108 if (ac == NULL)
786 goto out;
787 /* set command flags */
788 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
789
790 /* build the command proper */
791 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
792
793 /* we have to poll, as the system may be going down or otherwise damaged */
794 if (sc->amr_poll_command(ac))
795 goto out;
796 error = ac->ac_status;
797
798 out:
1109 goto out;
1110 /* set command flags */
1111 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
1112
1113 /* build the command proper */
1114 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
1115
1116 /* we have to poll, as the system may be going down or otherwise damaged */
1117 if (sc->amr_poll_command(ac))
1118 goto out;
1119 error = ac->ac_status;
1120
1121 out:
1122 mtx_lock(&sc->amr_list_lock);
799 if (ac != NULL)
800 amr_releasecmd(ac);
1123 if (ac != NULL)
1124 amr_releasecmd(ac);
801 mtx_unlock(&sc->amr_io_lock);
1125 mtx_unlock(&sc->amr_list_lock);
802 return(error);
803}
804
805/********************************************************************************
806 * Detect extented cdb >> greater than 10 byte cdb support
807 * returns '1' means this support exist
808 * returns '0' means this support doesn't exist
809 */
810static int
811amr_support_ext_cdb(struct amr_softc *sc)
812{
813 struct amr_command *ac;
814 u_int8_t *mbox;
815 int error;
816
817 /* get ourselves a command buffer */
818 error = 0;
1126 return(error);
1127}
1128
1129/********************************************************************************
1130 * Detect extented cdb >> greater than 10 byte cdb support
1131 * returns '1' means this support exist
1132 * returns '0' means this support doesn't exist
1133 */
1134static int
1135amr_support_ext_cdb(struct amr_softc *sc)
1136{
1137 struct amr_command *ac;
1138 u_int8_t *mbox;
1139 int error;
1140
1141 /* get ourselves a command buffer */
1142 error = 0;
819 if ((ac = amr_alloccmd(sc)) == NULL)
1143 mtx_lock(&sc->amr_list_lock);
1144 ac = amr_alloccmd(sc);
1145 mtx_unlock(&sc->amr_list_lock);
1146 if (ac == NULL)
820 goto out;
821 /* set command flags */
822 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
823
824 /* build the command proper */
825 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
826 mbox[0] = 0xA4;
827 mbox[2] = 0x16;
828
829
830 /* we have to poll, as the system may be going down or otherwise damaged */
831 if (sc->amr_poll_command(ac))
832 goto out;
833 if( ac->ac_status == AMR_STATUS_SUCCESS ) {
834 error = 1;
835 }
836
837out:
1147 goto out;
1148 /* set command flags */
1149 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
1150
1151 /* build the command proper */
1152 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
1153 mbox[0] = 0xA4;
1154 mbox[2] = 0x16;
1155
1156
1157 /* we have to poll, as the system may be going down or otherwise damaged */
1158 if (sc->amr_poll_command(ac))
1159 goto out;
1160 if( ac->ac_status == AMR_STATUS_SUCCESS ) {
1161 error = 1;
1162 }
1163
1164out:
1165 mtx_lock(&sc->amr_list_lock);
838 if (ac != NULL)
839 amr_releasecmd(ac);
1166 if (ac != NULL)
1167 amr_releasecmd(ac);
1168 mtx_unlock(&sc->amr_list_lock);
840 return(error);
841}
842
843/********************************************************************************
844 * Try to find I/O work for the controller from one or more of the work queues.
845 *
846 * We make the assumption that if the controller is not ready to take a command
847 * at some given time, it will generate an interrupt at some later time when

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

886}
887
888/********************************************************************************
889 * Handle completion of an I/O command.
890 */
891static void
892amr_completeio(struct amr_command *ac)
893{
1169 return(error);
1170}
1171
1172/********************************************************************************
1173 * Try to find I/O work for the controller from one or more of the work queues.
1174 *
1175 * We make the assumption that if the controller is not ready to take a command
1176 * at some given time, it will generate an interrupt at some later time when

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

1215}
1216
1217/********************************************************************************
1218 * Handle completion of an I/O command.
1219 */
1220static void
1221amr_completeio(struct amr_command *ac)
1222{
894 struct amrd_softc *sc = ac->ac_bio->bio_disk->d_drv1;
1223 struct amrd_softc *sc = ac->ac_bio->bio_disk->d_drv1;
1224 static struct timeval lastfail;
1225 static int curfail;
895
896 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */
897 ac->ac_bio->bio_error = EIO;
898 ac->ac_bio->bio_flags |= BIO_ERROR;
899
1226
1227 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */
1228 ac->ac_bio->bio_error = EIO;
1229 ac->ac_bio->bio_flags |= BIO_ERROR;
1230
900 device_printf(sc->amrd_dev, "I/O error - 0x%x\n", ac->ac_status);
1231 if (ppsratecheck(&lastfail, &curfail, 1))
1232 device_printf(sc->amrd_dev, "I/O error - 0x%x\n", ac->ac_status);
901/* amr_printcommand(ac);*/
902 }
903 amrd_intr(ac->ac_bio);
1233/* amr_printcommand(ac);*/
1234 }
1235 amrd_intr(ac->ac_bio);
1236 mtx_lock(&ac->ac_sc->amr_list_lock);
904 amr_releasecmd(ac);
1237 amr_releasecmd(ac);
1238 mtx_unlock(&ac->ac_sc->amr_list_lock);
905}
906
907/********************************************************************************
908 ********************************************************************************
909 Command Processing
910 ********************************************************************************
911 ********************************************************************************/
912

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

939
940 /* connect the bio to the command */
941 ac->ac_complete = amr_completeio;
942 ac->ac_bio = bio;
943 ac->ac_data = bio->bio_data;
944 ac->ac_length = bio->bio_bcount;
945 if (bio->bio_cmd == BIO_READ) {
946 ac->ac_flags |= AMR_CMD_DATAIN;
1239}
1240
1241/********************************************************************************
1242 ********************************************************************************
1243 Command Processing
1244 ********************************************************************************
1245 ********************************************************************************/
1246

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

1273
1274 /* connect the bio to the command */
1275 ac->ac_complete = amr_completeio;
1276 ac->ac_bio = bio;
1277 ac->ac_data = bio->bio_data;
1278 ac->ac_length = bio->bio_bcount;
1279 if (bio->bio_cmd == BIO_READ) {
1280 ac->ac_flags |= AMR_CMD_DATAIN;
947 cmd = AMR_CMD_LREAD;
1281 if (AMR_IS_SG64(sc)) {
1282 cmd = AMR_CMD_LREAD64;
1283 ac->ac_flags |= AMR_CMD_SG64;
1284 } else
1285 cmd = AMR_CMD_LREAD;
948 } else {
949 ac->ac_flags |= AMR_CMD_DATAOUT;
1286 } else {
1287 ac->ac_flags |= AMR_CMD_DATAOUT;
950 cmd = AMR_CMD_LWRITE;
1288 if (AMR_IS_SG64(sc)) {
1289 cmd = AMR_CMD_LWRITE64;
1290 ac->ac_flags |= AMR_CMD_SG64;
1291 } else
1292 cmd = AMR_CMD_LWRITE;
951 }
952 amrd = (struct amrd_softc *)bio->bio_disk->d_drv1;
953 driveno = amrd->amrd_drive - sc->amr_drive;
954 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE;
955
956 ac->ac_mailbox.mb_command = cmd;
957 ac->ac_mailbox.mb_blkcount = blkcount;
958 ac->ac_mailbox.mb_lba = bio->bio_pblkno;
959 ac->ac_mailbox.mb_drive = driveno;
1293 }
1294 amrd = (struct amrd_softc *)bio->bio_disk->d_drv1;
1295 driveno = amrd->amrd_drive - sc->amr_drive;
1296 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE;
1297
1298 ac->ac_mailbox.mb_command = cmd;
1299 ac->ac_mailbox.mb_blkcount = blkcount;
1300 ac->ac_mailbox.mb_lba = bio->bio_pblkno;
1301 ac->ac_mailbox.mb_drive = driveno;
1302 if (sc->amr_state & AMR_STATE_REMAP_LD)
1303 ac->ac_mailbox.mb_drive |= 0x80;
1304
960 /* we fill in the s/g related data when the command is mapped */
961
962 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size)
963 device_printf(sc->amr_dev, "I/O beyond end of unit (%lld,%d > %lu)\n",
964 (long long)bio->bio_pblkno, blkcount,
965 (u_long)sc->amr_drive[driveno].al_size);
966
967 *acp = ac;

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

976amr_wait_command(struct amr_command *ac)
977{
978 int error = 0;
979
980 debug_called(1);
981
982 ac->ac_complete = NULL;
983 ac->ac_flags |= AMR_CMD_SLEEP;
1305 /* we fill in the s/g related data when the command is mapped */
1306
1307 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size)
1308 device_printf(sc->amr_dev, "I/O beyond end of unit (%lld,%d > %lu)\n",
1309 (long long)bio->bio_pblkno, blkcount,
1310 (u_long)sc->amr_drive[driveno].al_size);
1311
1312 *acp = ac;

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

1321amr_wait_command(struct amr_command *ac)
1322{
1323 int error = 0;
1324
1325 debug_called(1);
1326
1327 ac->ac_complete = NULL;
1328 ac->ac_flags |= AMR_CMD_SLEEP;
984 if ((error = amr_start(ac)) != 0)
1329 if ((error = amr_start(ac)) != 0) {
985 return(error);
1330 return(error);
1331 }
986
987 while ((ac->ac_flags & AMR_CMD_BUSY) && (error != EWOULDBLOCK)) {
1332
1333 while ((ac->ac_flags & AMR_CMD_BUSY) && (error != EWOULDBLOCK)) {
988 error = msleep(ac, &ac->ac_sc->amr_io_lock, PRIBIO, "amrwcmd", 0);
1334 error = tsleep(ac, PRIBIO, "amrwcmd", 0);
989 }
990 return(error);
991}
992
993/********************************************************************************
994 * Take a command, submit it to the controller and busy-wait for it to return.
995 * Returns nonzero on error. Can be safely called with interrupts enabled.
996 */

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

1025 return(error);
1026}
1027
1028static void
1029amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1030{
1031 struct amr_command *ac = arg;
1032 struct amr_softc *sc = ac->ac_sc;
1335 }
1336 return(error);
1337}
1338
1339/********************************************************************************
1340 * Take a command, submit it to the controller and busy-wait for it to return.
1341 * Returns nonzero on error. Can be safely called with interrupts enabled.
1342 */

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

1371 return(error);
1372}
1373
1374static void
1375amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1376{
1377 struct amr_command *ac = arg;
1378 struct amr_softc *sc = ac->ac_sc;
1379 int flags;
1033
1380
1034 amr_setup_dmamap(arg, segs, nsegs, err);
1035 if (ac->ac_flags & AMR_CMD_DATAIN) {
1036 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
1037 BUS_DMASYNC_PREREAD);
1381 flags = 0;
1382 if (ac->ac_flags & AMR_CMD_DATAIN)
1383 flags |= BUS_DMASYNC_PREREAD;
1384 if (ac->ac_flags & AMR_CMD_DATAOUT)
1385 flags |= BUS_DMASYNC_PREWRITE;
1386
1387 if (AC_IS_SG64(ac)) {
1388 amr_setup_dma64map(arg, segs, nsegs, err);
1389 bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_dma64map, flags);
1390 } else {
1391 amr_setup_dmamap(arg, segs, nsegs, err);
1392 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, flags);
1038 }
1393 }
1039 if (ac->ac_flags & AMR_CMD_DATAOUT) {
1040 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
1041 BUS_DMASYNC_PREWRITE);
1042 }
1043 sc->amr_poll_command1(sc, ac);
1044}
1045
1046/********************************************************************************
1047 * Take a command, submit it to the controller and busy-wait for it to return.
1048 * Returns nonzero on error. Can be safely called with interrupts enabled.
1049 */
1050static int
1051amr_quartz_poll_command(struct amr_command *ac)
1052{
1394 sc->amr_poll_command1(sc, ac);
1395}
1396
1397/********************************************************************************
1398 * Take a command, submit it to the controller and busy-wait for it to return.
1399 * Returns nonzero on error. Can be safely called with interrupts enabled.
1400 */
1401static int
1402amr_quartz_poll_command(struct amr_command *ac)
1403{
1404 bus_dma_tag_t tag;
1405 bus_dmamap_t datamap;
1053 struct amr_softc *sc = ac->ac_sc;
1054 int error;
1055
1056 debug_called(2);
1057
1058 error = 0;
1059
1406 struct amr_softc *sc = ac->ac_sc;
1407 int error;
1408
1409 debug_called(2);
1410
1411 error = 0;
1412
1413 if (AC_IS_SG64(ac)) {
1414 tag = sc->amr_buffer64_dmat;
1415 datamap = ac->ac_dma64map;
1416 } else {
1417 tag = sc->amr_buffer_dmat;
1418 datamap = ac->ac_dmamap;
1419 }
1420
1060 /* now we have a slot, we can map the command (unmapped in amr_complete) */
1061 if (ac->ac_data != 0) {
1421 /* now we have a slot, we can map the command (unmapped in amr_complete) */
1422 if (ac->ac_data != 0) {
1062 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
1063 ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
1423 if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length,
1424 amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
1064 error = 1;
1065 }
1066 } else {
1067 error = amr_quartz_poll_command1(sc, ac);
1068 }
1069
1070 return (error);
1071}
1072
1073static int
1074amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac)
1075{
1076 int count, error;
1077
1425 error = 1;
1426 }
1427 } else {
1428 error = amr_quartz_poll_command1(sc, ac);
1429 }
1430
1431 return (error);
1432}
1433
1434static int
1435amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac)
1436{
1437 int count, error;
1438
1439 mtx_lock(&sc->amr_hw_lock);
1078 if ((sc->amr_state & AMR_STATE_INTEN) == 0) {
1079 count=0;
1080 while (sc->amr_busyslots) {
1440 if ((sc->amr_state & AMR_STATE_INTEN) == 0) {
1441 count=0;
1442 while (sc->amr_busyslots) {
1081 msleep(sc, &sc->amr_io_lock, PRIBIO | PCATCH, "amrpoll", hz);
1443 msleep(sc, &sc->amr_hw_lock, PRIBIO | PCATCH, "amrpoll", hz);
1082 if(count++>10) {
1083 break;
1084 }
1085 }
1086
1087 if(sc->amr_busyslots) {
1088 device_printf(sc->amr_dev, "adapter is busy\n");
1444 if(count++>10) {
1445 break;
1446 }
1447 }
1448
1449 if(sc->amr_busyslots) {
1450 device_printf(sc->amr_dev, "adapter is busy\n");
1089 if (ac->ac_data != NULL)
1090 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1451 mtx_unlock(&sc->amr_hw_lock);
1452 if (ac->ac_data != NULL) {
1453 if (AC_IS_SG64(ac))
1454 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map);
1455 else
1456 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1457 }
1091 ac->ac_status=0;
1092 return(1);
1093 }
1094 }
1095
1096 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1097
1098 /* clear the poll/ack fields in the mailbox */

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

1111 error = (ac->ac_status !=AMR_STATUS_SUCCESS) ? 1:0;
1112 while(sc->amr_mailbox->mb_poll != 0x77);
1113 sc->amr_mailbox->mb_poll = 0;
1114 sc->amr_mailbox->mb_ack = 0x77;
1115
1116 /* acknowledge that we have the commands */
1117 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
1118 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK);
1458 ac->ac_status=0;
1459 return(1);
1460 }
1461 }
1462
1463 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1464
1465 /* clear the poll/ack fields in the mailbox */

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

1478 error = (ac->ac_status !=AMR_STATUS_SUCCESS) ? 1:0;
1479 while(sc->amr_mailbox->mb_poll != 0x77);
1480 sc->amr_mailbox->mb_poll = 0;
1481 sc->amr_mailbox->mb_ack = 0x77;
1482
1483 /* acknowledge that we have the commands */
1484 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
1485 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK);
1486 mtx_unlock(&sc->amr_hw_lock);
1119
1120 /* unmap the command's data buffer */
1121 if (ac->ac_flags & AMR_CMD_DATAIN) {
1122 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
1123 BUS_DMASYNC_POSTREAD);
1124 }
1125 if (ac->ac_flags & AMR_CMD_DATAOUT) {
1126 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
1127 BUS_DMASYNC_POSTWRITE);
1128 }
1487
1488 /* unmap the command's data buffer */
1489 if (ac->ac_flags & AMR_CMD_DATAIN) {
1490 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
1491 BUS_DMASYNC_POSTREAD);
1492 }
1493 if (ac->ac_flags & AMR_CMD_DATAOUT) {
1494 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
1495 BUS_DMASYNC_POSTWRITE);
1496 }
1129 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1497 if (AC_IS_SG64(ac))
1498 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map);
1499 else
1500 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1130
1131 return(error);
1132}
1133
1501
1502 return(error);
1503}
1504
1134/********************************************************************************
1135 * Get a free command slot for a command if it doesn't already have one.
1136 *
1137 * May be safely called multiple times for a given command.
1138 */
1139static int
1140amr_getslot(struct amr_command *ac)
1505static __inline int
1506amr_freeslot(struct amr_command *ac)
1141{
1507{
1142 struct amr_softc *sc = ac->ac_sc;
1143 int slot;
1508 struct amr_softc *sc = ac->ac_sc;
1509 int slot;
1144
1145 debug_called(3);
1146
1147 slot = ac->ac_slot;
1510
1511 debug_called(3);
1512
1513 slot = ac->ac_slot;
1148 if (sc->amr_busycmd[slot] != NULL)
1149 panic("amr: slot %d busy?\n", slot);
1514 if (sc->amr_busycmd[slot] == NULL)
1515 panic("amr: slot %d not busy?\n", slot);
1150
1516
1151 sc->amr_busycmd[slot] = ac;
1152 sc->amr_busyslots++;
1517 sc->amr_busycmd[slot] = NULL;
1518 atomic_subtract_int(&sc->amr_busyslots, 1);
1153
1154 return (0);
1155}
1156
1157/********************************************************************************
1158 * Map/unmap (ac)'s data in the controller's addressable space as required.
1159 *
1160 * These functions may be safely called multiple times on a given command.
1161 */
1162static void
1163amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1164{
1165 struct amr_command *ac = (struct amr_command *)arg;
1519
1520 return (0);
1521}
1522
1523/********************************************************************************
1524 * Map/unmap (ac)'s data in the controller's addressable space as required.
1525 *
1526 * These functions may be safely called multiple times on a given command.
1527 */
1528static void
1529amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1530{
1531 struct amr_command *ac = (struct amr_command *)arg;
1166 struct amr_softc *sc = ac->ac_sc;
1167 struct amr_sgentry *sg;
1168 int i;
1169 u_int8_t *sgc;
1170
1171 debug_called(3);
1172
1173 /* get base address of s/g table */
1532 struct amr_sgentry *sg;
1533 int i;
1534 u_int8_t *sgc;
1535
1536 debug_called(3);
1537
1538 /* get base address of s/g table */
1174 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
1539 sg = ac->ac_sg.sg32;
1175
1176 /* save data physical address */
1540
1541 /* save data physical address */
1177 ac->ac_dataphys = segs[0].ds_addr;
1178
1542
1179 /* for AMR_CMD_CONFIG the s/g count goes elsewhere */
1180 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG) {
1543 /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
1544 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && (
1545 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG ||
1546 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)) {
1181 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param);
1182 } else {
1183 sgc = &ac->ac_mailbox.mb_nsgelem;
1184 }
1185
1186 /* decide whether we need to populate the s/g table */
1187 if (nsegments < 2) {
1188 *sgc = 0;
1189 ac->ac_mailbox.mb_nsgelem = 0;
1547 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param);
1548 } else {
1549 sgc = &ac->ac_mailbox.mb_nsgelem;
1550 }
1551
1552 /* decide whether we need to populate the s/g table */
1553 if (nsegments < 2) {
1554 *sgc = 0;
1555 ac->ac_mailbox.mb_nsgelem = 0;
1190 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
1556 ac->ac_mailbox.mb_physaddr = segs[0].ds_addr;
1191 } else {
1192 ac->ac_mailbox.mb_nsgelem = nsegments;
1193 *sgc = nsegments;
1557 } else {
1558 ac->ac_mailbox.mb_nsgelem = nsegments;
1559 *sgc = nsegments;
1194 ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr +
1195 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
1560 /* XXX Setting these to 0 might not be needed. */
1561 ac->ac_sg64_lo = 0;
1562 ac->ac_sg64_hi = 0;
1563 ac->ac_mailbox.mb_physaddr = ac->ac_sgbusaddr;
1196 for (i = 0; i < nsegments; i++, sg++) {
1197 sg->sg_addr = segs[i].ds_addr;
1198 sg->sg_count = segs[i].ds_len;
1199 }
1200 }
1201
1202}
1203
1204static void
1564 for (i = 0; i < nsegments; i++, sg++) {
1565 sg->sg_addr = segs[i].ds_addr;
1566 sg->sg_count = segs[i].ds_len;
1567 }
1568 }
1569
1570}
1571
1572static void
1573amr_setup_dma64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1574{
1575 struct amr_command *ac = (struct amr_command *)arg;
1576 struct amr_sg64entry *sg;
1577 int i;
1578 u_int8_t *sgc;
1579
1580 debug_called(3);
1581
1582 /* get base address of s/g table */
1583 sg = ac->ac_sg.sg64;
1584
1585 /* save data physical address */
1586
1587 /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
1588 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && (
1589 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG ||
1590 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)) {
1591 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param);
1592 } else {
1593 sgc = &ac->ac_mailbox.mb_nsgelem;
1594 }
1595
1596 ac->ac_mailbox.mb_nsgelem = nsegments;
1597 *sgc = nsegments;
1598 ac->ac_sg64_hi = 0;
1599 ac->ac_sg64_lo = ac->ac_sgbusaddr;
1600 ac->ac_mailbox.mb_physaddr = 0xffffffff;
1601 for (i = 0; i < nsegments; i++, sg++) {
1602 sg->sg_addr = segs[i].ds_addr;
1603 sg->sg_count = segs[i].ds_len;
1604 }
1605}
1606
1607static void
1205amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1206{
1207 struct amr_command *ac = (struct amr_command *)arg;
1208 struct amr_softc *sc = ac->ac_sc;
1209 struct amr_sgentry *sg;
1210 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
1211 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data;
1212 int i;
1213
1214 /* get base address of s/g table */
1608amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1609{
1610 struct amr_command *ac = (struct amr_command *)arg;
1611 struct amr_softc *sc = ac->ac_sc;
1612 struct amr_sgentry *sg;
1613 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
1614 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data;
1615 int i;
1616
1617 /* get base address of s/g table */
1215 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
1618 sg = ac->ac_sg.sg32;
1216
1217 /* decide whether we need to populate the s/g table */
1218 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) {
1219 if (nsegments < 2) {
1220 aep->ap_no_sg_elements = 0;
1221 aep->ap_data_transfer_address = segs[0].ds_addr;
1222 } else {
1223 /* save s/g table information in passthrough */
1224 aep->ap_no_sg_elements = nsegments;
1619
1620 /* decide whether we need to populate the s/g table */
1621 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) {
1622 if (nsegments < 2) {
1623 aep->ap_no_sg_elements = 0;
1624 aep->ap_data_transfer_address = segs[0].ds_addr;
1625 } else {
1626 /* save s/g table information in passthrough */
1627 aep->ap_no_sg_elements = nsegments;
1225 aep->ap_data_transfer_address = sc->amr_sgbusaddr +
1226 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
1628 aep->ap_data_transfer_address = ac->ac_sgbusaddr;
1227 /*
1228 * populate s/g table (overwrites previous call which mapped the
1229 * passthrough)
1230 */
1231 for (i = 0; i < nsegments; i++, sg++) {
1232 sg->sg_addr = segs[i].ds_addr;
1233 sg->sg_count = segs[i].ds_len;
1234 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
1235 }
1236 }
1629 /*
1630 * populate s/g table (overwrites previous call which mapped the
1631 * passthrough)
1632 */
1633 for (i = 0; i < nsegments; i++, sg++) {
1634 sg->sg_addr = segs[i].ds_addr;
1635 sg->sg_count = segs[i].ds_len;
1636 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
1637 }
1638 }
1237 debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x\n",
1238 ac->ac_slot, aep->ap_no_sg_elements, aep->ap_data_transfer_address,
1239 ac->ac_dataphys);
1639 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot,
1640 aep->ap_no_sg_elements, aep->ap_data_transfer_address);
1240 } else {
1241 if (nsegments < 2) {
1242 ap->ap_no_sg_elements = 0;
1243 ap->ap_data_transfer_address = segs[0].ds_addr;
1244 } else {
1245 /* save s/g table information in passthrough */
1246 ap->ap_no_sg_elements = nsegments;
1641 } else {
1642 if (nsegments < 2) {
1643 ap->ap_no_sg_elements = 0;
1644 ap->ap_data_transfer_address = segs[0].ds_addr;
1645 } else {
1646 /* save s/g table information in passthrough */
1647 ap->ap_no_sg_elements = nsegments;
1247 ap->ap_data_transfer_address = sc->amr_sgbusaddr +
1248 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
1648 ap->ap_data_transfer_address = ac->ac_sgbusaddr;
1249 /*
1250 * populate s/g table (overwrites previous call which mapped the
1251 * passthrough)
1252 */
1253 for (i = 0; i < nsegments; i++, sg++) {
1254 sg->sg_addr = segs[i].ds_addr;
1255 sg->sg_count = segs[i].ds_len;
1256 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
1257 }
1258 }
1649 /*
1650 * populate s/g table (overwrites previous call which mapped the
1651 * passthrough)
1652 */
1653 for (i = 0; i < nsegments; i++, sg++) {
1654 sg->sg_addr = segs[i].ds_addr;
1655 sg->sg_count = segs[i].ds_len;
1656 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
1657 }
1658 }
1259 debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x",
1260 ac->ac_slot, ap->ap_no_sg_elements, ap->ap_data_transfer_address,
1261 ac->ac_dataphys);
1659 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot,
1660 ap->ap_no_sg_elements, ap->ap_data_transfer_address);
1262 }
1263 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1264 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1265 BUS_DMASYNC_PREREAD);
1266 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1267 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1268 BUS_DMASYNC_PREWRITE);
1269 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0)
1270 panic("no direction for ccb?\n");
1271
1272 if (ac->ac_flags & AMR_CMD_DATAIN)
1273 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
1274 if (ac->ac_flags & AMR_CMD_DATAOUT)
1275 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
1276
1277 ac->ac_flags |= AMR_CMD_MAPPED;
1278
1661 }
1662 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1663 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1664 BUS_DMASYNC_PREREAD);
1665 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1666 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1667 BUS_DMASYNC_PREWRITE);
1668 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0)
1669 panic("no direction for ccb?\n");
1670
1671 if (ac->ac_flags & AMR_CMD_DATAIN)
1672 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
1673 if (ac->ac_flags & AMR_CMD_DATAOUT)
1674 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
1675
1676 ac->ac_flags |= AMR_CMD_MAPPED;
1677
1279 amr_start1(sc, ac);
1678 if (amr_start1(sc, ac) == EBUSY) {
1679 amr_freeslot(ac);
1680 amr_requeue_ready(ac);
1681 }
1280}
1281
1682}
1683
1684static void
1685amr_setup_ccb64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1686{
1687 struct amr_command *ac = (struct amr_command *)arg;
1688 struct amr_softc *sc = ac->ac_sc;
1689 struct amr_sg64entry *sg;
1690 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
1691 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data;
1692 int i;
1693
1694 /* get base address of s/g table */
1695 sg = ac->ac_sg.sg64;
1696
1697 /* decide whether we need to populate the s/g table */
1698 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) {
1699 /* save s/g table information in passthrough */
1700 aep->ap_no_sg_elements = nsegments;
1701 aep->ap_data_transfer_address = ac->ac_sgbusaddr;
1702 /*
1703 * populate s/g table (overwrites previous call which mapped the
1704 * passthrough)
1705 */
1706 for (i = 0; i < nsegments; i++, sg++) {
1707 sg->sg_addr = segs[i].ds_addr;
1708 sg->sg_count = segs[i].ds_len;
1709 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
1710 }
1711 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot,
1712 aep->ap_no_sg_elements, aep->ap_data_transfer_address);
1713 } else {
1714 /* save s/g table information in passthrough */
1715 ap->ap_no_sg_elements = nsegments;
1716 ap->ap_data_transfer_address = ac->ac_sgbusaddr;
1717 /*
1718 * populate s/g table (overwrites previous call which mapped the
1719 * passthrough)
1720 */
1721 for (i = 0; i < nsegments; i++, sg++) {
1722 sg->sg_addr = segs[i].ds_addr;
1723 sg->sg_count = segs[i].ds_len;
1724 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
1725 }
1726 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot,
1727 ap->ap_no_sg_elements, ap->ap_data_transfer_address);
1728 }
1729 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1730 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map,
1731 BUS_DMASYNC_PREREAD);
1732 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1733 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map,
1734 BUS_DMASYNC_PREWRITE);
1735 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0)
1736 panic("no direction for ccb?\n");
1737
1738 if (ac->ac_flags & AMR_CMD_DATAIN)
1739 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map,
1740 BUS_DMASYNC_PREREAD);
1741 if (ac->ac_flags & AMR_CMD_DATAOUT)
1742 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map,
1743 BUS_DMASYNC_PREWRITE);
1744
1745 ac->ac_flags |= AMR_CMD_MAPPED;
1746
1747 if (amr_start1(sc, ac) == EBUSY) {
1748 amr_freeslot(ac);
1749 amr_requeue_ready(ac);
1750 }
1751}
1752
1282static int
1283amr_mapcmd(struct amr_command *ac)
1284{
1753static int
1754amr_mapcmd(struct amr_command *ac)
1755{
1756 bus_dma_tag_t tag;
1757 bus_dmamap_t datamap, ccbmap;
1758 bus_dmamap_callback_t *cb;
1759 bus_dmamap_callback_t *ccb_cb;
1285 struct amr_softc *sc = ac->ac_sc;
1286
1287 debug_called(3);
1288
1760 struct amr_softc *sc = ac->ac_sc;
1761
1762 debug_called(3);
1763
1764 if (AC_IS_SG64(ac)) {
1765 tag = sc->amr_buffer64_dmat;
1766 datamap = ac->ac_dma64map;
1767 ccbmap = ac->ac_ccb_dma64map;
1768 cb = amr_setup_dma64map;
1769 ccb_cb = amr_setup_ccb64map;
1770 } else {
1771 tag = sc->amr_buffer_dmat;
1772 datamap = ac->ac_dmamap;
1773 ccbmap = ac->ac_ccb_dmamap;
1774 cb = amr_setup_dmamap;
1775 ccb_cb = amr_setup_ccbmap;
1776 }
1777
1289 /* if the command involves data at all, and hasn't been mapped */
1290 if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
1291 if (ac->ac_ccb_data == NULL) {
1292 /* map the data buffers into bus space and build the s/g list */
1778 /* if the command involves data at all, and hasn't been mapped */
1779 if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
1780 if (ac->ac_ccb_data == NULL) {
1781 /* map the data buffers into bus space and build the s/g list */
1293 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
1294 ac->ac_length, amr_setup_data_dmamap, ac, 0) == EINPROGRESS) {
1782 if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length,
1783 amr_setup_data_dmamap, ac, 0) == EINPROGRESS) {
1295 sc->amr_state |= AMR_STATE_QUEUE_FRZN;
1296 }
1297 } else {
1784 sc->amr_state |= AMR_STATE_QUEUE_FRZN;
1785 }
1786 } else {
1298 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
1299 ac->ac_length, amr_setup_dmamap, ac, BUS_DMA_NOWAIT) != 0){
1787 if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length,
1788 cb, ac, BUS_DMA_NOWAIT) != 0) {
1300 return (ENOMEM);
1301 }
1789 return (ENOMEM);
1790 }
1302 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1303 ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccbmap, ac,
1304 0) == EINPROGRESS) {
1791 if (bus_dmamap_load(tag, ccbmap, ac->ac_ccb_data,
1792 ac->ac_ccb_length, ccb_cb, ac, 0) == EINPROGRESS) {
1305 sc->amr_state |= AMR_STATE_QUEUE_FRZN;
1306 }
1307 }
1793 sc->amr_state |= AMR_STATE_QUEUE_FRZN;
1794 }
1795 }
1308 } else if ((ac->ac_flags & AMR_CMD_MAPPED) == 0) {
1309 amr_start1(sc, ac);
1796 } else {
1797 if (amr_start1(sc, ac) == EBUSY) {
1798 amr_freeslot(ac);
1799 amr_requeue_ready(ac);
1800 }
1310 }
1311
1312 return (0);
1313}
1314
1315static void
1316amr_unmapcmd(struct amr_command *ac)
1317{
1318 struct amr_softc *sc = ac->ac_sc;
1801 }
1802
1803 return (0);
1804}
1805
1806static void
1807amr_unmapcmd(struct amr_command *ac)
1808{
1809 struct amr_softc *sc = ac->ac_sc;
1810 int flag;
1319
1320 debug_called(3);
1321
1322 /* if the command involved data at all and was mapped */
1323 if (ac->ac_flags & AMR_CMD_MAPPED) {
1324
1325 if (ac->ac_data != NULL) {
1811
1812 debug_called(3);
1813
1814 /* if the command involved data at all and was mapped */
1815 if (ac->ac_flags & AMR_CMD_MAPPED) {
1816
1817 if (ac->ac_data != NULL) {
1818
1819 flag = 0;
1326 if (ac->ac_flags & AMR_CMD_DATAIN)
1820 if (ac->ac_flags & AMR_CMD_DATAIN)
1327 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap,
1328 BUS_DMASYNC_POSTREAD);
1821 flag |= BUS_DMASYNC_POSTREAD;
1329 if (ac->ac_flags & AMR_CMD_DATAOUT)
1822 if (ac->ac_flags & AMR_CMD_DATAOUT)
1330 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap,
1331 BUS_DMASYNC_POSTWRITE);
1332 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1823 flag |= BUS_DMASYNC_POSTWRITE;
1824
1825 if (AC_IS_SG64(ac)) {
1826 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map, flag);
1827 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map);
1828 } else {
1829 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, flag);
1830 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1831 }
1333 }
1334
1335 if (ac->ac_ccb_data != NULL) {
1832 }
1833
1834 if (ac->ac_ccb_data != NULL) {
1835
1836 flag = 0;
1336 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1837 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1337 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1338 BUS_DMASYNC_POSTREAD);
1838 flag |= BUS_DMASYNC_POSTREAD;
1339 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1839 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1340 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
1341 BUS_DMASYNC_POSTWRITE);
1342 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
1840 flag |= BUS_DMASYNC_POSTWRITE;
1841
1842 if (AC_IS_SG64(ac)) {
1843 bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_ccb_dma64map,flag);
1844 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map);
1845 } else {
1846 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, flag);
1847 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
1848 }
1343 }
1344 ac->ac_flags &= ~AMR_CMD_MAPPED;
1345 }
1346}
1347
1348static void
1349amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1350{
1351 struct amr_command *ac = arg;
1352 struct amr_softc *sc = ac->ac_sc;
1849 }
1850 ac->ac_flags &= ~AMR_CMD_MAPPED;
1851 }
1852}
1853
1854static void
1855amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1856{
1857 struct amr_command *ac = arg;
1858 struct amr_softc *sc = ac->ac_sc;
1859 int flags;
1353
1860
1354 amr_setup_dmamap(arg, segs, nsegs, err);
1355
1861 flags = 0;
1356 if (ac->ac_flags & AMR_CMD_DATAIN)
1862 if (ac->ac_flags & AMR_CMD_DATAIN)
1357 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
1863 flags |= BUS_DMASYNC_PREREAD;
1358 if (ac->ac_flags & AMR_CMD_DATAOUT)
1864 if (ac->ac_flags & AMR_CMD_DATAOUT)
1359 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
1865 flags |= BUS_DMASYNC_PREWRITE;
1866
1867 if (AC_IS_SG64(ac)) {
1868 amr_setup_dma64map(arg, segs, nsegs, err);
1869 bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_dma64map, flags);
1870 } else {
1871 amr_setup_dmamap(arg, segs, nsegs, err);
1872 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, flags);
1873 }
1360 ac->ac_flags |= AMR_CMD_MAPPED;
1361
1874 ac->ac_flags |= AMR_CMD_MAPPED;
1875
1362 amr_start1(sc, ac);
1876 if (amr_start1(sc, ac) == EBUSY) {
1877 amr_freeslot(ac);
1878 amr_requeue_ready(ac);
1879 }
1363}
1364
1365/********************************************************************************
1366 * Take a command and give it to the controller, returns 0 if successful, or
1367 * EBUSY if the command should be retried later.
1368 */
1369static int
1370amr_start(struct amr_command *ac)
1371{
1372 struct amr_softc *sc;
1373 int error = 0;
1880}
1881
1882/********************************************************************************
1883 * Take a command and give it to the controller, returns 0 if successful, or
1884 * EBUSY if the command should be retried later.
1885 */
1886static int
1887amr_start(struct amr_command *ac)
1888{
1889 struct amr_softc *sc;
1890 int error = 0;
1891 int slot;
1374
1375 debug_called(3);
1376
1377 /* mark command as busy so that polling consumer can tell */
1378 sc = ac->ac_sc;
1379 ac->ac_flags |= AMR_CMD_BUSY;
1380
1381 /* get a command slot (freed in amr_done) */
1892
1893 debug_called(3);
1894
1895 /* mark command as busy so that polling consumer can tell */
1896 sc = ac->ac_sc;
1897 ac->ac_flags |= AMR_CMD_BUSY;
1898
1899 /* get a command slot (freed in amr_done) */
1382 if (amr_getslot(ac)) {
1383 return(EBUSY);
1384 }
1900 slot = ac->ac_slot;
1901 if (sc->amr_busycmd[slot] != NULL)
1902 panic("amr: slot %d busy?\n", slot);
1903 sc->amr_busycmd[slot] = ac;
1904 atomic_add_int(&sc->amr_busyslots, 1);
1385
1386 /* Now we have a slot, we can map the command (unmapped in amr_complete). */
1387 if ((error = amr_mapcmd(ac)) == ENOMEM) {
1388 /*
1389 * Memroy resources are short, so free the slot and let this be tried
1390 * later.
1391 */
1905
1906 /* Now we have a slot, we can map the command (unmapped in amr_complete). */
1907 if ((error = amr_mapcmd(ac)) == ENOMEM) {
1908 /*
1909 * Memroy resources are short, so free the slot and let this be tried
1910 * later.
1911 */
1392 sc->amr_busycmd[ac->ac_slot] = NULL;
1393 sc->amr_busyslots--;
1912 amr_freeslot(ac);
1394 }
1395
1396 return (error);
1397}
1398
1399
1400static int
1401amr_start1(struct amr_softc *sc, struct amr_command *ac)
1402{
1913 }
1914
1915 return (error);
1916}
1917
1918
1919static int
1920amr_start1(struct amr_softc *sc, struct amr_command *ac)
1921{
1403 int done, i;
1922 int i = 0;
1923
1924 mtx_lock(&sc->amr_hw_lock);
1925 while (sc->amr_mailbox->mb_busy && (i++ < 10))
1926 DELAY(1);
1927 if (sc->amr_mailbox->mb_busy) {
1928 mtx_unlock(&sc->amr_hw_lock);
1929 return (EBUSY);
1930 }
1404
1931
1405 /* mark the new mailbox we are going to copy in as busy */
1406 ac->ac_mailbox.mb_busy = 1;
1407
1408 /* clear the poll/ack fields in the mailbox */
1409 sc->amr_mailbox->mb_poll = 0;
1410 sc->amr_mailbox->mb_ack = 0;
1411
1412 /*
1413 * Save the slot number so that we can locate this command when complete.
1414 * Note that ident = 0 seems to be special, so we don't use it.
1415 */
1932 /*
1933 * Save the slot number so that we can locate this command when complete.
1934 * Note that ident = 0 seems to be special, so we don't use it.
1935 */
1416 ac->ac_mailbox.mb_ident = ac->ac_slot + 1;
1936 ac->ac_mailbox.mb_ident = ac->ac_slot + 1; /* will be coppied into mbox */
1937 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, 14);
1938 sc->amr_mailbox->mb_busy = 1;
1939 sc->amr_mailbox->mb_poll = 0;
1940 sc->amr_mailbox->mb_ack = 0;
1941 sc->amr_mailbox64->sg64_hi = ac->ac_sg64_hi;
1942 sc->amr_mailbox64->sg64_lo = ac->ac_sg64_lo;
1417
1943
1418 /*
1419 * Spin waiting for the mailbox, give up after ~1 second. We expect the
1420 * controller to be able to handle our I/O.
1421 *
1422 * XXX perhaps we should wait for less time, and count on the deferred command
1423 * handling to deal with retries?
1424 */
1425 debug(4, "wait for mailbox");
1426 for (i = 10000, done = 0; (i > 0) && !done; i--) {
1427
1428 /* is the mailbox free? */
1429 if (sc->amr_mailbox->mb_busy == 0) {
1430 debug(4, "got mailbox");
1431 sc->amr_mailbox64->mb64_segment = 0;
1432 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1433 done = 1;
1434
1435 /* not free, spin waiting */
1436 } else {
1437 debug(4, "busy flag %x\n", sc->amr_mailbox->mb_busy);
1438 /* this is somewhat ugly */
1439 DELAY(100);
1440 }
1944 if (sc->amr_submit_command(sc)) {
1945 /* the controller wasn't ready to take the command, forget that we tried to post it */
1946 sc->amr_mailbox->mb_busy = 0;
1947 mtx_unlock(&sc->amr_hw_lock);
1948 return (EBUSY);
1441 }
1442
1949 }
1950
1443 /*
1444 * Now give the command to the controller
1445 */
1446 if (done) {
1447 if (sc->amr_submit_command(sc)) {
1448 /* the controller wasn't ready to take the command, forget that we tried to post it */
1449 sc->amr_mailbox->mb_busy = 0;
1450 return(EBUSY);
1451 }
1452 debug(3, "posted command");
1453 return(0);
1454 }
1455
1456 /*
1457 * The controller wouldn't take the command. Return the command as busy
1458 * so that it is retried later.
1459 */
1460 return(EBUSY);
1951 mtx_unlock(&sc->amr_hw_lock);
1952 return(0);
1461}
1462
1463/********************************************************************************
1464 * Extract one or more completed commands from the controller (sc)
1465 *
1466 * Returns nonzero if any commands on the work queue were marked as completed.
1467 */
1468

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

1489 /* get pointer to busy command */
1490 idx = mbox.mb_completed[i] - 1;
1491 ac = sc->amr_busycmd[idx];
1492
1493 /* really a busy command? */
1494 if (ac != NULL) {
1495
1496 /* pull the command from the busy index */
1953}
1954
1955/********************************************************************************
1956 * Extract one or more completed commands from the controller (sc)
1957 *
1958 * Returns nonzero if any commands on the work queue were marked as completed.
1959 */
1960

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

1981 /* get pointer to busy command */
1982 idx = mbox.mb_completed[i] - 1;
1983 ac = sc->amr_busycmd[idx];
1984
1985 /* really a busy command? */
1986 if (ac != NULL) {
1987
1988 /* pull the command from the busy index */
1497 sc->amr_busycmd[idx] = NULL;
1498 sc->amr_busyslots--;
1989 amr_freeslot(ac);
1499
1500 /* save status for later use */
1501 ac->ac_status = mbox.mb_status;
1502 amr_enqueue_completed(ac);
1503 debug(3, "completed command with status %x", mbox.mb_status);
1504 } else {
1505 device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
1506 }
1507 }
1990
1991 /* save status for later use */
1992 ac->ac_status = mbox.mb_status;
1993 amr_enqueue_completed(ac);
1994 debug(3, "completed command with status %x", mbox.mb_status);
1995 } else {
1996 device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
1997 }
1998 }
1508 } else {
1999 } else
1509 break; /* no work */
2000 break; /* no work */
1510 }
1511 }
1512
1513 /* handle completion and timeouts */
1514 amr_complete(sc, 0);
1515
1516 return(result);
1517}
1518

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

1553 wakeup(ac);
1554 }
1555
1556 if(!sc->amr_busyslots) {
1557 wakeup(sc);
1558 }
1559 }
1560
2001 }
2002
2003 /* handle completion and timeouts */
2004 amr_complete(sc, 0);
2005
2006 return(result);
2007}
2008

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

2043 wakeup(ac);
2044 }
2045
2046 if(!sc->amr_busyslots) {
2047 wakeup(sc);
2048 }
2049 }
2050
2051 mtx_lock(&sc->amr_list_lock);
1561 sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
1562 amr_startio(sc);
2052 sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
2053 amr_startio(sc);
2054 mtx_unlock(&sc->amr_list_lock);
1563}
1564
1565/********************************************************************************
1566 ********************************************************************************
1567 Command Buffer Management
1568 ********************************************************************************
1569 ********************************************************************************/
1570

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

1629 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
1630 if (acc != NULL) {
1631 nextslot = sc->amr_nextslot;
1632 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
1633 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
1634 ac = &acc->acc_command[i];
1635 ac->ac_sc = sc;
1636 ac->ac_slot = nextslot;
2055}
2056
2057/********************************************************************************
2058 ********************************************************************************
2059 Command Buffer Management
2060 ********************************************************************************
2061 ********************************************************************************/
2062

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

2121 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
2122 if (acc != NULL) {
2123 nextslot = sc->amr_nextslot;
2124 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
2125 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
2126 ac = &acc->acc_command[i];
2127 ac->ac_sc = sc;
2128 ac->ac_slot = nextslot;
1637 if (!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) &&
1638 !bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap))
1639 amr_releasecmd(ac);
2129
2130 /*
2131 * The SG table for each slot is a fixed size and is assumed to
2132 * to hold 64-bit s/g objects when the driver is configured to do
2133 * 64-bit DMA. 32-bit DMA commands still use the same table, but
2134 * cast down to 32-bit objects.
2135 */
2136 if (AMR_IS_SG64(sc)) {
2137 ac->ac_sgbusaddr = sc->amr_sgbusaddr +
2138 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sg64entry));
2139 ac->ac_sg.sg64 = sc->amr_sg64table + (ac->ac_slot * AMR_NSEG);
2140 } else {
2141 ac->ac_sgbusaddr = sc->amr_sgbusaddr +
2142 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
2143 ac->ac_sg.sg32 = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
2144 }
2145
2146 if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) ||
2147 bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap) ||
2148 (AMR_IS_SG64(sc) &&
2149 (bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map) ||
2150 bus_dmamap_create(sc->amr_buffer64_dmat, 0, &ac->ac_ccb_dma64map))))
2151 break;
2152 amr_releasecmd(ac);
1640 if (++nextslot > sc->amr_maxio)
1641 break;
1642 }
1643 sc->amr_nextslot = nextslot;
1644 }
1645}
1646
1647/********************************************************************************
1648 * Free a command cluster
1649 */
1650static void
1651amr_freecmd_cluster(struct amr_command_cluster *acc)
1652{
1653 struct amr_softc *sc = acc->acc_command[0].ac_sc;
1654 int i;
1655
2153 if (++nextslot > sc->amr_maxio)
2154 break;
2155 }
2156 sc->amr_nextslot = nextslot;
2157 }
2158}
2159
2160/********************************************************************************
2161 * Free a command cluster
2162 */
2163static void
2164amr_freecmd_cluster(struct amr_command_cluster *acc)
2165{
2166 struct amr_softc *sc = acc->acc_command[0].ac_sc;
2167 int i;
2168
1656 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++)
2169 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
1657 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
2170 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
2171 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_ccb_dmamap);
2172 if (AMR_IS_SG64(sc))
2173 bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_dma64map);
2174 bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_ccb_dma64map);
2175 }
1658 free(acc, M_DEVBUF);
1659}
1660
1661/********************************************************************************
1662 ********************************************************************************
1663 Interface-specific Shims
1664 ********************************************************************************
1665 ********************************************************************************/
1666
1667/********************************************************************************
1668 * Tell the controller that the mailbox contains a valid command
1669 */
1670static int
1671amr_quartz_submit_command(struct amr_softc *sc)
1672{
1673 debug_called(3);
1674
2176 free(acc, M_DEVBUF);
2177}
2178
2179/********************************************************************************
2180 ********************************************************************************
2181 Interface-specific Shims
2182 ********************************************************************************
2183 ********************************************************************************/
2184
2185/********************************************************************************
2186 * Tell the controller that the mailbox contains a valid command
2187 */
2188static int
2189amr_quartz_submit_command(struct amr_softc *sc)
2190{
2191 debug_called(3);
2192
2193#if 0
1675 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT)
1676 return(EBUSY);
2194 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT)
2195 return(EBUSY);
2196#endif
1677 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
1678 return(0);
1679}
1680
1681static int
1682amr_std_submit_command(struct amr_softc *sc)
1683{
1684 debug_called(3);

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

1691
1692/********************************************************************************
1693 * Claim any work that the controller has completed; acknowledge completion,
1694 * save details of the completion in (mbsave)
1695 */
1696static int
1697amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1698{
2197 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
2198 return(0);
2199}
2200
2201static int
2202amr_std_submit_command(struct amr_softc *sc)
2203{
2204 debug_called(3);

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

2211
2212/********************************************************************************
2213 * Claim any work that the controller has completed; acknowledge completion,
2214 * save details of the completion in (mbsave)
2215 */
2216static int
2217amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
2218{
1699 int worked;
2219 int worked, i;
1700 u_int32_t outd;
2220 u_int32_t outd;
1701 u_int8_t nstatus;
2221 u_int8_t nstatus ,status;
2222 u_int8_t completed[46];
1702
1703 debug_called(3);
1704
1705 worked = 0;
1706
1707 /* work waiting for us? */
1708 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
1709
1710 /* acknowledge interrupt */
1711 AMR_QPUT_ODB(sc, AMR_QODB_READY);
1712
1713 while ((nstatus = sc->amr_mailbox->mb_nstatus) == 0xff)
2223
2224 debug_called(3);
2225
2226 worked = 0;
2227
2228 /* work waiting for us? */
2229 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
2230
2231 /* acknowledge interrupt */
2232 AMR_QPUT_ODB(sc, AMR_QODB_READY);
2233
2234 while ((nstatus = sc->amr_mailbox->mb_nstatus) == 0xff)
1714 ;
2235 cpu_spinwait();
1715 sc->amr_mailbox->mb_nstatus = 0xff;
1716
2236 sc->amr_mailbox->mb_nstatus = 0xff;
2237
1717 /* save mailbox, which contains a list of completed commands */
1718 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
2238 /* wait until fw wrote out all completions */
2239 for (i = 0; i < nstatus; i++) {
2240 while ((completed[i] = sc->amr_mailbox->mb_completed[i]) == 0xff)
2241 cpu_spinwait();
2242 sc->amr_mailbox->mb_completed[i] = 0xff;
2243 }
2244
2245 /* this should never happen, someone screwed up the completion status */
2246 if ((status = sc->amr_mailbox->mb_status) == 0xff) {
2247 device_printf(sc->amr_dev, "status 0xff from the firmware\n");
2248 return (worked);
2249 }
2250 sc->amr_mailbox->mb_status = 0xff;
2251
2252 /* Save information for later processing */
1719 mbsave->mb_nstatus = nstatus;
2253 mbsave->mb_nstatus = nstatus;
2254 mbsave->mb_status = status;
2255 for (i = 0; i < nstatus; i++)
2256 mbsave->mb_completed[i] = completed[i];
1720
1721 /* acknowledge that we have the commands */
1722 AMR_QPUT_IDB(sc, AMR_QIDB_ACK);
1723
2257
2258 /* acknowledge that we have the commands */
2259 AMR_QPUT_IDB(sc, AMR_QIDB_ACK);
2260
2261#if 0
1724#ifndef AMR_QUARTZ_GOFASTER
1725 /*
1726 * This waits for the controller to notice that we've taken the
1727 * command from it. It's very inefficient, and we shouldn't do it,
1728 * but if we remove this code, we stop completing commands under
1729 * load.
1730 *
1731 * Peter J says we shouldn't do this. The documentation says we
1732 * should. Who is right?
1733 */
1734 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
1735 ; /* XXX aiee! what if it dies? */
1736#endif
2262#ifndef AMR_QUARTZ_GOFASTER
2263 /*
2264 * This waits for the controller to notice that we've taken the
2265 * command from it. It's very inefficient, and we shouldn't do it,
2266 * but if we remove this code, we stop completing commands under
2267 * load.
2268 *
2269 * Peter J says we shouldn't do this. The documentation says we
2270 * should. Who is right?
2271 */
2272 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
2273 ; /* XXX aiee! what if it dies? */
2274#endif
2275#endif
1737
1738 worked = 1; /* got some work */
1739 }
1740
1741 return(worked);
1742}
1743
1744static int

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

1854 * Identify the controller and print some information about it.
1855 */
1856static void
1857amr_describe_controller(struct amr_softc *sc)
1858{
1859 struct amr_prodinfo *ap;
1860 struct amr_enquiry *ae;
1861 char *prod;
2276
2277 worked = 1; /* got some work */
2278 }
2279
2280 return(worked);
2281}
2282
2283static int

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

2393 * Identify the controller and print some information about it.
2394 */
2395static void
2396amr_describe_controller(struct amr_softc *sc)
2397{
2398 struct amr_prodinfo *ap;
2399 struct amr_enquiry *ae;
2400 char *prod;
2401 int status;
1862
2402
1863 mtx_lock(&sc->amr_io_lock);
1864 /*
1865 * Try to get 40LD product info, which tells us what the card is labelled as.
1866 */
2403 /*
2404 * Try to get 40LD product info, which tells us what the card is labelled as.
2405 */
1867 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) != NULL) {
2406 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0, &status)) != NULL) {
1868 device_printf(sc->amr_dev, "<LSILogic %.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
1869 ap->ap_product, ap->ap_firmware, ap->ap_bios,
1870 ap->ap_memsize);
1871
1872 free(ap, M_DEVBUF);
2407 device_printf(sc->amr_dev, "<LSILogic %.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
2408 ap->ap_product, ap->ap_firmware, ap->ap_bios,
2409 ap->ap_memsize);
2410
2411 free(ap, M_DEVBUF);
1873 mtx_unlock(&sc->amr_io_lock);
1874 return;
1875 }
1876
1877 /*
1878 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
1879 */
2412 return;
2413 }
2414
2415 /*
2416 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
2417 */
1880 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) {
2418 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0, &status)) != NULL) {
1881 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
1882
2419 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
2420
1883 } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) != NULL) {
2421 } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0, &status)) != NULL) {
1884
1885 /*
1886 * Try to work it out based on the PCI signatures.
1887 */
1888 switch (pci_get_device(sc->amr_dev)) {
1889 case 0x9010:
1890 prod = "Series 428";
1891 break;
1892 case 0x9060:
1893 prod = "Series 434";
1894 break;
1895 default:
1896 prod = "unknown controller";
1897 break;
1898 }
1899 } else {
1900 device_printf(sc->amr_dev, "<unsupported controller>\n");
2422
2423 /*
2424 * Try to work it out based on the PCI signatures.
2425 */
2426 switch (pci_get_device(sc->amr_dev)) {
2427 case 0x9010:
2428 prod = "Series 428";
2429 break;
2430 case 0x9060:
2431 prod = "Series 434";
2432 break;
2433 default:
2434 prod = "unknown controller";
2435 break;
2436 }
2437 } else {
2438 device_printf(sc->amr_dev, "<unsupported controller>\n");
1901 mtx_unlock(&sc->amr_io_lock);
1902 return;
1903 }
1904
1905 /*
1906 * HP NetRaid controllers have a special encoding of the firmware and
1907 * BIOS versions. The AMI version seems to have it as strings whereas
1908 * the HP version does it with a leading uppercase character and two
1909 * binary numbers.

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

1934 ae->ae_adapter.aa_bios[0],
1935 ae->ae_adapter.aa_memorysize);
1936 } else {
1937 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
1938 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
1939 ae->ae_adapter.aa_memorysize);
1940 }
1941 free(ae, M_DEVBUF);
2439 return;
2440 }
2441
2442 /*
2443 * HP NetRaid controllers have a special encoding of the firmware and
2444 * BIOS versions. The AMI version seems to have it as strings whereas
2445 * the HP version does it with a leading uppercase character and two
2446 * binary numbers.

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

2471 ae->ae_adapter.aa_bios[0],
2472 ae->ae_adapter.aa_memorysize);
2473 } else {
2474 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
2475 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
2476 ae->ae_adapter.aa_memorysize);
2477 }
2478 free(ae, M_DEVBUF);
1942 mtx_unlock(&sc->amr_io_lock);
1943}
1944
1945int
1946amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks)
1947{
1948 struct amr_command *ac;
1949 int error = EIO;
1950

--- 63 unchanged lines hidden ---
2479}
2480
2481int
2482amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks)
2483{
2484 struct amr_command *ac;
2485 int error = EIO;
2486

--- 63 unchanged lines hidden ---