Changeset View
Changeset View
Standalone View
Standalone View
head/sys/cam/scsi/scsi_da.c
Show First 20 Lines • Show All 1,519 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
daclose(struct disk *dp) | daclose(struct disk *dp) | ||||
{ | { | ||||
struct cam_periph *periph; | struct cam_periph *periph; | ||||
struct da_softc *softc; | struct da_softc *softc; | ||||
union ccb *ccb; | union ccb *ccb; | ||||
int error; | |||||
periph = (struct cam_periph *)dp->d_drv1; | periph = (struct cam_periph *)dp->d_drv1; | ||||
softc = (struct da_softc *)periph->softc; | softc = (struct da_softc *)periph->softc; | ||||
cam_periph_lock(periph); | cam_periph_lock(periph); | ||||
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, | CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, | ||||
("daclose\n")); | ("daclose\n")); | ||||
if (cam_periph_hold(periph, PRIBIO) == 0) { | if (cam_periph_hold(periph, PRIBIO) == 0) { | ||||
/* Flush disk cache. */ | /* Flush disk cache. */ | ||||
if ((softc->flags & DA_FLAG_DIRTY) != 0 && | if ((softc->flags & DA_FLAG_DIRTY) != 0 && | ||||
(softc->quirks & DA_Q_NO_SYNC_CACHE) == 0 && | (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0 && | ||||
(softc->flags & DA_FLAG_PACK_INVALID) == 0) { | (softc->flags & DA_FLAG_PACK_INVALID) == 0) { | ||||
ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); | ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); | ||||
scsi_synchronize_cache(&ccb->csio, /*retries*/1, | scsi_synchronize_cache(&ccb->csio, /*retries*/1, | ||||
/*cbfcnp*/dadone, MSG_SIMPLE_Q_TAG, | /*cbfcnp*/dadone, MSG_SIMPLE_Q_TAG, | ||||
/*begin_lba*/0, /*lb_count*/0, SSD_FULL_SIZE, | /*begin_lba*/0, /*lb_count*/0, SSD_FULL_SIZE, | ||||
5 * 60 * 1000); | 5 * 60 * 1000); | ||||
error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0, | cam_periph_runccb(ccb, daerror, /*cam_flags*/0, | ||||
/*sense_flags*/SF_RETRY_UA | SF_QUIET_IR, | /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR, | ||||
softc->disk->d_devstat); | softc->disk->d_devstat); | ||||
softc->flags &= ~DA_FLAG_DIRTY; | softc->flags &= ~DA_FLAG_DIRTY; | ||||
xpt_release_ccb(ccb); | xpt_release_ccb(ccb); | ||||
} | } | ||||
/* Allow medium removal. */ | /* Allow medium removal. */ | ||||
if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && | if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && | ||||
▲ Show 20 Lines • Show All 750 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
dadeletemethodsysctl(SYSCTL_HANDLER_ARGS) | dadeletemethodsysctl(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
char buf[16]; | char buf[16]; | ||||
const char *p; | const char *p; | ||||
struct da_softc *softc; | struct da_softc *softc; | ||||
int i, error, methods, value; | int i, error, value; | ||||
softc = (struct da_softc *)arg1; | softc = (struct da_softc *)arg1; | ||||
value = softc->delete_method; | value = softc->delete_method; | ||||
if (value < 0 || value > DA_DELETE_MAX) | if (value < 0 || value > DA_DELETE_MAX) | ||||
p = "UNKNOWN"; | p = "UNKNOWN"; | ||||
else | else | ||||
p = da_delete_method_names[value]; | p = da_delete_method_names[value]; | ||||
strncpy(buf, p, sizeof(buf)); | strncpy(buf, p, sizeof(buf)); | ||||
error = sysctl_handle_string(oidp, buf, sizeof(buf), req); | error = sysctl_handle_string(oidp, buf, sizeof(buf), req); | ||||
if (error != 0 || req->newptr == NULL) | if (error != 0 || req->newptr == NULL) | ||||
return (error); | return (error); | ||||
methods = softc->delete_available | (1 << DA_DELETE_DISABLE); | |||||
for (i = 0; i <= DA_DELETE_MAX; i++) { | for (i = 0; i <= DA_DELETE_MAX; i++) { | ||||
if (strcmp(buf, da_delete_method_names[i]) == 0) | if (strcmp(buf, da_delete_method_names[i]) == 0) | ||||
break; | break; | ||||
} | } | ||||
if (i > DA_DELETE_MAX) | if (i > DA_DELETE_MAX) | ||||
return (EINVAL); | return (EINVAL); | ||||
softc->delete_method_pref = i; | softc->delete_method_pref = i; | ||||
dadeletemethodchoose(softc, DA_DELETE_NONE); | dadeletemethodchoose(softc, DA_DELETE_NONE); | ||||
▲ Show 20 Lines • Show All 1,629 Lines • ▼ Show 20 Lines | dazonedone(struct cam_periph *periph, union ccb *ccb) | ||||
case DISK_ZONE_RWP: | case DISK_ZONE_RWP: | ||||
break; | break; | ||||
case DISK_ZONE_REPORT_ZONES: { | case DISK_ZONE_REPORT_ZONES: { | ||||
uint32_t avail_len; | uint32_t avail_len; | ||||
struct disk_zone_report *rep; | struct disk_zone_report *rep; | ||||
struct scsi_report_zones_hdr *hdr; | struct scsi_report_zones_hdr *hdr; | ||||
struct scsi_report_zones_desc *desc; | struct scsi_report_zones_desc *desc; | ||||
struct disk_zone_rep_entry *entry; | struct disk_zone_rep_entry *entry; | ||||
uint32_t num_alloced, hdr_len, num_avail; | uint32_t hdr_len, num_avail; | ||||
uint32_t num_to_fill, i; | uint32_t num_to_fill, i; | ||||
int ata; | int ata; | ||||
rep = &bp->bio_zone.zone_params.report; | rep = &bp->bio_zone.zone_params.report; | ||||
avail_len = ccb->csio.dxfer_len - ccb->csio.resid; | avail_len = ccb->csio.dxfer_len - ccb->csio.resid; | ||||
/* | /* | ||||
* Note that bio_resid isn't normally used for zone | * Note that bio_resid isn't normally used for zone | ||||
* commands, but it is used by devstat_end_transaction_bio() | * commands, but it is used by devstat_end_transaction_bio() | ||||
* to determine how much data was transferred. Because | * to determine how much data was transferred. Because | ||||
* the size of the SCSI/ATA data structures is different | * the size of the SCSI/ATA data structures is different | ||||
* than the size of the BIO interface structures, the | * than the size of the BIO interface structures, the | ||||
* amount of data actually transferred from the drive will | * amount of data actually transferred from the drive will | ||||
* be different than the amount of data transferred to | * be different than the amount of data transferred to | ||||
* the user. | * the user. | ||||
*/ | */ | ||||
bp->bio_resid = ccb->csio.resid; | bp->bio_resid = ccb->csio.resid; | ||||
num_alloced = rep->entries_allocated; | |||||
hdr = (struct scsi_report_zones_hdr *)ccb->csio.data_ptr; | hdr = (struct scsi_report_zones_hdr *)ccb->csio.data_ptr; | ||||
if (avail_len < sizeof(*hdr)) { | if (avail_len < sizeof(*hdr)) { | ||||
/* | /* | ||||
* Is there a better error than EIO here? We asked | * Is there a better error than EIO here? We asked | ||||
* for at least the header, and we got less than | * for at least the header, and we got less than | ||||
* that. | * that. | ||||
*/ | */ | ||||
bp->bio_error = EIO; | bp->bio_error = EIO; | ||||
▲ Show 20 Lines • Show All 2,058 Lines • Show Last 20 Lines |