mlx.c (54515) | mlx.c (54979) |
---|---|
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 54515 1999-12-12 20:59:29Z peter $ | 26 * $FreeBSD: head/sys/dev/mlx/mlx.c 54979 1999-12-22 01:21:28Z 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> --- 102 unchanged lines hidden (view full) --- 137static int mlx_start(struct mlx_command *mc); 138static int mlx_done(struct mlx_softc *sc); 139static void mlx_complete(struct mlx_softc *sc); 140 141/* 142 * Debugging. 143 */ 144static char *mlx_diagnose_command(struct mlx_command *mc); | 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> --- 102 unchanged lines hidden (view full) --- 137static int mlx_start(struct mlx_command *mc); 138static int mlx_done(struct mlx_softc *sc); 139static void mlx_complete(struct mlx_softc *sc); 140 141/* 142 * Debugging. 143 */ 144static char *mlx_diagnose_command(struct mlx_command *mc); |
145static char *mlx_name_controller(u_int32_t hwid); | 145static void mlx_describe_controller(struct mlx_softc *sc); |
146 147 148/* 149 * Utility functions. 150 */ 151static struct mlx_sysdrive *mlx_findunit(struct mlx_softc *sc, int unit); 152 153/******************************************************************************** --- 42 unchanged lines hidden (view full) --- 196 /* destroy the parent DMA tag */ 197 if (sc->mlx_parent_dmat) 198 bus_dma_tag_destroy(sc->mlx_parent_dmat); 199 200 /* release the register window mapping */ 201 if (sc->mlx_mem != NULL) 202 bus_release_resource(sc->mlx_dev, SYS_RES_MEMORY, 203 (sc->mlx_iftype == MLX_IFTYPE_3) ? MLX_CFG_BASE1 : MLX_CFG_BASE0, sc->mlx_mem); | 146 147 148/* 149 * Utility functions. 150 */ 151static struct mlx_sysdrive *mlx_findunit(struct mlx_softc *sc, int unit); 152 153/******************************************************************************** --- 42 unchanged lines hidden (view full) --- 196 /* destroy the parent DMA tag */ 197 if (sc->mlx_parent_dmat) 198 bus_dma_tag_destroy(sc->mlx_parent_dmat); 199 200 /* release the register window mapping */ 201 if (sc->mlx_mem != NULL) 202 bus_release_resource(sc->mlx_dev, SYS_RES_MEMORY, 203 (sc->mlx_iftype == MLX_IFTYPE_3) ? MLX_CFG_BASE1 : MLX_CFG_BASE0, sc->mlx_mem); |
204 205 /* free controller enquiry data */ 206 if (sc->mlx_enq2 != NULL) 207 free(sc->mlx_enq2, M_DEVBUF); |
|
204} 205 206/******************************************************************************** 207 * Map the scatter/gather table into bus space 208 */ 209static void 210mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 211{ --- 56 unchanged lines hidden (view full) --- 268} 269 270/******************************************************************************** 271 * Initialise the controller and softc 272 */ 273int 274mlx_attach(struct mlx_softc *sc) 275{ | 208} 209 210/******************************************************************************** 211 * Map the scatter/gather table into bus space 212 */ 213static void 214mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 215{ --- 56 unchanged lines hidden (view full) --- 272} 273 274/******************************************************************************** 275 * Initialise the controller and softc 276 */ 277int 278mlx_attach(struct mlx_softc *sc) 279{ |
276 struct mlx_enquiry *me; 277 struct mlx_enquiry2 *me2; 278 int rid, error; | 280 int rid, error, fwminor; |
279 280 debug("called"); 281 282 /* 283 * Initialise per-controller queues. 284 */ 285 TAILQ_INIT(&sc->mlx_work); 286 TAILQ_INIT(&sc->mlx_freecmds); --- 58 unchanged lines hidden (view full) --- 345 if (error != 0) { 346 device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n"); 347 return(ENOMEM); 348 } 349 350 /* 351 * Create an initial set of s/g mappings. 352 */ | 281 282 debug("called"); 283 284 /* 285 * Initialise per-controller queues. 286 */ 287 TAILQ_INIT(&sc->mlx_work); 288 TAILQ_INIT(&sc->mlx_freecmds); --- 58 unchanged lines hidden (view full) --- 347 if (error != 0) { 348 device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n"); 349 return(ENOMEM); 350 } 351 352 /* 353 * Create an initial set of s/g mappings. 354 */ |
353 sc->mlx_maxiop = 2; | 355 sc->mlx_maxiop = 8; |
354 error = mlx_sglist_map(sc); 355 if (error != 0) { 356 device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n"); 357 return(error); 358 } 359 | 356 error = mlx_sglist_map(sc); 357 if (error != 0) { 358 device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n"); 359 return(error); 360 } 361 |
360 /* 361 * Probe the controller for more information. 362 */ 363 /* send an ENQUIRY to the controller */ 364 if ((me = mlx_enquire(sc, MLX_CMD_ENQUIRY, sizeof(*me), NULL)) == NULL) { 365 device_printf(sc->mlx_dev, "ENQUIRY failed\n"); 366 return(ENXIO); 367 } 368 369 /* pull information out of the ENQUIRY result */ 370 sc->mlx_fwminor = me->me_fwminor; 371 sc->mlx_fwmajor = me->me_fwmajor; 372 sc->mlx_maxiop = me->me_max_commands; 373 sc->mlx_lastevent = sc->mlx_currevent = me->me_event_log_seq_num; 374 free(me, M_DEVBUF); 375 | |
376 /* send an ENQUIRY2 to the controller */ | 362 /* send an ENQUIRY2 to the controller */ |
377 if ((me2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(*me2), NULL)) == NULL) { | 363 if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) { |
378 device_printf(sc->mlx_dev, "ENQUIRY2 failed\n"); 379 return(ENXIO); 380 } 381 | 364 device_printf(sc->mlx_dev, "ENQUIRY2 failed\n"); 365 return(ENXIO); 366 } 367 |
382 /* pull information out of the ENQUIRY2 result */ 383 sc->mlx_nchan = me2->me_configured_channels; 384 sc->mlx_maxiosize = me2->me_maxblk; 385 sc->mlx_maxtarg = me2->me_max_targets; 386 sc->mlx_maxtags = me2->me_max_tags; 387 sc->mlx_scsicap = me2->me_scsi_cap; 388 sc->mlx_hwid = me2->me_hardware_id; | 368 /* 369 * We don't (yet) know where the event log is up to. 370 */ 371 sc->mlx_lastevent = -1; |
389 | 372 |
390 /* print a little information about the controller and ourselves */ 391 device_printf(sc->mlx_dev, "Mylex %s, firmware %d.%02d, %dMB RAM\n", 392 mlx_name_controller(sc->mlx_hwid), sc->mlx_fwmajor, sc->mlx_fwminor, 393 me2->me_mem_size / (1024 * 1024)); 394 free(me2, M_DEVBUF); | 373 /* print a little information about the controller */ 374 mlx_describe_controller(sc); |
395 396 /* 397 * Do quirk/feature related things. 398 */ | 375 376 /* 377 * Do quirk/feature related things. 378 */ |
379 fwminor = (sc->mlx_enq2->me_firmware_id >> 8) & 0xff; |
|
399 switch(sc->mlx_iftype) { 400 case MLX_IFTYPE_3: 401 /* XXX certify 3.52? */ | 380 switch(sc->mlx_iftype) { 381 case MLX_IFTYPE_3: 382 /* XXX certify 3.52? */ |
402 if (sc->mlx_fwminor < 51) { | 383 if (fwminor < 51) { |
403 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 404 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n"); 405 } 406 break; 407 case MLX_IFTYPE_4: 408 /* XXX certify firmware versions? */ | 384 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 385 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n"); 386 } 387 break; 388 case MLX_IFTYPE_4: 389 /* XXX certify firmware versions? */ |
409 if (sc->mlx_fwminor < 6) { | 390 if (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: | 391 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 392 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n"); 393 } 394 break; 395 case MLX_IFTYPE_5: |
415 if (sc->mlx_fwminor < 7) { | 396 if (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; 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. 428 */ | 397 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 398 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n"); 399 } 400 break; 401 default: 402 device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype); 403 return(ENXIO); /* should never happen */ 404 } 405 406 /* 407 * Create the final set of s/g mappings now that we know how many commands 408 * the controller actually supports. 409 */ |
410 sc->mlx_maxiop = sc->mlx_enq2->me_max_commands; |
|
429 error = mlx_sglist_map(sc); 430 if (error != 0) { 431 device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n"); 432 return(error); 433 } 434 435 /* 436 * No rebuild or check is in progress. --- 28 unchanged lines hidden (view full) --- 465 debug("called"); 466 467 /* 468 * Scan all the system drives and attach children for those that 469 * don't currently have them. 470 */ 471 mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL); 472 if (mes == NULL) { | 411 error = mlx_sglist_map(sc); 412 if (error != 0) { 413 device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n"); 414 return(error); 415 } 416 417 /* 418 * No rebuild or check is in progress. --- 28 unchanged lines hidden (view full) --- 447 debug("called"); 448 449 /* 450 * Scan all the system drives and attach children for those that 451 * don't currently have them. 452 */ 453 mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL); 454 if (mes == NULL) { |
473 device_printf(sc->mlx_dev, "error fetching drive status"); | 455 device_printf(sc->mlx_dev, "error fetching drive status\n"); |
474 return; 475 } 476 477 /* iterate over drives returned */ 478 for (i = 0, dr = &sc->mlx_sysdrive[0]; 479 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 480 i++, dr++) { 481 /* are we already attached to this drive? */ --- 311 unchanged lines hidden (view full) --- 793 return(EOPNOTSUPP); 794 795 mp = (struct mlx_pause *)addr; 796 if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) { 797 /* cancel a pending pause operation */ 798 sc->mlx_pause.mp_which = 0; 799 } else { 800 /* fix for legal channels */ | 456 return; 457 } 458 459 /* iterate over drives returned */ 460 for (i = 0, dr = &sc->mlx_sysdrive[0]; 461 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 462 i++, dr++) { 463 /* are we already attached to this drive? */ --- 311 unchanged lines hidden (view full) --- 775 return(EOPNOTSUPP); 776 777 mp = (struct mlx_pause *)addr; 778 if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) { 779 /* cancel a pending pause operation */ 780 sc->mlx_pause.mp_which = 0; 781 } else { 782 /* fix for legal channels */ |
801 mp->mp_which &= ((1 << sc->mlx_nchan) -1); | 783 mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1); |
802 /* check time values */ 803 if ((mp->mp_when < 0) || (mp->mp_when > 3600)) 804 return(EINVAL); 805 if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30))) 806 return(EINVAL); 807 808 /* check for a pause currently running */ 809 if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) --- 201 unchanged lines hidden (view full) --- 1011 /* 1012 * Generic controller status update. We could do more with this than just 1013 * checking the event log. 1014 */ 1015 case MLX_CMD_ENQUIRY: 1016 { 1017 struct mlx_enquiry *me = (struct mlx_enquiry *)mc->mc_data; 1018 | 784 /* check time values */ 785 if ((mp->mp_when < 0) || (mp->mp_when > 3600)) 786 return(EINVAL); 787 if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30))) 788 return(EINVAL); 789 790 /* check for a pause currently running */ 791 if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) --- 201 unchanged lines hidden (view full) --- 993 /* 994 * Generic controller status update. We could do more with this than just 995 * checking the event log. 996 */ 997 case MLX_CMD_ENQUIRY: 998 { 999 struct mlx_enquiry *me = (struct mlx_enquiry *)mc->mc_data; 1000 |
1019 /* New stuff in the event log? */ 1020 if (me->me_event_log_seq_num != sc->mlx_lastevent) { | 1001 if (sc->mlx_lastevent == -1) { 1002 /* initialise our view of the event log */ 1003 sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num; 1004 } else if (me->me_event_log_seq_num != sc->mlx_lastevent) { |
1021 /* record where current events are up to */ 1022 sc->mlx_currevent = me->me_event_log_seq_num; 1023 device_printf(sc->mlx_dev, "event log pointer was %d, now %d\n", 1024 sc->mlx_lastevent, sc->mlx_currevent); 1025 | 1005 /* record where current events are up to */ 1006 sc->mlx_currevent = me->me_event_log_seq_num; 1007 device_printf(sc->mlx_dev, "event log pointer was %d, now %d\n", 1008 sc->mlx_lastevent, sc->mlx_currevent); 1009 |
1026 /* start poll of event log */ | 1010 /* drain new eventlog entries */ |
1027 mlx_periodic_eventlog_poll(sc); 1028 } 1029 break; 1030 } 1031 case MLX_CMD_ENQSYSDRIVE: 1032 { 1033 struct mlx_enq_sys_drive *mes = (struct mlx_enq_sys_drive *)mc->mc_data; 1034 struct mlx_sysdrive *dr; --- 229 unchanged lines hidden (view full) --- 1264 failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30; 1265 if (failsafe > 0xf) { 1266 failsafe = 0xf; 1267 sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5; 1268 } 1269 } 1270 1271 /* build commands for every channel requested */ | 1011 mlx_periodic_eventlog_poll(sc); 1012 } 1013 break; 1014 } 1015 case MLX_CMD_ENQSYSDRIVE: 1016 { 1017 struct mlx_enq_sys_drive *mes = (struct mlx_enq_sys_drive *)mc->mc_data; 1018 struct mlx_sysdrive *dr; --- 229 unchanged lines hidden (view full) --- 1248 failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30; 1249 if (failsafe > 0xf) { 1250 failsafe = 0xf; 1251 sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5; 1252 } 1253 } 1254 1255 /* build commands for every channel requested */ |
1272 for (i = 0; i < sc->mlx_nchan; i++) { | 1256 for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) { |
1273 if ((1 << i) & sc->mlx_pause.mp_which) { 1274 1275 /* get ourselves a command buffer */ 1276 if ((mc = mlx_alloccmd(sc)) == NULL) 1277 goto fail; 1278 /* get a command slot */ 1279 mc->mc_flags |= MLX_CMD_PRIORITY; 1280 if (mlx_getslot(mc)) --- 464 unchanged lines hidden (view full) --- 1745 * 1746 * Don't hand out a slot to a normal-priority command unless there are at least 1747 * 4 slots free for priority commands. 1748 */ 1749static int 1750mlx_getslot(struct mlx_command *mc) 1751{ 1752 struct mlx_softc *sc = mc->mc_sc; | 1257 if ((1 << i) & sc->mlx_pause.mp_which) { 1258 1259 /* get ourselves a command buffer */ 1260 if ((mc = mlx_alloccmd(sc)) == NULL) 1261 goto fail; 1262 /* get a command slot */ 1263 mc->mc_flags |= MLX_CMD_PRIORITY; 1264 if (mlx_getslot(mc)) --- 464 unchanged lines hidden (view full) --- 1729 * 1730 * Don't hand out a slot to a normal-priority command unless there are at least 1731 * 4 slots free for priority commands. 1732 */ 1733static int 1734mlx_getslot(struct mlx_command *mc) 1735{ 1736 struct mlx_softc *sc = mc->mc_sc; |
1753 int s, slot, limit; | 1737 int s, slot; |
1754 1755 debug("called mc %p sc %p", mc, sc); 1756 1757 /* enforce slot-usage limit */ | 1738 1739 debug("called mc %p sc %p", mc, sc); 1740 1741 /* enforce slot-usage limit */ |
1758 limit = (mc->mc_flags & MLX_CMD_PRIORITY) ? sc->mlx_maxiop : sc->mlx_maxiop - 4; 1759 if (sc->mlx_busycmds > limit) | 1742 if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? 1743 sc->mlx_maxiop : sc->mlx_maxiop - 4)) |
1760 return(EBUSY); 1761 1762 /* 1763 * Allocate an outstanding command slot 1764 * 1765 * XXX linear search is slow 1766 */ 1767 s = splbio(); --- 204 unchanged lines hidden (view full) --- 1972 s = splbio(); 1973 count = 0; 1974 1975 /* scan the list of busy/done commands */ 1976 mc = TAILQ_FIRST(&sc->mlx_work); 1977 while (mc != NULL) { 1978 nc = TAILQ_NEXT(mc, mc_link); 1979 | 1744 return(EBUSY); 1745 1746 /* 1747 * Allocate an outstanding command slot 1748 * 1749 * XXX linear search is slow 1750 */ 1751 s = splbio(); --- 204 unchanged lines hidden (view full) --- 1956 s = splbio(); 1957 count = 0; 1958 1959 /* scan the list of busy/done commands */ 1960 mc = TAILQ_FIRST(&sc->mlx_work); 1961 while (mc != NULL) { 1962 nc = TAILQ_NEXT(mc, mc_link); 1963 |
1980 /* XXX this is slightly bogus */ 1981 if (count++ > (sc->mlx_maxiop * 2)) 1982 panic("mlx_work list corrupt!"); 1983 | |
1984 /* Command has been completed in some fashion */ 1985 if (mc->mc_status != MLX_STATUS_BUSY) { 1986 1987 /* unmap the command's data buffer */ 1988 mlx_unmapcmd(mc); 1989 /* 1990 * Does the command have a completion handler? 1991 */ --- 424 unchanged lines hidden (view full) --- 2416{ 2417 int hwid; 2418 char *name; 2419} mlx_controller_names[] = { 2420 {0x01, "960P/PD"}, 2421 {0x02, "960PL"}, 2422 {0x10, "960PG"}, 2423 {0x11, "960PJ"}, | 1964 /* Command has been completed in some fashion */ 1965 if (mc->mc_status != MLX_STATUS_BUSY) { 1966 1967 /* unmap the command's data buffer */ 1968 mlx_unmapcmd(mc); 1969 /* 1970 * Does the command have a completion handler? 1971 */ --- 424 unchanged lines hidden (view full) --- 2396{ 2397 int hwid; 2398 char *name; 2399} mlx_controller_names[] = { 2400 {0x01, "960P/PD"}, 2401 {0x02, "960PL"}, 2402 {0x10, "960PG"}, 2403 {0x11, "960PJ"}, |
2424 {0x16, "960PTL"}, 2425 {0x20, "1164P"}, | 2404 {0x12, "960PR"}, 2405 {0x13, "960PT"}, 2406 {0x14, "960PTL0"}, 2407 {0x15, "960PRL"}, 2408 {0x16, "960PTL1"}, 2409 {0x20, "1164PVX"}, |
2426 {-1, NULL} 2427}; 2428 | 2410 {-1, NULL} 2411}; 2412 |
2429static char * 2430mlx_name_controller(u_int32_t hwid) | 2413static void 2414mlx_describe_controller(struct mlx_softc *sc) |
2431{ 2432 static char buf[80]; 2433 char *model; | 2415{ 2416 static char buf[80]; 2417 char *model; |
2434 int nchn, i; | 2418 int i; |
2435 2436 for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) { | 2419 2420 for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) { |
2437 if ((hwid & 0xff) == mlx_controller_names[i].hwid) { | 2421 if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) { |
2438 model = mlx_controller_names[i].name; 2439 break; 2440 } 2441 } 2442 if (model == NULL) { | 2422 model = mlx_controller_names[i].name; 2423 break; 2424 } 2425 } 2426 if (model == NULL) { |
2443 sprintf(buf, " model 0x%x", hwid & 0xff); | 2427 sprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff); |
2444 model = buf; 2445 } | 2428 model = buf; 2429 } |
2446 nchn = (hwid >> 8) & 0xff; 2447 sprintf(buf, "DAC%s, %d channel%s", model, nchn, nchn > 1 ? "s" : ""); 2448 return(buf); | 2430 device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%d, %dMB RAM\n", 2431 model, 2432 sc->mlx_enq2->me_actual_channels, 2433 sc->mlx_enq2->me_actual_channels > 1 ? "s" : "", 2434 sc->mlx_enq2->me_firmware_id & 0xff, 2435 (sc->mlx_enq2->me_firmware_id >> 8) & 0xff, 2436 (sc->mlx_enq2->me_firmware_id >> 16), 2437 (sc->mlx_enq2->me_firmware_id >> 24) & 0xff, 2438 sc->mlx_enq2->me_mem_size / (1024 * 1024)); 2439 2440 if (bootverbose) { 2441 device_printf(sc->mlx_dev, " Hardware ID 0x%08x\n", sc->mlx_enq2->me_hardware_id); 2442 device_printf(sc->mlx_dev, " Firmware ID 0x%08x\n", sc->mlx_enq2->me_firmware_id); 2443 device_printf(sc->mlx_dev, " Configured/Actual channels %d/%d\n", sc->mlx_enq2->me_configured_channels, 2444 sc->mlx_enq2->me_actual_channels); 2445 device_printf(sc->mlx_dev, " Max Targets %d\n", sc->mlx_enq2->me_max_targets); 2446 device_printf(sc->mlx_dev, " Max Tags %d\n", sc->mlx_enq2->me_max_tags); 2447 device_printf(sc->mlx_dev, " Max System Drives %d\n", sc->mlx_enq2->me_max_sys_drives); 2448 device_printf(sc->mlx_dev, " Max Arms %d\n", sc->mlx_enq2->me_max_arms); 2449 device_printf(sc->mlx_dev, " Max Spans %d\n", sc->mlx_enq2->me_max_spans); 2450 device_printf(sc->mlx_dev, " DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size, 2451 sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size); 2452 device_printf(sc->mlx_dev, " DRAM type %d\n", sc->mlx_enq2->me_mem_type); 2453 device_printf(sc->mlx_dev, " Clock Speed %dns\n", sc->mlx_enq2->me_clock_speed); 2454 device_printf(sc->mlx_dev, " Hardware Speed %dns\n", sc->mlx_enq2->me_hardware_speed); 2455 device_printf(sc->mlx_dev, " Max Commands %d\n", sc->mlx_enq2->me_max_commands); 2456 device_printf(sc->mlx_dev, " Max SG Entries %d\n", sc->mlx_enq2->me_max_sg); 2457 device_printf(sc->mlx_dev, " Max DP %d\n", sc->mlx_enq2->me_max_dp); 2458 device_printf(sc->mlx_dev, " Max IOD %d\n", sc->mlx_enq2->me_max_iod); 2459 device_printf(sc->mlx_dev, " Max Comb %d\n", sc->mlx_enq2->me_max_comb); 2460 device_printf(sc->mlx_dev, " Latency %ds\n", sc->mlx_enq2->me_latency); 2461 device_printf(sc->mlx_dev, " SCSI Timeout %ds\n", sc->mlx_enq2->me_scsi_timeout); 2462 device_printf(sc->mlx_dev, " Min Free Lines %d\n", sc->mlx_enq2->me_min_freelines); 2463 device_printf(sc->mlx_dev, " Rate Constant %d\n", sc->mlx_enq2->me_rate_const); 2464 device_printf(sc->mlx_dev, " MAXBLK %d\n", sc->mlx_enq2->me_maxblk); 2465 device_printf(sc->mlx_dev, " Blocking Factor %d sectors\n", sc->mlx_enq2->me_blocking_factor); 2466 device_printf(sc->mlx_dev, " Cache Line Size %d blocks\n", sc->mlx_enq2->me_cacheline); 2467 device_printf(sc->mlx_dev, " SCSI Capability %s%dMHz, %d bit\n", 2468 sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "", 2469 (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10, 2470 8 << (sc->mlx_enq2->me_scsi_cap & 0x3)); 2471 device_printf(sc->mlx_dev, " Firmware Build Number %d\n", sc->mlx_enq2->me_firmware_build); 2472 device_printf(sc->mlx_dev, " Fault Management Type %d\n", sc->mlx_enq2->me_fault_mgmt_type); 2473 device_printf(sc->mlx_dev, " Features %b\n", sc->mlx_enq2->me_firmware_features, 2474 "\20\4Background Init\3Read Ahead\2MORE\1Cluster\n"); 2475 2476 } |
2449} 2450 2451/******************************************************************************** 2452 ******************************************************************************** 2453 Utility Functions 2454 ******************************************************************************** 2455 ********************************************************************************/ 2456 --- 19 unchanged lines hidden --- | 2477} 2478 2479/******************************************************************************** 2480 ******************************************************************************** 2481 Utility Functions 2482 ******************************************************************************** 2483 ********************************************************************************/ 2484 --- 19 unchanged lines hidden --- |