mlx.c (54073) | mlx.c (54419) |
---|---|
1/*- 2 * Copyright (c) 1999 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 1999 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/dev/mlx/mlx.c 54073 1999-12-03 08:41:24Z mdodd $ | 26 * $FreeBSD: head/sys/dev/mlx/mlx.c 54419 1999-12-11 00:00:13Z msmith $ |
27 */ 28 29/* 30 * Driver for the Mylex DAC960 family of RAID controllers. 31 */ 32 33#include <sys/param.h> 34#include <sys/systm.h> --- 49 unchanged lines hidden (view full) --- 84static int mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 85static int mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 86static void mlx_v3_intaction(struct mlx_softc *sc, int action); 87 88static int mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 89static int mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 90static void mlx_v4_intaction(struct mlx_softc *sc, int action); 91 | 27 */ 28 29/* 30 * Driver for the Mylex DAC960 family of RAID controllers. 31 */ 32 33#include <sys/param.h> 34#include <sys/systm.h> --- 49 unchanged lines hidden (view full) --- 84static int mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 85static int mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 86static void mlx_v3_intaction(struct mlx_softc *sc, int action); 87 88static int mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 89static int mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 90static void mlx_v4_intaction(struct mlx_softc *sc, int action); 91 |
92static int mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 93static int mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 94static void mlx_v5_intaction(struct mlx_softc *sc, int action); 95 |
|
92/* 93 * Status monitoring 94 */ 95static void mlx_periodic(void *data); 96static void mlx_periodic_enquiry(struct mlx_command *mc); 97static void mlx_periodic_eventlog_poll(struct mlx_softc *sc); 98static void mlx_periodic_eventlog_respond(struct mlx_command *mc); 99static void mlx_periodic_rebuild(struct mlx_command *mc); --- 191 unchanged lines hidden (view full) --- 291 sc->mlx_findcomplete = mlx_v3_findcomplete; 292 sc->mlx_intaction = mlx_v3_intaction; 293 break; 294 case MLX_IFTYPE_4: 295 sc->mlx_tryqueue = mlx_v4_tryqueue; 296 sc->mlx_findcomplete = mlx_v4_findcomplete; 297 sc->mlx_intaction = mlx_v4_intaction; 298 break; | 96/* 97 * Status monitoring 98 */ 99static void mlx_periodic(void *data); 100static void mlx_periodic_enquiry(struct mlx_command *mc); 101static void mlx_periodic_eventlog_poll(struct mlx_softc *sc); 102static void mlx_periodic_eventlog_respond(struct mlx_command *mc); 103static void mlx_periodic_rebuild(struct mlx_command *mc); --- 191 unchanged lines hidden (view full) --- 295 sc->mlx_findcomplete = mlx_v3_findcomplete; 296 sc->mlx_intaction = mlx_v3_intaction; 297 break; 298 case MLX_IFTYPE_4: 299 sc->mlx_tryqueue = mlx_v4_tryqueue; 300 sc->mlx_findcomplete = mlx_v4_findcomplete; 301 sc->mlx_intaction = mlx_v4_intaction; 302 break; |
303 case MLX_IFTYPE_5: 304 sc->mlx_tryqueue = mlx_v5_tryqueue; 305 sc->mlx_findcomplete = mlx_v5_findcomplete; 306 sc->mlx_intaction = mlx_v5_intaction; 307 break; |
|
299 default: 300 device_printf(sc->mlx_dev, "attaching unsupported interface version %d\n", sc->mlx_iftype); 301 return(ENXIO); /* should never happen */ 302 } 303 304 /* disable interrupts before we start talking to the controller */ 305 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 306 --- 90 unchanged lines hidden (view full) --- 397 break; 398 case MLX_IFTYPE_4: 399 /* XXX certify firmware versions? */ 400 if (sc->mlx_fwminor < 6) { 401 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 402 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n"); 403 } 404 break; | 308 default: 309 device_printf(sc->mlx_dev, "attaching unsupported interface version %d\n", sc->mlx_iftype); 310 return(ENXIO); /* should never happen */ 311 } 312 313 /* disable interrupts before we start talking to the controller */ 314 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 315 --- 90 unchanged lines hidden (view full) --- 406 break; 407 case MLX_IFTYPE_4: 408 /* XXX certify firmware versions? */ 409 if (sc->mlx_fwminor < 6) { 410 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 411 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n"); 412 } 413 break; |
414 case MLX_IFTYPE_5: 415 if (sc->mlx_fwminor < 7) { 416 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 417 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n"); 418 } 419 break; |
|
405 default: 406 device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype); 407 return(ENXIO); /* should never happen */ 408 } 409 410 /* 411 * Create the final set of s/g mappings now that we know how many commands 412 * the controller actually supports. --- 86 unchanged lines hidden (view full) --- 499 500/******************************************************************************** 501 * Disconnect from the controller completely, in preparation for unload. 502 */ 503int 504mlx_detach(device_t dev) 505{ 506 struct mlx_softc *sc = device_get_softc(dev); | 420 default: 421 device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype); 422 return(ENXIO); /* should never happen */ 423 } 424 425 /* 426 * Create the final set of s/g mappings now that we know how many commands 427 * the controller actually supports. --- 86 unchanged lines hidden (view full) --- 514 515/******************************************************************************** 516 * Disconnect from the controller completely, in preparation for unload. 517 */ 518int 519mlx_detach(device_t dev) 520{ 521 struct mlx_softc *sc = device_get_softc(dev); |
507 int error; | 522 struct mlxd_softc *mlxd; 523 int i, s, error; |
508 509 debug("called"); 510 | 524 525 debug("called"); 526 |
527 error = EBUSY; 528 s = splbio(); |
|
511 if (sc->mlx_state & MLX_STATE_OPEN) | 529 if (sc->mlx_state & MLX_STATE_OPEN) |
512 return(EBUSY); | 530 goto out; |
513 | 531 |
532 for (i = 0; i < MLX_MAXDRIVES; i++) { 533 if (sc->mlx_sysdrive[i].ms_disk != 0) { 534 mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk); 535 if (mlxd->mlxd_flags & MLXD_OPEN) { /* drive is mounted, abort detach */ 536 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n"); 537 goto out; 538 } 539 } 540 } |
|
514 if ((error = mlx_shutdown(dev))) | 541 if ((error = mlx_shutdown(dev))) |
515 return(error); | 542 goto out; |
516 517 mlx_free(sc); 518 519 /* 520 * Deregister the control device on last detach. 521 */ 522 if (--cdev_registered == 0) 523 cdevsw_remove(&mlx_cdevsw); | 543 544 mlx_free(sc); 545 546 /* 547 * Deregister the control device on last detach. 548 */ 549 if (--cdev_registered == 0) 550 cdevsw_remove(&mlx_cdevsw); |
524 525 return(0); | 551 error = 0; 552 out: 553 splx(s); 554 return(error); |
526} 527 528/******************************************************************************** 529 * Bring the controller down to a dormant state and detach all child devices. 530 * 531 * This function is called before detach, system shutdown, or before performing 532 * an operation which may add or delete system disks. (Call mlx_startup to 533 * resume normal operation.) 534 * 535 * Note that we can assume that the bufq on the controller is empty, as we won't 536 * allow shutdown if any device is open. 537 */ 538int 539mlx_shutdown(device_t dev) 540{ 541 struct mlx_softc *sc = device_get_softc(dev); | 555} 556 557/******************************************************************************** 558 * Bring the controller down to a dormant state and detach all child devices. 559 * 560 * This function is called before detach, system shutdown, or before performing 561 * an operation which may add or delete system disks. (Call mlx_startup to 562 * resume normal operation.) 563 * 564 * Note that we can assume that the bufq on the controller is empty, as we won't 565 * allow shutdown if any device is open. 566 */ 567int 568mlx_shutdown(device_t dev) 569{ 570 struct mlx_softc *sc = device_get_softc(dev); |
542 struct mlxd_softc *mlxd; | |
543 int i, s, error; 544 545 debug("called"); 546 547 s = splbio(); 548 error = 0; 549 | 571 int i, s, error; 572 573 debug("called"); 574 575 s = splbio(); 576 error = 0; 577 |
550 /* assume we're going to shut down */ | |
551 sc->mlx_state |= MLX_STATE_SHUTDOWN; | 578 sc->mlx_state |= MLX_STATE_SHUTDOWN; |
552 for (i = 0; i < MLX_MAXDRIVES; i++) { 553 if (sc->mlx_sysdrive[i].ms_disk != 0) { 554 mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk); 555 if (mlxd->mlxd_flags & MLXD_OPEN) { /* drive is mounted, abort shutdown */ 556 sc->mlx_state &= ~MLX_STATE_SHUTDOWN; 557 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't shutdown\n"); 558 error = EBUSY; 559 goto out; 560 } 561 } 562 } | 579 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); |
563 564 /* flush controller */ 565 device_printf(sc->mlx_dev, "flushing cache..."); 566 if (mlx_flush(sc)) { 567 printf("failed\n"); 568 } else { 569 printf("done\n"); 570 } 571 572 /* delete all our child devices */ 573 for (i = 0; i < MLX_MAXDRIVES; i++) { 574 if (sc->mlx_sysdrive[i].ms_disk != 0) { 575 if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0) 576 goto out; 577 sc->mlx_sysdrive[i].ms_disk = 0; 578 } 579 } 580 | 580 581 /* flush controller */ 582 device_printf(sc->mlx_dev, "flushing cache..."); 583 if (mlx_flush(sc)) { 584 printf("failed\n"); 585 } else { 586 printf("done\n"); 587 } 588 589 /* delete all our child devices */ 590 for (i = 0; i < MLX_MAXDRIVES; i++) { 591 if (sc->mlx_sysdrive[i].ms_disk != 0) { 592 if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0) 593 goto out; 594 sc->mlx_sysdrive[i].ms_disk = 0; 595 } 596 } 597 |
581 bus_generic_detach(sc->mlx_dev); 582 | |
583 out: 584 splx(s); 585 return(error); 586} 587 588/******************************************************************************** 589 * Bring the controller to a quiescent state, ready for system suspend. 590 */ --- 37 unchanged lines hidden (view full) --- 628/******************************************************************************* 629 * Take an interrupt, or be poked by other code to look for interrupt-worthy 630 * status. 631 */ 632void 633mlx_intr(void *arg) 634{ 635 struct mlx_softc *sc = (struct mlx_softc *)arg; | 598 out: 599 splx(s); 600 return(error); 601} 602 603/******************************************************************************** 604 * Bring the controller to a quiescent state, ready for system suspend. 605 */ --- 37 unchanged lines hidden (view full) --- 643/******************************************************************************* 644 * Take an interrupt, or be poked by other code to look for interrupt-worthy 645 * status. 646 */ 647void 648mlx_intr(void *arg) 649{ 650 struct mlx_softc *sc = (struct mlx_softc *)arg; |
636 int worked; | |
637 638 debug("called"); 639 | 651 652 debug("called"); 653 |
640 /* spin collecting finished commands */ 641 worked = 0; 642 while (mlx_done(sc)) 643 worked = 1; 644 645 /* did we do anything? */ 646 if (worked) 647 mlx_complete(sc); | 654 /* collect finished commands, queue anything waiting */ 655 mlx_done(sc); |
648}; 649 650/******************************************************************************* 651 * Receive a buf structure from a child device and queue it on a particular 652 * disk resource, then poke the disk resource to start as much work as it can. 653 */ 654int 655mlx_submit_buf(struct mlx_softc *sc, struct buf *bp) --- 102 unchanged lines hidden (view full) --- 758 error = EBUSY; 759 goto detach_out; 760 } 761 762 /* nuke drive */ 763 if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0) 764 goto detach_out; 765 dr->ms_disk = 0; | 656}; 657 658/******************************************************************************* 659 * Receive a buf structure from a child device and queue it on a particular 660 * disk resource, then poke the disk resource to start as much work as it can. 661 */ 662int 663mlx_submit_buf(struct mlx_softc *sc, struct buf *bp) --- 102 unchanged lines hidden (view full) --- 766 error = EBUSY; 767 goto detach_out; 768 } 769 770 /* nuke drive */ 771 if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0) 772 goto detach_out; 773 dr->ms_disk = 0; |
766 bus_generic_detach(sc->mlx_dev); | |
767 768 detach_out: 769 if (error) { 770 printf("failed\n"); 771 } else { 772 printf("done\n"); 773 } 774 return(error); --- 130 unchanged lines hidden (view full) --- 905 906 907/******************************************************************************** 908 ******************************************************************************** 909 Status Monitoring 910 ******************************************************************************** 911 ********************************************************************************/ 912 | 774 775 detach_out: 776 if (error) { 777 printf("failed\n"); 778 } else { 779 printf("done\n"); 780 } 781 return(error); --- 130 unchanged lines hidden (view full) --- 912 913 914/******************************************************************************** 915 ******************************************************************************** 916 Status Monitoring 917 ******************************************************************************** 918 ********************************************************************************/ 919 |
913#define MLX_PERIODIC_ISBUSY(sc) (sc->mlx_polling <= 0) 914#define MLX_PERIODIC_BUSY(sc) atomic_add_int(&sc->mlx_polling, 1); 915#define MLX_PERIODIC_UNBUSY(sc) atomic_subtract_int(&sc->mlx_polling, 1); 916 | |
917/******************************************************************************** 918 * Fire off commands to periodically check the status of connected drives. 919 */ 920static void 921mlx_periodic(void *data) 922{ 923 struct mlx_softc *sc = (struct mlx_softc *)data; 924 --- 23 unchanged lines hidden (view full) --- 948 sysbeep(500, hz); 949 } else { 950 sysbeep((time_second % 5) * 100 + 500, hz/8); 951 } 952 953 /* 954 * Run normal periodic activities? 955 */ | 920/******************************************************************************** 921 * Fire off commands to periodically check the status of connected drives. 922 */ 923static void 924mlx_periodic(void *data) 925{ 926 struct mlx_softc *sc = (struct mlx_softc *)data; 927 --- 23 unchanged lines hidden (view full) --- 951 sysbeep(500, hz); 952 } else { 953 sysbeep((time_second % 5) * 100 + 500, hz/8); 954 } 955 956 /* 957 * Run normal periodic activities? 958 */ |
956 } else if (MLX_PERIODIC_ISBUSY(sc)) { | 959 } else if (time_second > (sc->mlx_lastpoll + 10)) { 960 sc->mlx_lastpoll = time_second; |
957 | 961 |
958 /* time to perform a periodic status poll? XXX tuneable interval? */ 959 if (time_second > (sc->mlx_lastpoll + 10)) { 960 sc->mlx_lastpoll = time_second; | 962 /* 963 * Check controller status. 964 * 965 * XXX Note that this may not actually launch a command in situations of high load. 966 */ 967 mlx_enquire(sc, MLX_CMD_ENQUIRY, sizeof(struct mlx_enquiry), mlx_periodic_enquiry); |
961 | 968 |
962 /* for caution's sake */ 963 if (sc->mlx_polling < 0) { 964 device_printf(sc->mlx_dev, "mlx_polling < 0\n"); 965 atomic_set_int(&sc->mlx_polling, 0); 966 } 967 968 /* 969 * Check controller status. 970 */ 971 MLX_PERIODIC_BUSY(sc); 972 mlx_enquire(sc, MLX_CMD_ENQUIRY, sizeof(struct mlx_enquiry), mlx_periodic_enquiry); 973 974 /* 975 * Check system drive status. 976 * 977 * XXX This might be better left to event-driven detection, eg. I/O to an offline 978 * drive will detect it's offline, rebuilds etc. should detect the drive is back 979 * online. 980 */ 981 MLX_PERIODIC_BUSY(sc); 982 mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES, | 969 /* 970 * Check system drive status. 971 * 972 * XXX This might be better left to event-driven detection, eg. I/O to an offline 973 * drive will detect it's offline, rebuilds etc. should detect the drive is back 974 * online. 975 */ 976 mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES, |
983 mlx_periodic_enquiry); | 977 mlx_periodic_enquiry); |
984 } 985 | 978 |
986 /* 987 * Get drive rebuild/check status 988 */ | 979 /* 980 * Get drive rebuild/check status 981 */ |
989 if (sc->mlx_rebuild >= 0) { 990 MLX_PERIODIC_BUSY(sc); | 982 if (sc->mlx_rebuild >= 0) |
991 mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild); | 983 mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild); |
992 } 993 } else { 994 /* 995 * If things are still running from the last poll, complain about it. 996 * 997 * XXX If this becomes an issue, we should have some way of telling what 998 * has become stuck. 999 */ 1000 device_printf(sc->mlx_dev, "poll still busy (%d)\n", sc->mlx_polling); | |
1001 } 1002 | 984 } 985 |
1003 /* XXX check for wedged/timed out commands? */ | 986 /* deal with possibly-missed interrupts and timed-out commands */ 987 mlx_done(sc); |
1004 1005 /* reschedule another poll next second or so */ 1006 sc->mlx_timeout = timeout(mlx_periodic, sc, hz); 1007} 1008 1009/******************************************************************************** 1010 * Handle the result of an ENQUIRY command instigated by periodic status polling. 1011 */ --- 60 unchanged lines hidden (view full) --- 1072 /* save new state */ 1073 dr->ms_state = mes[i].sd_state; 1074 } 1075 } 1076 } 1077 break; 1078 } 1079 default: | 988 989 /* reschedule another poll next second or so */ 990 sc->mlx_timeout = timeout(mlx_periodic, sc, hz); 991} 992 993/******************************************************************************** 994 * Handle the result of an ENQUIRY command instigated by periodic status polling. 995 */ --- 60 unchanged lines hidden (view full) --- 1056 /* save new state */ 1057 dr->ms_state = mes[i].sd_state; 1058 } 1059 } 1060 } 1061 break; 1062 } 1063 default: |
1064 device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __FUNCTION__, mc->mc_mailbox[0]); |
|
1080 break; 1081 } 1082 1083 out: 1084 free(mc->mc_data, M_DEVBUF); 1085 mlx_releasecmd(mc); | 1065 break; 1066 } 1067 1068 out: 1069 free(mc->mc_data, M_DEVBUF); 1070 mlx_releasecmd(mc); |
1086 /* this event is done */ 1087 MLX_PERIODIC_UNBUSY(sc); | |
1088} 1089 1090/******************************************************************************** 1091 * Instigate a poll for one event log message on (sc). 1092 * We only poll for one message at a time, to keep our command usage down. 1093 */ 1094static void 1095mlx_periodic_eventlog_poll(struct mlx_softc *sc) 1096{ 1097 struct mlx_command *mc; 1098 void *result = NULL; 1099 int error; 1100 1101 debug("called"); 1102 | 1071} 1072 1073/******************************************************************************** 1074 * Instigate a poll for one event log message on (sc). 1075 * We only poll for one message at a time, to keep our command usage down. 1076 */ 1077static void 1078mlx_periodic_eventlog_poll(struct mlx_softc *sc) 1079{ 1080 struct mlx_command *mc; 1081 void *result = NULL; 1082 int error; 1083 1084 debug("called"); 1085 |
1103 /* presume we are going to create another event */ 1104 MLX_PERIODIC_BUSY(sc); 1105 | |
1106 /* get ourselves a command buffer */ 1107 error = 1; 1108 if ((mc = mlx_alloccmd(sc)) == NULL) 1109 goto out; 1110 /* allocate the response structure */ 1111 if ((result = malloc(/*sizeof(struct mlx_eventlog_entry)*/1024, M_DEVBUF, M_NOWAIT)) == NULL) 1112 goto out; 1113 /* get a command slot */ --- 16 unchanged lines hidden (view full) --- 1130 1131 error = 0; /* success */ 1132 out: 1133 if (error != 0) { 1134 if (mc != NULL) 1135 mlx_releasecmd(mc); 1136 if (result != NULL) 1137 free(result, M_DEVBUF); | 1086 /* get ourselves a command buffer */ 1087 error = 1; 1088 if ((mc = mlx_alloccmd(sc)) == NULL) 1089 goto out; 1090 /* allocate the response structure */ 1091 if ((result = malloc(/*sizeof(struct mlx_eventlog_entry)*/1024, M_DEVBUF, M_NOWAIT)) == NULL) 1092 goto out; 1093 /* get a command slot */ --- 16 unchanged lines hidden (view full) --- 1110 1111 error = 0; /* success */ 1112 out: 1113 if (error != 0) { 1114 if (mc != NULL) 1115 mlx_releasecmd(mc); 1116 if (result != NULL) 1117 free(result, M_DEVBUF); |
1138 /* abort this event */ 1139 MLX_PERIODIC_UNBUSY(sc); | |
1140 } 1141} 1142 1143/******************************************************************************** 1144 * Handle the result of polling for a log message, generate diagnostic output. 1145 * If this wasn't the last message waiting for us, we'll go collect another. 1146 */ 1147static char *mlx_sense_messages[] = { --- 16 unchanged lines hidden (view full) --- 1164mlx_periodic_eventlog_respond(struct mlx_command *mc) 1165{ 1166 struct mlx_softc *sc = mc->mc_sc; 1167 struct mlx_eventlog_entry *el = (struct mlx_eventlog_entry *)mc->mc_data; 1168 char *reason; 1169 1170 debug("called"); 1171 | 1118 } 1119} 1120 1121/******************************************************************************** 1122 * Handle the result of polling for a log message, generate diagnostic output. 1123 * If this wasn't the last message waiting for us, we'll go collect another. 1124 */ 1125static char *mlx_sense_messages[] = { --- 16 unchanged lines hidden (view full) --- 1142mlx_periodic_eventlog_respond(struct mlx_command *mc) 1143{ 1144 struct mlx_softc *sc = mc->mc_sc; 1145 struct mlx_eventlog_entry *el = (struct mlx_eventlog_entry *)mc->mc_data; 1146 char *reason; 1147 1148 debug("called"); 1149 |
1150 sc->mlx_lastevent++; /* next message... */ |
|
1172 if (mc->mc_status == 0) { | 1151 if (mc->mc_status == 0) { |
1173 sc->mlx_lastevent++; /* got the message OK */ | |
1174 1175 /* handle event log message */ 1176 switch(el->el_type) { 1177 /* 1178 * This is the only sort of message we understand at the moment. 1179 * The tests here are probably incomplete. 1180 */ 1181 case MLX_LOGMSG_SENSE: /* sense data */ --- 35 unchanged lines hidden (view full) --- 1217 1218 /* dispose of command and data */ 1219 free(mc->mc_data, M_DEVBUF); 1220 mlx_releasecmd(mc); 1221 1222 /* is there another message to obtain? */ 1223 if (sc->mlx_lastevent != sc->mlx_currevent) 1224 mlx_periodic_eventlog_poll(sc); | 1152 1153 /* handle event log message */ 1154 switch(el->el_type) { 1155 /* 1156 * This is the only sort of message we understand at the moment. 1157 * The tests here are probably incomplete. 1158 */ 1159 case MLX_LOGMSG_SENSE: /* sense data */ --- 35 unchanged lines hidden (view full) --- 1195 1196 /* dispose of command and data */ 1197 free(mc->mc_data, M_DEVBUF); 1198 mlx_releasecmd(mc); 1199 1200 /* is there another message to obtain? */ 1201 if (sc->mlx_lastevent != sc->mlx_currevent) 1202 mlx_periodic_eventlog_poll(sc); |
1225 1226 /* this event is done */ 1227 MLX_PERIODIC_UNBUSY(sc); | |
1228} 1229 1230/******************************************************************************** 1231 * Handle the completion of a rebuild operation. 1232 */ 1233static void 1234mlx_periodic_rebuild(struct mlx_command *mc) 1235{ --- 14 unchanged lines hidden (view full) --- 1250 sc->mlx_check = -1; 1251 } else { 1252 device_printf(sc->mlx_dev, "consistency check completed\n"); 1253 } 1254 break; 1255 } 1256 free(mc->mc_data, M_DEVBUF); 1257 mlx_releasecmd(mc); | 1203} 1204 1205/******************************************************************************** 1206 * Handle the completion of a rebuild operation. 1207 */ 1208static void 1209mlx_periodic_rebuild(struct mlx_command *mc) 1210{ --- 14 unchanged lines hidden (view full) --- 1225 sc->mlx_check = -1; 1226 } else { 1227 device_printf(sc->mlx_dev, "consistency check completed\n"); 1228 } 1229 break; 1230 } 1231 free(mc->mc_data, M_DEVBUF); 1232 mlx_releasecmd(mc); |
1258 /* this event is done */ 1259 MLX_PERIODIC_UNBUSY(sc); | |
1260} 1261 1262/******************************************************************************** 1263 ******************************************************************************** 1264 Channel Pause 1265 ******************************************************************************** 1266 ********************************************************************************/ 1267 --- 170 unchanged lines hidden (view full) --- 1438 goto out; 1439 /* get a command slot */ 1440 if (mlx_getslot(mc)) 1441 goto out; 1442 1443 /* build a flush command */ 1444 mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0); 1445 | 1233} 1234 1235/******************************************************************************** 1236 ******************************************************************************** 1237 Channel Pause 1238 ******************************************************************************** 1239 ********************************************************************************/ 1240 --- 170 unchanged lines hidden (view full) --- 1411 goto out; 1412 /* get a command slot */ 1413 if (mlx_getslot(mc)) 1414 goto out; 1415 1416 /* build a flush command */ 1417 mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0); 1418 |
1446 /* run the command in either polled or wait mode */ 1447 if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc)) | 1419 /* can't assume that interrupts are going to work here, so play it safe */ 1420 if (mlx_poll_command(mc)) |
1448 goto out; 1449 1450 /* command completed OK? */ 1451 if (mc->mc_status != 0) { 1452 device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc)); 1453 goto out; 1454 } 1455 --- 127 unchanged lines hidden (view full) --- 1583 struct mlx_command *mc; 1584 struct mlxd_softc *mlxd; 1585 struct buf *bp; 1586 int blkcount; 1587 int driveno; 1588 int cmd; 1589 int s; 1590 | 1421 goto out; 1422 1423 /* command completed OK? */ 1424 if (mc->mc_status != 0) { 1425 device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc)); 1426 goto out; 1427 } 1428 --- 127 unchanged lines hidden (view full) --- 1556 struct mlx_command *mc; 1557 struct mlxd_softc *mlxd; 1558 struct buf *bp; 1559 int blkcount; 1560 int driveno; 1561 int cmd; 1562 int s; 1563 |
1564 /* avoid reentrancy */ 1565 if (mlx_lock_tas(sc, MLX_LOCK_STARTING)) 1566 return; 1567 |
|
1591 /* spin until something prevents us from doing any work */ 1592 s = splbio(); 1593 for (;;) { 1594 1595 /* see if there's work to be done */ 1596 if ((bp = bufq_first(&sc->mlx_bufq)) == NULL) 1597 break; 1598 /* get a command */ --- 22 unchanged lines hidden (view full) --- 1621 cmd = MLX_CMD_WRITEOLDSG; 1622 } 1623 1624 /* map the command so the controller can work with it */ 1625 mlx_mapcmd(mc); 1626 1627 /* build a suitable I/O command (assumes 512-byte rounded transfers) */ 1628 mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1; | 1568 /* spin until something prevents us from doing any work */ 1569 s = splbio(); 1570 for (;;) { 1571 1572 /* see if there's work to be done */ 1573 if ((bp = bufq_first(&sc->mlx_bufq)) == NULL) 1574 break; 1575 /* get a command */ --- 22 unchanged lines hidden (view full) --- 1598 cmd = MLX_CMD_WRITEOLDSG; 1599 } 1600 1601 /* map the command so the controller can work with it */ 1602 mlx_mapcmd(mc); 1603 1604 /* build a suitable I/O command (assumes 512-byte rounded transfers) */ 1605 mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1; |
1629 driveno = mlxd->mlxd_drive - &sc->mlx_sysdrive[0]; | 1606 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive; |
1630 blkcount = (bp->b_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE; 1631 1632 if ((bp->b_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size) 1633 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n", 1634 bp->b_pblkno, blkcount, sc->mlx_sysdrive[driveno].ms_size); 1635 1636 /* 1637 * Build the I/O command. Note that the SG list type bits are set to zero, --- 11 unchanged lines hidden (view full) --- 1649 if (mlx_start(mc) != 0) { 1650 /* fail the command */ 1651 mc->mc_status = MLX_STATUS_WEDGED; 1652 mlx_completeio(mc); 1653 } 1654 s = splbio(); 1655 } 1656 splx(s); | 1607 blkcount = (bp->b_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE; 1608 1609 if ((bp->b_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size) 1610 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n", 1611 bp->b_pblkno, blkcount, sc->mlx_sysdrive[driveno].ms_size); 1612 1613 /* 1614 * Build the I/O command. Note that the SG list type bits are set to zero, --- 11 unchanged lines hidden (view full) --- 1626 if (mlx_start(mc) != 0) { 1627 /* fail the command */ 1628 mc->mc_status = MLX_STATUS_WEDGED; 1629 mlx_completeio(mc); 1630 } 1631 s = splbio(); 1632 } 1633 splx(s); |
1634 mlx_lock_clr(sc, MLX_LOCK_STARTING); |
|
1657} 1658 1659/******************************************************************************** 1660 * Handle completion of an I/O command. 1661 */ 1662static void 1663mlx_completeio(struct mlx_command *mc) 1664{ --- 205 unchanged lines hidden (view full) --- 1870 if (mc->mc_flags & MLX_CMD_DATAOUT) 1871 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE); 1872 1873 bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap); 1874 } 1875} 1876 1877/******************************************************************************** | 1635} 1636 1637/******************************************************************************** 1638 * Handle completion of an I/O command. 1639 */ 1640static void 1641mlx_completeio(struct mlx_command *mc) 1642{ --- 205 unchanged lines hidden (view full) --- 1848 if (mc->mc_flags & MLX_CMD_DATAOUT) 1849 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE); 1850 1851 bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap); 1852 } 1853} 1854 1855/******************************************************************************** |
1878 * Try to deliver (mc) to the controller. Take care of any completed commands 1879 * that we encounter while doing so. | 1856 * Try to deliver (mc) to the controller. |
1880 * 1881 * Can be called at any interrupt level, with or without interrupts enabled. 1882 */ 1883static int 1884mlx_start(struct mlx_command *mc) 1885{ 1886 struct mlx_softc *sc = mc->mc_sc; | 1857 * 1858 * Can be called at any interrupt level, with or without interrupts enabled. 1859 */ 1860static int 1861mlx_start(struct mlx_command *mc) 1862{ 1863 struct mlx_softc *sc = mc->mc_sc; |
1887 int i, s, done, worked; | 1864 int i, s, done; |
1888 1889 debug("called"); 1890 1891 /* save the slot number as ident so we can handle this command when complete */ 1892 mc->mc_mailbox[0x1] = mc->mc_slot; 1893 1894 /* mark the command as currently being processed */ 1895 mc->mc_status = MLX_STATUS_BUSY; | 1865 1866 debug("called"); 1867 1868 /* save the slot number as ident so we can handle this command when complete */ 1869 mc->mc_mailbox[0x1] = mc->mc_slot; 1870 1871 /* mark the command as currently being processed */ 1872 mc->mc_status = MLX_STATUS_BUSY; |
1896 1897 /* assume we don't collect any completed commands */ 1898 worked = 0; | |
1899 | 1873 |
1874 /* set a default 60-second timeout XXX tunable? XXX not currently used */ 1875 mc->mc_timeout = time_second + 60; 1876 |
|
1900 /* spin waiting for the mailbox */ 1901 for (i = 100000, done = 0; (i > 0) && !done; i--) { 1902 s = splbio(); 1903 if (sc->mlx_tryqueue(sc, mc)) { 1904 done = 1; 1905 /* move command to work queue */ 1906 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link); 1907 } | 1877 /* spin waiting for the mailbox */ 1878 for (i = 100000, done = 0; (i > 0) && !done; i--) { 1879 s = splbio(); 1880 if (sc->mlx_tryqueue(sc, mc)) { 1881 done = 1; 1882 /* move command to work queue */ 1883 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link); 1884 } |
1908 splx(s); 1909 /* check for command completion while we're at it */ 1910 if (mlx_done(sc)) 1911 worked = 1; | 1885 splx(s); /* drop spl to allow completion interrupts */ |
1912 } | 1886 } |
1913 /* check to see if we picked up any completed commands */ 1914 if (worked) 1915 mlx_complete(sc); | |
1916 1917 /* command is enqueued */ 1918 if (done) 1919 return(0); 1920 1921 /* 1922 * We couldn't get the controller to take the command. Revoke the slot 1923 * that the command was given and return it with a bad status. 1924 */ 1925 sc->mlx_busycmd[mc->mc_slot] = NULL; 1926 device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n"); 1927 mc->mc_status = MLX_STATUS_WEDGED; | 1887 1888 /* command is enqueued */ 1889 if (done) 1890 return(0); 1891 1892 /* 1893 * We couldn't get the controller to take the command. Revoke the slot 1894 * that the command was given and return it with a bad status. 1895 */ 1896 sc->mlx_busycmd[mc->mc_slot] = NULL; 1897 device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n"); 1898 mc->mc_status = MLX_STATUS_WEDGED; |
1899 mlx_complete(sc); |
|
1928 return(EIO); 1929} 1930 1931/******************************************************************************** | 1900 return(EIO); 1901} 1902 1903/******************************************************************************** |
1932 * Look at the controller (sc) and see if a command has been completed. 1933 * If so, move the command buffer to the done queue for later collection 1934 * and free the slot for immediate reuse. | 1904 * Poll the controller (sc) for completed commands. 1905 * Update command status and free slots for reuse. If any slots were freed, 1906 * new commands may be posted. |
1935 * | 1907 * |
1936 * Returns nonzero if anything was added to the done queue. | 1908 * Returns nonzero if one or more commands were completed. |
1937 */ 1938static int 1939mlx_done(struct mlx_softc *sc) 1940{ 1941 struct mlx_command *mc; | 1909 */ 1910static int 1911mlx_done(struct mlx_softc *sc) 1912{ 1913 struct mlx_command *mc; |
1942 int s; | 1914 int s, result; |
1943 u_int8_t slot; 1944 u_int16_t status; 1945 1946 debug("called"); 1947 | 1915 u_int8_t slot; 1916 u_int16_t status; 1917 1918 debug("called"); 1919 |
1948 mc = NULL; 1949 slot = 0; | 1920 result = 0; |
1950 | 1921 |
1951 /* poll for a completed command's identifier and status */ | 1922 /* loop collecting completed commands */ |
1952 s = splbio(); | 1923 s = splbio(); |
1953 if (sc->mlx_findcomplete(sc, &slot, &status)) { 1954 mc = sc->mlx_busycmd[slot]; /* find command */ 1955 if (mc != NULL) { /* paranoia */ 1956 if (mc->mc_status == MLX_STATUS_BUSY) { 1957 mc->mc_status = status; /* save status */ | 1924 for (;;) { 1925 /* poll for a completed command's identifier and status */ 1926 if (sc->mlx_findcomplete(sc, &slot, &status)) { 1927 result = 1; 1928 mc = sc->mlx_busycmd[slot]; /* find command */ 1929 if (mc != NULL) { /* paranoia */ 1930 if (mc->mc_status == MLX_STATUS_BUSY) { 1931 mc->mc_status = status; /* save status */ |
1958 | 1932 |
1959 /* free slot for reuse */ 1960 sc->mlx_busycmd[slot] = NULL; 1961 sc->mlx_busycmds--; | 1933 /* free slot for reuse */ 1934 sc->mlx_busycmd[slot] = NULL; 1935 sc->mlx_busycmds--; 1936 } else { 1937 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot); 1938 } |
1962 } else { | 1939 } else { |
1963 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot); 1964 mc = NULL; | 1940 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot); |
1965 } 1966 } else { | 1941 } 1942 } else { |
1967 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot); | 1943 break; |
1968 } 1969 } | 1944 } 1945 } |
1970 splx(s); | |
1971 | 1946 |
1972 if (mc != NULL) { 1973 /* unmap the command's data buffer */ 1974 mlx_unmapcmd(mc); 1975 return(1); 1976 } 1977 return(0); | 1947 /* if we've completed any commands, try posting some more */ 1948 if (result) 1949 mlx_startio(sc); 1950 1951 /* handle completion and timeouts */ 1952 mlx_complete(sc); 1953 1954 return(result); |
1978} 1979 1980/******************************************************************************** | 1955} 1956 1957/******************************************************************************** |
1981 * Handle completion for all commands on (sc)'s done queue. | 1958 * Perform post-completion processing for commands on (sc). |
1982 */ 1983static void 1984mlx_complete(struct mlx_softc *sc) 1985{ 1986 struct mlx_command *mc, *nc; 1987 int s, count; 1988 1989 debug("called"); 1990 | 1959 */ 1960static void 1961mlx_complete(struct mlx_softc *sc) 1962{ 1963 struct mlx_command *mc, *nc; 1964 int s, count; 1965 1966 debug("called"); 1967 |
1968 /* avoid reentrancy XXX might want to signal and request a restart */ 1969 if (mlx_lock_tas(sc, MLX_LOCK_COMPLETING)) 1970 return; 1971 |
|
1991 s = splbio(); 1992 count = 0; | 1972 s = splbio(); 1973 count = 0; |
1993 1994 /* scan the list of done commands */ | 1974 1975 /* scan the list of busy/done commands */ |
1995 mc = TAILQ_FIRST(&sc->mlx_work); 1996 while (mc != NULL) { 1997 nc = TAILQ_NEXT(mc, mc_link); 1998 1999 /* XXX this is slightly bogus */ 2000 if (count++ > (sc->mlx_maxiop * 2)) 2001 panic("mlx_work list corrupt!"); 2002 | 1976 mc = TAILQ_FIRST(&sc->mlx_work); 1977 while (mc != NULL) { 1978 nc = TAILQ_NEXT(mc, mc_link); 1979 1980 /* XXX this is slightly bogus */ 1981 if (count++ > (sc->mlx_maxiop * 2)) 1982 panic("mlx_work list corrupt!"); 1983 |
2003 /* Skip commands that are still busy */ | 1984 /* Command has been completed in some fashion */ |
2004 if (mc->mc_status != MLX_STATUS_BUSY) { | 1985 if (mc->mc_status != MLX_STATUS_BUSY) { |
2005 2006 | 1986 1987 /* unmap the command's data buffer */ 1988 mlx_unmapcmd(mc); |
2007 /* | 1989 /* |
2008 * Does the command have a completion handler? 2009 */ | 1990 * Does the command have a completion handler? 1991 */ |
2010 if (mc->mc_complete != NULL) { 2011 /* remove from list and give to handler */ 2012 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 2013 mc->mc_complete(mc); 2014 2015 /* 2016 * Is there a sleeper waiting on this command? 2017 */ --- 8 unchanged lines hidden (view full) --- 2026 */ 2027 } else { 2028 } 2029 } 2030 mc = nc; 2031 } 2032 splx(s); 2033 | 1992 if (mc->mc_complete != NULL) { 1993 /* remove from list and give to handler */ 1994 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 1995 mc->mc_complete(mc); 1996 1997 /* 1998 * Is there a sleeper waiting on this command? 1999 */ --- 8 unchanged lines hidden (view full) --- 2008 */ 2009 } else { 2010 } 2011 } 2012 mc = nc; 2013 } 2014 splx(s); 2015 |
2034 /* queue some more work if there is any */ 2035 mlx_startio(sc); | 2016 mlx_lock_clr(sc, MLX_LOCK_COMPLETING); |
2036} 2037 2038/******************************************************************************** 2039 ******************************************************************************** 2040 Command Buffer Management 2041 ******************************************************************************** 2042 ********************************************************************************/ 2043 --- 231 unchanged lines hidden (view full) --- 2275 sc->mlx_state |= MLX_STATE_INTEN; 2276 break; 2277 } 2278} 2279 2280 2281/******************************************************************************** 2282 ******************************************************************************** | 2017} 2018 2019/******************************************************************************** 2020 ******************************************************************************** 2021 Command Buffer Management 2022 ******************************************************************************** 2023 ********************************************************************************/ 2024 --- 231 unchanged lines hidden (view full) --- 2256 sc->mlx_state |= MLX_STATE_INTEN; 2257 break; 2258 } 2259} 2260 2261 2262/******************************************************************************** 2263 ******************************************************************************** |
2264 Type 5 interface accessor methods 2265 ******************************************************************************** 2266 ********************************************************************************/ 2267 2268/******************************************************************************** 2269 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2270 * (the controller is not ready to take a command). 2271 * 2272 * Must be called at splbio or in a fashion that prevents reentry. 2273 */ 2274static int 2275mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2276{ 2277 int i; 2278 2279 debug("called"); 2280 2281 /* ready for our command? */ 2282 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) { 2283 /* copy mailbox data to window */ 2284 for (i = 0; i < 13; i++) 2285 MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2286 2287 /* post command */ 2288 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD); 2289 return(1); 2290 } 2291 return(0); 2292} 2293 2294/******************************************************************************** 2295 * See if a command has been completed, if so acknowledge its completion 2296 * and recover the slot number and status code. 2297 * 2298 * Must be called at splbio or in a fashion that prevents reentry. 2299 */ 2300static int 2301mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2302{ 2303 2304 debug("called"); 2305 2306 /* status available? */ 2307 if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) { 2308 *slot = MLX_V5_GET_STATUS_IDENT(sc); /* get command identifier */ 2309 *status = MLX_V5_GET_STATUS(sc); /* get status */ 2310 2311 /* acknowledge completion */ 2312 MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK); 2313 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK); 2314 return(1); 2315 } 2316 return(0); 2317} 2318 2319/******************************************************************************** 2320 * Enable/disable interrupts as requested. 2321 * 2322 * Must be called at splbio or in a fashion that prevents reentry. 2323 */ 2324static void 2325mlx_v5_intaction(struct mlx_softc *sc, int action) 2326{ 2327 debug("called"); 2328 2329 switch(action) { 2330 case MLX_INTACTION_DISABLE: 2331 MLX_V5_PUT_IER(sc, MLX_V5_IER_DISINT); 2332 sc->mlx_state &= ~MLX_STATE_INTEN; 2333 break; 2334 case MLX_INTACTION_ENABLE: 2335 MLX_V5_PUT_IER(sc, 0); 2336 sc->mlx_state |= MLX_STATE_INTEN; 2337 break; 2338 } 2339} 2340 2341 2342/******************************************************************************** 2343 ******************************************************************************** |
|
2283 Debugging 2284 ******************************************************************************** 2285 ********************************************************************************/ 2286 2287/******************************************************************************** 2288 * Return a status message describing (mc) 2289 */ 2290static char *mlx_status_messages[] = { --- 55 unchanged lines hidden (view full) --- 2346 2347 sprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]); 2348 return(unkmsg); 2349} 2350 2351/******************************************************************************* 2352 * Return a string describing the controller (hwid) 2353 */ | 2344 Debugging 2345 ******************************************************************************** 2346 ********************************************************************************/ 2347 2348/******************************************************************************** 2349 * Return a status message describing (mc) 2350 */ 2351static char *mlx_status_messages[] = { --- 55 unchanged lines hidden (view full) --- 2407 2408 sprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]); 2409 return(unkmsg); 2410} 2411 2412/******************************************************************************* 2413 * Return a string describing the controller (hwid) 2414 */ |
2415static struct 2416{ 2417 int hwid; 2418 char *name; 2419} mlx_controller_names[] = { 2420 {0x01, "960P/PD"}, 2421 {0x02, "960PL"}, 2422 {0x10, "960PG"}, 2423 {0x11, "960PJ"}, 2424 {0x16, "960PTL"}, 2425 {0x20, "1164P"}, 2426 {-1, NULL} 2427}; 2428 |
|
2354static char * 2355mlx_name_controller(u_int32_t hwid) 2356{ 2357 static char buf[80]; | 2429static char * 2430mlx_name_controller(u_int32_t hwid) 2431{ 2432 static char buf[80]; |
2358 char smbuf[16]; 2359 char *submodel; 2360 int nchn; 2361 2362 switch(hwid & 0xff) { 2363 case 0x01: 2364 submodel = "P/PD"; 2365 break; 2366 case 0x02: 2367 submodel = "PL"; 2368 break; 2369 case 0x10: 2370 submodel = "PG"; 2371 break; 2372 case 0x11: 2373 submodel = "PJ"; 2374 break; 2375 case 0x16: 2376 submodel = "PTL"; 2377 break; 2378 default: 2379 sprintf(smbuf, " model 0x%x", hwid & 0xff); 2380 submodel = smbuf; 2381 break; | 2433 char *model; 2434 int nchn, i; 2435 2436 for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) { 2437 if ((hwid & 0xff) == mlx_controller_names[i].hwid) { 2438 model = mlx_controller_names[i].name; 2439 break; 2440 } |
2382 } | 2441 } |
2442 if (model == NULL) { 2443 sprintf(buf, " model 0x%x", hwid & 0xff); 2444 model = buf; 2445 } |
|
2383 nchn = (hwid >> 8) & 0xff; | 2446 nchn = (hwid >> 8) & 0xff; |
2384 sprintf(buf, "DAC960%s, %d channel%s", submodel, nchn, nchn > 1 ? "s" : ""); | 2447 sprintf(buf, "DAC%s, %d channel%s", model, nchn, nchn > 1 ? "s" : ""); |
2385 return(buf); 2386} 2387 2388/******************************************************************************** 2389 ******************************************************************************** 2390 Utility Functions 2391 ******************************************************************************** 2392 ********************************************************************************/ --- 20 unchanged lines hidden --- | 2448 return(buf); 2449} 2450 2451/******************************************************************************** 2452 ******************************************************************************** 2453 Utility Functions 2454 ******************************************************************************** 2455 ********************************************************************************/ --- 20 unchanged lines hidden --- |