| @@ -1,36 +1,36 @@ | | | @@ -1,36 +1,36 @@ |
1 | /* $NetBSD: mpii.c,v 1.8 2016/05/02 19:18:29 christos Exp $ */ | | 1 | /* $NetBSD: mpii.c,v 1.8.10.1 2018/06/09 14:32:52 martin Exp $ */ |
2 | /* OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp */ | | 2 | /* OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp */ |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2010 Mike Belopuhov <mkb@crypt.org.ru> | | 4 | * Copyright (c) 2010 Mike Belopuhov <mkb@crypt.org.ru> |
5 | * Copyright (c) 2009 James Giannoules | | 5 | * Copyright (c) 2009 James Giannoules |
6 | * Copyright (c) 2005 - 2010 David Gwynne <dlg@openbsd.org> | | 6 | * Copyright (c) 2005 - 2010 David Gwynne <dlg@openbsd.org> |
7 | * Copyright (c) 2005 - 2010 Marco Peereboom <marco@openbsd.org> | | 7 | * Copyright (c) 2005 - 2010 Marco Peereboom <marco@openbsd.org> |
8 | * | | 8 | * |
9 | * Permission to use, copy, modify, and distribute this software for any | | 9 | * Permission to use, copy, modify, and distribute this software for any |
10 | * purpose with or without fee is hereby granted, provided that the above | | 10 | * purpose with or without fee is hereby granted, provided that the above |
11 | * copyright notice and this permission notice appear in all copies. | | 11 | * copyright notice and this permission notice appear in all copies. |
12 | * | | 12 | * |
13 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | 13 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
19 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 19 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
20 | */ | | 20 | */ |
21 | | | 21 | |
22 | #include <sys/cdefs.h> | | 22 | #include <sys/cdefs.h> |
23 | __KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.8 2016/05/02 19:18:29 christos Exp $"); | | 23 | __KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.8.10.1 2018/06/09 14:32:52 martin Exp $"); |
24 | | | 24 | |
25 | #include "bio.h" | | 25 | #include "bio.h" |
26 | | | 26 | |
27 | #include <sys/param.h> | | 27 | #include <sys/param.h> |
28 | #include <sys/systm.h> | | 28 | #include <sys/systm.h> |
29 | #include <sys/buf.h> | | 29 | #include <sys/buf.h> |
30 | #include <sys/device.h> | | 30 | #include <sys/device.h> |
31 | #include <sys/ioctl.h> | | 31 | #include <sys/ioctl.h> |
32 | #include <sys/malloc.h> | | 32 | #include <sys/malloc.h> |
33 | #include <sys/kernel.h> | | 33 | #include <sys/kernel.h> |
34 | #include <sys/mutex.h> | | 34 | #include <sys/mutex.h> |
35 | #include <sys/condvar.h> | | 35 | #include <sys/condvar.h> |
36 | #include <sys/dkio.h> | | 36 | #include <sys/dkio.h> |
| @@ -3424,46 +3424,54 @@ mpii_event_raid(struct mpii_softc *sc, s | | | @@ -3424,46 +3424,54 @@ mpii_event_raid(struct mpii_softc *sc, s |
3424 | ce = (struct mpii_evt_ir_cfg_element *)(ccl + 1); | | 3424 | ce = (struct mpii_evt_ir_cfg_element *)(ccl + 1); |
3425 | | | 3425 | |
3426 | for (i = 0; i < ccl->num_elements; i++, ce++) { | | 3426 | for (i = 0; i < ccl->num_elements; i++, ce++) { |
3427 | type = (le16toh(ce->element_flags) & | | 3427 | type = (le16toh(ce->element_flags) & |
3428 | MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK); | | 3428 | MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK); |
3429 | | | 3429 | |
3430 | switch (type) { | | 3430 | switch (type) { |
3431 | case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME: | | 3431 | case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME: |
3432 | switch (ce->reason_code) { | | 3432 | switch (ce->reason_code) { |
3433 | case MPII_EVT_IR_CFG_ELEMENT_RC_ADDED: | | 3433 | case MPII_EVT_IR_CFG_ELEMENT_RC_ADDED: |
3434 | case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED: | | 3434 | case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED: |
3435 | if (mpii_find_dev(sc, | | 3435 | if (mpii_find_dev(sc, |
3436 | le16toh(ce->vol_dev_handle))) { | | 3436 | le16toh(ce->vol_dev_handle))) { |
3437 | printf("%s: device %#x is already " | | 3437 | aprint_error_dev(sc->sc_dev, |
3438 | "configured\n", DEVNAME(sc), | | 3438 | "device %#x is already " |
| | | 3439 | "configured\n", |
3439 | le16toh(ce->vol_dev_handle)); | | 3440 | le16toh(ce->vol_dev_handle)); |
3440 | break; | | 3441 | break; |
3441 | } | | 3442 | } |
3442 | dev = malloc(sizeof(*dev), M_DEVBUF, | | 3443 | dev = malloc(sizeof(*dev), M_DEVBUF, |
3443 | M_NOWAIT | M_ZERO); | | 3444 | M_NOWAIT | M_ZERO); |
3444 | if (!dev) { | | 3445 | if (!dev) { |
3445 | printf("%s: failed to allocate a " | | 3446 | aprint_error_dev(sc->sc_dev, |
3446 | "device structure\n", DEVNAME(sc)); | | 3447 | "can't allocate device structure\n"); |
3447 | break; | | 3448 | break; |
3448 | } | | 3449 | } |
3449 | SET(dev->flags, MPII_DF_VOLUME); | | 3450 | SET(dev->flags, MPII_DF_VOLUME); |
3450 | dev->slot = sc->sc_vd_id_low; | | 3451 | dev->slot = sc->sc_vd_id_low; |
3451 | dev->dev_handle = le16toh(ce->vol_dev_handle); | | 3452 | dev->dev_handle = le16toh(ce->vol_dev_handle); |
3452 | if (mpii_insert_dev(sc, dev)) { | | 3453 | if (mpii_insert_dev(sc, dev)) { |
| | | 3454 | aprint_error_dev(sc->sc_dev, |
| | | 3455 | "can't insert device structure\n"); |
| | | 3456 | free(dev, M_DEVBUF); |
| | | 3457 | break; |
| | | 3458 | } |
| | | 3459 | if (mpii_cache_enable(sc, dev)) { |
| | | 3460 | aprint_error_dev(sc->sc_dev, |
| | | 3461 | "can't enable device cache\n"); |
3453 | free(dev, M_DEVBUF); | | 3462 | free(dev, M_DEVBUF); |
3454 | break; | | 3463 | break; |
3455 | } | | 3464 | } |
3456 | mpii_cache_enable(sc, dev); | | | |
3457 | sc->sc_vd_count++; | | 3465 | sc->sc_vd_count++; |
3458 | break; | | 3466 | break; |
3459 | case MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED: | | 3467 | case MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED: |
3460 | case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED: | | 3468 | case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED: |
3461 | if (!(dev = mpii_find_dev(sc, | | 3469 | if (!(dev = mpii_find_dev(sc, |
3462 | le16toh(ce->vol_dev_handle)))) | | 3470 | le16toh(ce->vol_dev_handle)))) |
3463 | break; | | 3471 | break; |
3464 | mpii_remove_dev(sc, dev); | | 3472 | mpii_remove_dev(sc, dev); |
3465 | sc->sc_vd_count--; | | 3473 | sc->sc_vd_count--; |
3466 | break; | | 3474 | break; |
3467 | } | | 3475 | } |
3468 | break; | | 3476 | break; |
3469 | case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK: | | 3477 | case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK: |
| @@ -3505,64 +3513,66 @@ mpii_event_sas(struct mpii_softc *sc, st | | | @@ -3505,64 +3513,66 @@ mpii_event_sas(struct mpii_softc *sc, st |
3505 | int i; | | 3513 | int i; |
3506 | | | 3514 | |
3507 | tcl = (struct mpii_evt_sas_tcl *)(enp + 1); | | 3515 | tcl = (struct mpii_evt_sas_tcl *)(enp + 1); |
3508 | | | 3516 | |
3509 | if (tcl->num_entries == 0) | | 3517 | if (tcl->num_entries == 0) |
3510 | return; | | 3518 | return; |
3511 | | | 3519 | |
3512 | pe = (struct mpii_evt_phy_entry *)(tcl + 1); | | 3520 | pe = (struct mpii_evt_phy_entry *)(tcl + 1); |
3513 | | | 3521 | |
3514 | for (i = 0; i < tcl->num_entries; i++, pe++) { | | 3522 | for (i = 0; i < tcl->num_entries; i++, pe++) { |
3515 | switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) { | | 3523 | switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) { |
3516 | case MPII_EVENT_SAS_TOPO_PS_RC_ADDED: | | 3524 | case MPII_EVENT_SAS_TOPO_PS_RC_ADDED: |
3517 | if (mpii_find_dev(sc, le16toh(pe->dev_handle))) { | | 3525 | if (mpii_find_dev(sc, le16toh(pe->dev_handle))) { |
3518 | printf("%s: device %#x is already " | | 3526 | aprint_error_dev(sc->sc_dev, |
3519 | "configured\n", DEVNAME(sc), | | 3527 | "device %#x is already configured\n", |
3520 | le16toh(pe->dev_handle)); | | 3528 | le16toh(pe->dev_handle)); |
3521 | break; | | 3529 | break; |
3522 | } | | 3530 | } |
3523 | dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT | M_ZERO); | | 3531 | dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT | M_ZERO); |
3524 | if (!dev) { | | 3532 | if (!dev) { |
3525 | printf("%s: failed to allocate a " | | 3533 | aprint_error_dev(sc->sc_dev, "can't allocate " |
3526 | "device structure\n", DEVNAME(sc)); | | 3534 | "device structure\n"); |
3527 | break; | | 3535 | break; |
3528 | } | | 3536 | } |
3529 | dev->slot = sc->sc_pd_id_start + tcl->start_phy_num + i; | | 3537 | dev->slot = sc->sc_pd_id_start + tcl->start_phy_num + i; |
3530 | dev->dev_handle = le16toh(pe->dev_handle); | | 3538 | dev->dev_handle = le16toh(pe->dev_handle); |
3531 | dev->phy_num = tcl->start_phy_num + i; | | 3539 | dev->phy_num = tcl->start_phy_num + i; |
3532 | if (tcl->enclosure_handle) | | 3540 | if (tcl->enclosure_handle) |
3533 | dev->physical_port = tcl->physical_port; | | 3541 | dev->physical_port = tcl->physical_port; |
3534 | dev->enclosure = le16toh(tcl->enclosure_handle); | | 3542 | dev->enclosure = le16toh(tcl->enclosure_handle); |
3535 | dev->expander = le16toh(tcl->expander_handle); | | 3543 | dev->expander = le16toh(tcl->expander_handle); |
3536 | if (mpii_insert_dev(sc, dev)) { | | 3544 | if (mpii_insert_dev(sc, dev)) { |
| | | 3545 | aprint_error_dev(sc->sc_dev, "can't insert " |
| | | 3546 | "device structure\n"); |
3537 | free(dev, M_DEVBUF); | | 3547 | free(dev, M_DEVBUF); |
3538 | break; | | 3548 | break; |
3539 | } | | 3549 | } |
3540 | break; | | 3550 | break; |
3541 | case MPII_EVENT_SAS_TOPO_PS_RC_MISSING: | | 3551 | case MPII_EVENT_SAS_TOPO_PS_RC_MISSING: |
3542 | if (!(dev = mpii_find_dev(sc, | | 3552 | if (!(dev = mpii_find_dev(sc, |
3543 | le16toh(pe->dev_handle)))) | | 3553 | le16toh(pe->dev_handle)))) |
3544 | break; | | 3554 | break; |
3545 | mpii_remove_dev(sc, dev); | | 3555 | mpii_remove_dev(sc, dev); |
3546 | #if 0 | | 3556 | #if 0 |
3547 | if (sc->sc_scsibus) { | | 3557 | if (sc->sc_scsibus) { |
3548 | SET(dev->flags, MPII_DF_DETACH); | | 3558 | SET(dev->flags, MPII_DF_DETACH); |
3549 | scsi_activate(sc->sc_scsibus, dev->slot, -1, | | 3559 | scsi_activate(sc->sc_scsibus, dev->slot, -1, |
3550 | DVACT_DEACTIVATE); | | 3560 | DVACT_DEACTIVATE); |
3551 | if (scsi_task(mpii_event_defer, sc, | | 3561 | if (scsi_task(mpii_event_defer, sc, |
3552 | dev, 0) != 0) | | 3562 | dev, 0) != 0) |
3553 | printf("%s: unable to run device " | | 3563 | aprint_error_dev(sc->sc_dev, |
3554 | "detachment routine\n", | | 3564 | "unable to run device " |
3555 | DEVNAME(sc)); | | 3565 | "detachment routine\n"); |
3556 | } | | 3566 | } |
3557 | #else | | 3567 | #else |
3558 | mpii_event_defer(sc, dev); | | 3568 | mpii_event_defer(sc, dev); |
3559 | #endif /* XXX */ | | 3569 | #endif /* XXX */ |
3560 | break; | | 3570 | break; |
3561 | } | | 3571 | } |
3562 | } | | 3572 | } |
3563 | } | | 3573 | } |
3564 | | | 3574 | |
3565 | static void | | 3575 | static void |
3566 | mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb) | | 3576 | mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb) |
3567 | { | | 3577 | { |
3568 | struct mpii_msg_event_reply *enp; | | 3578 | struct mpii_msg_event_reply *enp; |
| @@ -4969,27 +4979,27 @@ mpii_cache_enable(struct mpii_softc *sc, | | | @@ -4969,27 +4979,27 @@ mpii_cache_enable(struct mpii_softc *sc, |
4969 | struct mpii_msg_raid_action_reply *rep; | | 4979 | struct mpii_msg_raid_action_reply *rep; |
4970 | struct mpii_cfg_hdr hdr; | | 4980 | struct mpii_cfg_hdr hdr; |
4971 | struct mpii_ccb *ccb; | | 4981 | struct mpii_ccb *ccb; |
4972 | u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle; | | 4982 | u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle; |
4973 | size_t pagelen; | | 4983 | size_t pagelen; |
4974 | int rv = 0; | | 4984 | int rv = 0; |
4975 | int enabled; | | 4985 | int enabled; |
4976 | | | 4986 | |
4977 | if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0, | | 4987 | if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0, |
4978 | addr, MPII_PG_POLL, &hdr) != 0) | | 4988 | addr, MPII_PG_POLL, &hdr) != 0) |
4979 | return (EINVAL); | | 4989 | return (EINVAL); |
4980 | | | 4990 | |
4981 | pagelen = hdr.page_length * 4; | | 4991 | pagelen = hdr.page_length * 4; |
4982 | vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO); | | 4992 | vpg = malloc(pagelen, M_TEMP, M_NOWAIT | M_ZERO); |
4983 | if (vpg == NULL) | | 4993 | if (vpg == NULL) |
4984 | return (ENOMEM); | | 4994 | return (ENOMEM); |
4985 | | | 4995 | |
4986 | if (mpii_req_cfg_page(sc, addr, MPII_PG_POLL, &hdr, 1, | | 4996 | if (mpii_req_cfg_page(sc, addr, MPII_PG_POLL, &hdr, 1, |
4987 | vpg, pagelen) != 0) { | | 4997 | vpg, pagelen) != 0) { |
4988 | rv = EINVAL; | | 4998 | rv = EINVAL; |
4989 | goto done; | | 4999 | goto done; |
4990 | free(vpg, M_TEMP); | | 5000 | free(vpg, M_TEMP); |
4991 | return (EINVAL); | | 5001 | return (EINVAL); |
4992 | } | | 5002 | } |
4993 | | | 5003 | |
4994 | enabled = ((le16toh(vpg->volume_settings) & | | 5004 | enabled = ((le16toh(vpg->volume_settings) & |
4995 | MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK) == | | 5005 | MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK) == |