ahci(4): Allow enclosure emulation without hardware.
After 53f5ac1310
allowed SATA device mapping to enclosure slots,
it may have sense to provide enclosure device emulation even without
real hardware interface like SGPIO just for purposes of physical
device location tracking (still assuming straight cabling).
MFC after: 1 week
Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
75add59a8e
commit
9aba757e92
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 21, 2019
|
||||
.Dd December 17, 2021
|
||||
.Dt AHCI 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -73,6 +73,10 @@ controls whether the driver should use direct command completion from
|
||||
interrupt thread(s), or queue them to CAM completion threads.
|
||||
Default value depends on number of MSI interrupts supported and number of
|
||||
implemented SATA ports.
|
||||
.It Va hint.ahci. Ns Ar X Ns Va .em
|
||||
controls whether the driver should implement virtual enclosure management
|
||||
device on top of SGPIO or other interface.
|
||||
Default value depends on controller capabilities.
|
||||
.It Va hint.ahcich. Ns Ar X Ns Va .pm_level
|
||||
controls SATA interface Power Management for the specified channel,
|
||||
allowing some power to be saved at the cost of additional command
|
||||
|
@ -376,7 +376,10 @@ ahci_attach(device_t dev)
|
||||
device_set_ivars(child, (void *)(intptr_t)(unit | AHCI_REMAPPED_UNIT));
|
||||
}
|
||||
|
||||
if (ctlr->caps & AHCI_CAP_EMS) {
|
||||
int em = (ctlr->caps & AHCI_CAP_EMS) != 0;
|
||||
resource_int_value(device_get_name(dev), device_get_unit(dev),
|
||||
"em", &em);
|
||||
if (em) {
|
||||
child = device_add_child(dev, "ahciem", -1);
|
||||
if (child == NULL)
|
||||
device_printf(dev, "failed to add enclosure device\n");
|
||||
@ -602,6 +605,8 @@ ahci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
} else if (!is_em) {
|
||||
offset = AHCI_OFFSET + (unit << 7);
|
||||
size = 128;
|
||||
} else if ((ctlr->caps & AHCI_CAP_EMS) == 0) {
|
||||
break;
|
||||
} else if (*rid == 0) {
|
||||
offset = AHCI_EM_CTL;
|
||||
size = 4;
|
||||
|
@ -86,17 +86,18 @@ ahci_em_attach(device_t dev)
|
||||
enc->ichannels = ctlr->ichannels;
|
||||
mtx_init(&enc->mtx, "AHCI enclosure lock", NULL, MTX_DEF);
|
||||
rid = 0;
|
||||
if (!(enc->r_memc = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&rid, RF_ACTIVE))) {
|
||||
mtx_destroy(&enc->mtx);
|
||||
return (ENXIO);
|
||||
}
|
||||
enc->capsem = ATA_INL(enc->r_memc, 0);
|
||||
rid = 1;
|
||||
if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&rid, RF_ACTIVE))) {
|
||||
error = ENXIO;
|
||||
goto err0;
|
||||
if ((enc->r_memc = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&rid, RF_ACTIVE)) != NULL) {
|
||||
enc->capsem = ATA_INL(enc->r_memc, 0);
|
||||
rid = 1;
|
||||
if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&rid, RF_ACTIVE))) {
|
||||
error = ENXIO;
|
||||
goto err0;
|
||||
}
|
||||
} else {
|
||||
enc->capsem = AHCI_EM_XMT | AHCI_EM_SMB | AHCI_EM_LED;
|
||||
enc->r_memt = NULL;
|
||||
}
|
||||
if ((enc->capsem & (AHCI_EM_XMT | AHCI_EM_SMB)) == 0) {
|
||||
rid = 2;
|
||||
@ -194,7 +195,8 @@ ahci_em_attach(device_t dev)
|
||||
err0:
|
||||
if (enc->r_memt)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc);
|
||||
if (enc->r_memc)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc);
|
||||
mtx_destroy(&enc->mtx);
|
||||
return (error);
|
||||
}
|
||||
@ -216,8 +218,10 @@ ahci_em_detach(device_t dev)
|
||||
cam_sim_free(enc->sim, /*free_devq*/TRUE);
|
||||
mtx_unlock(&enc->mtx);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt);
|
||||
if (enc->r_memc)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc);
|
||||
if (enc->r_memt)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt);
|
||||
if (enc->r_memr)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr);
|
||||
mtx_destroy(&enc->mtx);
|
||||
@ -231,6 +235,8 @@ ahci_em_reset(device_t dev)
|
||||
int i, timeout;
|
||||
|
||||
enc = device_get_softc(dev);
|
||||
if (enc->r_memc == NULL)
|
||||
return (0);
|
||||
ATA_OUTL(enc->r_memc, 0, AHCI_EM_RST);
|
||||
timeout = 1000;
|
||||
while ((ATA_INL(enc->r_memc, 0) & AHCI_EM_RST) &&
|
||||
@ -292,6 +298,8 @@ ahci_em_setleds(device_t dev, int c)
|
||||
int16_t val;
|
||||
|
||||
enc = device_get_softc(dev);
|
||||
if (enc->r_memc == NULL)
|
||||
return;
|
||||
|
||||
val = 0;
|
||||
if (enc->status[c][2] & SESCTL_RQSACT) /* Activity */
|
||||
|
Loading…
Reference in New Issue
Block a user