Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/nvme/nvme_da.c
Show First 20 Lines • Show All 635 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
disk_destroy(softc->disk); | disk_destroy(softc->disk); | ||||
free(softc, M_DEVBUF); | free(softc, M_DEVBUF); | ||||
cam_periph_lock(periph); | cam_periph_lock(periph); | ||||
} | } | ||||
static void | static void | ||||
ndasetgeom(struct nda_softc *softc, struct cam_periph *periph) | |||||
{ | |||||
struct disk *disk = softc->disk; | |||||
struct ccb_pathinq cpi; | |||||
const struct nvme_namespace_data *nsd; | |||||
const struct nvme_controller_data *cd; | |||||
uint8_t flbas_fmt, lbads, vwc_present; | |||||
nsd = nvme_get_identify_ns(periph); | |||||
cd = nvme_get_identify_cntrl(periph); | |||||
flbas_fmt = (nsd->flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) & | |||||
NVME_NS_DATA_FLBAS_FORMAT_MASK; | |||||
lbads = (nsd->lbaf[flbas_fmt] >> NVME_NS_DATA_LBAF_LBADS_SHIFT) & | |||||
NVME_NS_DATA_LBAF_LBADS_MASK; | |||||
disk->d_sectorsize = 1 << lbads; | |||||
disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze); | |||||
disk->d_delmaxsize = disk->d_mediasize; | |||||
disk->d_flags = DISKFLAG_DIRECT_COMPLETION; | |||||
if (nvme_ctrlr_has_dataset_mgmt(cd)) | |||||
disk->d_flags |= DISKFLAG_CANDELETE; | |||||
vwc_present = (cd->vwc >> NVME_CTRLR_DATA_VWC_PRESENT_SHIFT) & | |||||
NVME_CTRLR_DATA_VWC_PRESENT_MASK; | |||||
if (vwc_present) | |||||
disk->d_flags |= DISKFLAG_CANFLUSHCACHE; | |||||
if ((cpi.hba_misc & PIM_UNMAPPED) != 0) { | |||||
disk->d_flags |= DISKFLAG_UNMAPPED_BIO; | |||||
softc->unmappedio = 1; | |||||
} | |||||
} | |||||
static void | |||||
ndaasync(void *callback_arg, u_int32_t code, | ndaasync(void *callback_arg, u_int32_t code, | ||||
struct cam_path *path, void *arg) | struct cam_path *path, void *arg) | ||||
{ | { | ||||
struct cam_periph *periph; | struct cam_periph *periph; | ||||
struct nda_softc *softc; | |||||
struct ccb_getdev *cgd; | |||||
int error; | |||||
periph = (struct cam_periph *)callback_arg; | periph = (struct cam_periph *)callback_arg; | ||||
switch (code) { | switch (code) { | ||||
case AC_FOUND_DEVICE: | case AC_FOUND_DEVICE: | ||||
{ | { | ||||
struct ccb_getdev *cgd; | |||||
cam_status status; | cam_status status; | ||||
cgd = (struct ccb_getdev *)arg; | cgd = (struct ccb_getdev *)arg; | ||||
if (cgd == NULL) | if (cgd == NULL) | ||||
break; | break; | ||||
if (cgd->protocol != PROTO_NVME) | if (cgd->protocol != PROTO_NVME) | ||||
break; | break; | ||||
Show All 10 Lines | status = cam_periph_alloc(ndaregister, ndaoninvalidate, | ||||
AC_FOUND_DEVICE, cgd); | AC_FOUND_DEVICE, cgd); | ||||
if (status != CAM_REQ_CMP | if (status != CAM_REQ_CMP | ||||
&& status != CAM_REQ_INPROG) | && status != CAM_REQ_INPROG) | ||||
printf("ndaasync: Unable to attach to new device " | printf("ndaasync: Unable to attach to new device " | ||||
"due to status 0x%x\n", status); | "due to status 0x%x\n", status); | ||||
break; | break; | ||||
} | } | ||||
case AC_GETDEV_CHANGED: | |||||
{ | |||||
softc = (struct nda_softc *)periph->softc; | |||||
imp: You can't do this in the kernel. the stack is too small. | |||||
Done Inline ActionsOK, remove this output. wanpengqian_gmail.com: OK, remove this output. | |||||
/* | |||||
* Update our information based on the new Identify data. | |||||
*/ | |||||
ndasetgeom(softc, periph); | |||||
error = disk_resize(softc->disk, M_NOWAIT); | |||||
if (error != 0) { | |||||
xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error); | |||||
break; | |||||
} | |||||
break; | |||||
} | |||||
case AC_ADVINFO_CHANGED: | case AC_ADVINFO_CHANGED: | ||||
{ | { | ||||
uintptr_t buftype; | uintptr_t buftype; | ||||
buftype = (uintptr_t)arg; | buftype = (uintptr_t)arg; | ||||
if (buftype == CDAI_TYPE_PHYS_PATH) { | if (buftype == CDAI_TYPE_PHYS_PATH) { | ||||
struct nda_softc *softc; | |||||
softc = periph->softc; | softc = periph->softc; | ||||
disk_attr_changed(softc->disk, "GEOM::physpath", | disk_attr_changed(softc->disk, "GEOM::physpath", | ||||
M_NOWAIT); | M_NOWAIT); | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case AC_LOST_DEVICE: | case AC_LOST_DEVICE: | ||||
default: | default: | ||||
▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | |||||
ndaregister(struct cam_periph *periph, void *arg) | ndaregister(struct cam_periph *periph, void *arg) | ||||
{ | { | ||||
struct nda_softc *softc; | struct nda_softc *softc; | ||||
struct disk *disk; | struct disk *disk; | ||||
struct ccb_pathinq cpi; | struct ccb_pathinq cpi; | ||||
const struct nvme_namespace_data *nsd; | const struct nvme_namespace_data *nsd; | ||||
const struct nvme_controller_data *cd; | const struct nvme_controller_data *cd; | ||||
char announce_buf[80]; | char announce_buf[80]; | ||||
uint8_t flbas_fmt, lbads, vwc_present; | |||||
u_int maxio; | u_int maxio; | ||||
int quirks; | int quirks; | ||||
nsd = nvme_get_identify_ns(periph); | nsd = nvme_get_identify_ns(periph); | ||||
cd = nvme_get_identify_cntrl(periph); | cd = nvme_get_identify_cntrl(periph); | ||||
softc = (struct nda_softc *)malloc(sizeof(*softc), M_DEVBUF, | softc = (struct nda_softc *)malloc(sizeof(*softc), M_DEVBUF, | ||||
M_NOWAIT | M_ZERO); | M_NOWAIT | M_ZERO); | ||||
Show All 30 Lines | ndaregister(struct cam_periph *periph, void *arg) | ||||
cam_periph_unlock(periph); | cam_periph_unlock(periph); | ||||
snprintf(announce_buf, sizeof(announce_buf), | snprintf(announce_buf, sizeof(announce_buf), | ||||
"kern.cam.nda.%d.quirks", periph->unit_number); | "kern.cam.nda.%d.quirks", periph->unit_number); | ||||
quirks = softc->quirks; | quirks = softc->quirks; | ||||
TUNABLE_INT_FETCH(announce_buf, &quirks); | TUNABLE_INT_FETCH(announce_buf, &quirks); | ||||
softc->quirks = quirks; | softc->quirks = quirks; | ||||
cam_iosched_set_sort_queue(softc->cam_iosched, 0); | cam_iosched_set_sort_queue(softc->cam_iosched, 0); | ||||
softc->disk = disk = disk_alloc(); | softc->disk = disk = disk_alloc(); | ||||
disk->d_rotation_rate = DISK_RR_NON_ROTATING; | disk->d_rotation_rate = DISK_RR_NON_ROTATING; | ||||
Not Done Inline ActionsI think this should be after we set the other parameters. imp: I think this should be after we set the other parameters. | |||||
Done Inline ActionsYes, I did not match the original sequence. wanpengqian_gmail.com: Yes, I did not match the original sequence. | |||||
disk->d_open = ndaopen; | disk->d_open = ndaopen; | ||||
disk->d_close = ndaclose; | disk->d_close = ndaclose; | ||||
disk->d_strategy = ndastrategy; | disk->d_strategy = ndastrategy; | ||||
disk->d_ioctl = ndaioctl; | disk->d_ioctl = ndaioctl; | ||||
disk->d_getattr = ndagetattr; | disk->d_getattr = ndagetattr; | ||||
if (cam_sim_pollable(periph->sim)) | if (cam_sim_pollable(periph->sim)) | ||||
disk->d_dump = ndadump; | disk->d_dump = ndadump; | ||||
disk->d_gone = ndadiskgonecb; | disk->d_gone = ndadiskgonecb; | ||||
disk->d_name = "nda"; | disk->d_name = "nda"; | ||||
disk->d_drv1 = periph; | disk->d_drv1 = periph; | ||||
disk->d_unit = periph->unit_number; | disk->d_unit = periph->unit_number; | ||||
maxio = cpi.maxio; /* Honor max I/O size of SIM */ | maxio = cpi.maxio; /* Honor max I/O size of SIM */ | ||||
if (maxio == 0) | if (maxio == 0) | ||||
maxio = DFLTPHYS; /* traditional default */ | maxio = DFLTPHYS; /* traditional default */ | ||||
else if (maxio > maxphys) | else if (maxio > maxphys) | ||||
maxio = maxphys; /* for safety */ | maxio = maxphys; /* for safety */ | ||||
disk->d_maxsize = maxio; | disk->d_maxsize = maxio; | ||||
flbas_fmt = (nsd->flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) & | |||||
NVME_NS_DATA_FLBAS_FORMAT_MASK; | ndasetgeom(softc, periph); | ||||
lbads = (nsd->lbaf[flbas_fmt] >> NVME_NS_DATA_LBAF_LBADS_SHIFT) & | |||||
NVME_NS_DATA_LBAF_LBADS_MASK; | |||||
disk->d_sectorsize = 1 << lbads; | |||||
disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze); | |||||
disk->d_delmaxsize = disk->d_mediasize; | |||||
disk->d_flags = DISKFLAG_DIRECT_COMPLETION; | |||||
if (nvme_ctrlr_has_dataset_mgmt(cd)) | |||||
disk->d_flags |= DISKFLAG_CANDELETE; | |||||
vwc_present = (cd->vwc >> NVME_CTRLR_DATA_VWC_PRESENT_SHIFT) & | |||||
NVME_CTRLR_DATA_VWC_PRESENT_MASK; | |||||
if (vwc_present) | |||||
disk->d_flags |= DISKFLAG_CANFLUSHCACHE; | |||||
if ((cpi.hba_misc & PIM_UNMAPPED) != 0) { | |||||
disk->d_flags |= DISKFLAG_UNMAPPED_BIO; | |||||
softc->unmappedio = 1; | |||||
} | |||||
/* | /* | ||||
* d_ident and d_descr are both far bigger than the length of either | * d_ident and d_descr are both far bigger than the length of either | ||||
* the serial or model number strings. | * the serial or model number strings. | ||||
*/ | */ | ||||
cam_strvis(disk->d_descr, cd->mn, | cam_strvis(disk->d_descr, cd->mn, | ||||
NVME_MODEL_NUMBER_LENGTH, sizeof(disk->d_descr)); | NVME_MODEL_NUMBER_LENGTH, sizeof(disk->d_descr)); | ||||
cam_strvis(disk->d_ident, cd->sn, | cam_strvis(disk->d_ident, cd->sn, | ||||
NVME_SERIAL_NUMBER_LENGTH, sizeof(disk->d_ident)); | NVME_SERIAL_NUMBER_LENGTH, sizeof(disk->d_ident)); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | ndaregister(struct cam_periph *periph, void *arg) | ||||
*/ | */ | ||||
if (cam_periph_acquire(periph) == 0) | if (cam_periph_acquire(periph) == 0) | ||||
taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task); | taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task); | ||||
/* | /* | ||||
* Register for device going away and info about the drive | * Register for device going away and info about the drive | ||||
* changing (though with NVMe, it can't) | * changing (though with NVMe, it can't) | ||||
*/ | */ | ||||
xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED, | xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED | AC_GETDEV_CHANGED, | ||||
ndaasync, periph, periph->path); | ndaasync, periph, periph->path); | ||||
softc->state = NDA_STATE_NORMAL; | softc->state = NDA_STATE_NORMAL; | ||||
return(CAM_REQ_CMP); | return(CAM_REQ_CMP); | ||||
} | } | ||||
static void | static void | ||||
ndastart(struct cam_periph *periph, union ccb *start_ccb) | ndastart(struct cam_periph *periph, union ccb *start_ccb) | ||||
▲ Show 20 Lines • Show All 361 Lines • Show Last 20 Lines |
You can't do this in the kernel. the stack is too small.