diff options
Diffstat (limited to 'sys/dev/nvme/nvme_ctrlr.c')
| -rw-r--r-- | sys/dev/nvme/nvme_ctrlr.c | 33 | 
1 files changed, 31 insertions, 2 deletions
| diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 3a1894bf754d..e607667decf5 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -33,6 +33,7 @@  #include <sys/buf.h>  #include <sys/bus.h>  #include <sys/conf.h> +#include <sys/disk.h>  #include <sys/ioccom.h>  #include <sys/proc.h>  #include <sys/smp.h> @@ -1254,6 +1255,24 @@ nvme_ctrlr_poll(struct nvme_controller *ctrlr)  }  /* + * Copy the NVME device's serial number to the provided buffer, which must be + * at least DISK_IDENT_SIZE bytes large. + */ +void +nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn) +{ +	_Static_assert(NVME_SERIAL_NUMBER_LENGTH < DISK_IDENT_SIZE, +		"NVME serial number too big for disk ident"); + +	memmove(sn, ctrlr->cdata.sn, NVME_SERIAL_NUMBER_LENGTH); +	sn[NVME_SERIAL_NUMBER_LENGTH] = '\0'; +	for (int i = 0; sn[i] != '\0'; i++) { +		if (sn[i] < 0x20 || sn[i] >= 0x80) +			sn[i] = ' '; +	} +} + +/*   * Poll the single-vector interrupt case: num_io_queues will be 1 and   * there's only a single vector. While we're polling, we mask further   * interrupts in the controller. @@ -1495,6 +1514,11 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,  	case NVME_GET_CONTROLLER_DATA:  		memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata));  		break; +	case DIOCGIDENT: { +		uint8_t *sn = arg; +		nvme_ctrlr_get_ident(ctrlr, sn); +		break; +	}  	/* Linux Compatible (see nvme_linux.h) */  	case NVME_IOCTL_ID:  		td->td_retval[0] = 0xfffffffful; @@ -1738,9 +1762,14 @@ noadminq:  		bus_release_resource(ctrlr->dev, SYS_RES_IRQ,  		    rman_get_rid(ctrlr->res), ctrlr->res); -	if (ctrlr->bar4_resource != NULL) { +	if (ctrlr->msix_table_resource != NULL) { +		bus_release_resource(dev, SYS_RES_MEMORY, +		    ctrlr->msix_table_resource_id, ctrlr->msix_table_resource); +	} + +	if (ctrlr->msix_pba_resource != NULL) {  		bus_release_resource(dev, SYS_RES_MEMORY, -		    ctrlr->bar4_resource_id, ctrlr->bar4_resource); +		    ctrlr->msix_pba_resource_id, ctrlr->msix_pba_resource);  	}  	bus_release_resource(dev, SYS_RES_MEMORY, | 
