diff options
| author | cg149915 <none@none> | 2006-02-12 18:34:23 -0800 |
|---|---|---|
| committer | cg149915 <none@none> | 2006-02-12 18:34:23 -0800 |
| commit | 0167b58cea98965c58fab4be4e690b6e456f7440 (patch) | |
| tree | ce95848e01ff762edd1c89304f9881b61db127e8 /usr/src | |
| parent | 7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fe (diff) | |
| download | illumos-joyent-0167b58cea98965c58fab4be4e690b6e456f7440.tar.gz | |
PSARC 2005/731 hotpluggable disk support
6348407 Enable EFI partitions and device ID supports for hotpluggable devices
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/lib/libdiskmgt/common/findevs.c | 15 | ||||
| -rw-r--r-- | usr/src/uts/common/io/1394/targets/scsa1394/hba.c | 29 | ||||
| -rw-r--r-- | usr/src/uts/common/io/scsi/targets/sd.c | 1042 | ||||
| -rw-r--r-- | usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c | 44 | ||||
| -rw-r--r-- | usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf | 55 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/dkio.h | 8 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/scsi/targets/sddef.h | 55 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h | 4 |
8 files changed, 933 insertions, 319 deletions
diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c index 9c55ee7e2d..5a5bd4fc15 100644 --- a/usr/src/lib/libdiskmgt/common/findevs.c +++ b/usr/src/lib/libdiskmgt/common/findevs.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +56,7 @@ #define PROD_ID_PROP "inquiry-product-id" #define PROD_ID_USB_PROP "usb-product-name" #define REMOVABLE_PROP "removable-media" +#define HOTPLUGGABLE_PROP "hotpluggable" #define SCSI_OPTIONS_PROP "scsi-options" #define VENDOR_ID_PROP "inquiry-vendor-id" #define VENDOR_ID_USB_PROP "usb-vendor-name" @@ -973,10 +974,20 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args) diskp->drv_type = DM_DT_FLOPPY; diskp->removable = 1; } else { - /* not a "CD-ROM" or Floppy */ + /* not a "CD-ROM" or Floppy */ diskp->removable = get_prop(REMOVABLE_PROP, args->node); if (diskp->removable == -1) { + /* + * This is a workaround. Hotpluggable devices don't export + * a "removable-media" property, but they are treated as + * removable media devices by vold to implement automount. + * Once vold is EOL'ed, it should be removed. + */ + diskp->removable = get_prop(HOTPLUGGABLE_PROP, args->node); + } + + if (diskp->removable == -1) { diskp->removable = 0; #if defined(i386) || defined(__amd64) /* diff --git a/usr/src/uts/common/io/1394/targets/scsa1394/hba.c b/usr/src/uts/common/io/1394/targets/scsa1394/hba.c index 84829dcc2e..3435f0b11a 100644 --- a/usr/src/uts/common/io/1394/targets/scsa1394/hba.c +++ b/usr/src/uts/common/io/1394/targets/scsa1394/hba.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -201,7 +201,7 @@ int scsa1394_start_stop_timeout_max = SCSA1394_START_STOP_TIMEOUT_MAX; /* workarounds */ int scsa1394_wrka_rbc2direct = 1; -int scsa1394_wrka_force_rmb = 1; +int scsa1394_wrka_fake_rmb = 0; int scsa1394_wrka_fake_prin = 1; int scsa1394_wrka_symbios = 1; @@ -732,6 +732,26 @@ scsa1394_create_children(scsa1394_state_t *sp) continue; } + /* + * Some devices don't support LOG SENSE, so tell + * sd driver not to send this command. + */ + ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, + "pm-capable", 1); + if (ret != DDI_PROP_SUCCESS) { + ddi_prop_remove_all(cdip); + (void) ndi_devi_free(cdip); + continue; + } + + ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, + "hotpluggable"); + if (ret != DDI_PROP_SUCCESS) { + ddi_prop_remove_all(cdip); + (void) ndi_devi_free(cdip); + continue; + } + if (driver_name) { compatible[0] = driver_name; ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip, @@ -951,8 +971,7 @@ scsa1394_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)()) #endif } - /* vold only handles devices with removeable bit set */ - if (scsa1394_wrka_force_rmb) { + if (scsa1394_wrka_fake_rmb) { sd->sd_inq->inq_rmb = 1; } @@ -2392,7 +2411,7 @@ scsa1394_cmd_status_wrka(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) /* force RMB to 1 */ lp->l_rmb_orig = inq->inq_rmb; - if (scsa1394_wrka_force_rmb) { + if (scsa1394_wrka_fake_rmb) { inq->inq_rmb = 1; } break; diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c index 97d08787a6..afa69996ef 100644 --- a/usr/src/uts/common/io/scsi/targets/sd.c +++ b/usr/src/uts/common/io/scsi/targets/sd.c @@ -30,6 +30,9 @@ * SCSI disk target driver. */ + + + #include <sys/scsi/scsi.h> #include <sys/dkbad.h> #include <sys/dklabel.h> @@ -49,6 +52,12 @@ #include <sys/efi_partition.h> #include <sys/var.h> #include <sys/aio_req.h> + +#ifdef __lock_lint +#define _LP64 +#define __amd64 +#endif + #if (defined(__fibre)) /* Note: is there a leadville version of the following? */ #include <sys/fc4/fcal_linkapp.h> @@ -62,6 +71,7 @@ #include <sys/scsi/targets/sddef.h> + /* * Loadable module info. */ @@ -822,6 +832,7 @@ static int sd_pm_idletime = 1; #define sddetach ssddetach #define sd_unit_attach ssd_unit_attach #define sd_unit_detach ssd_unit_detach +#define sd_set_unit_attributes ssd_set_unit_attributes #define sd_create_minor_nodes ssd_create_minor_nodes #define sd_create_errstats ssd_create_errstats #define sd_set_errstats ssd_set_errstats @@ -1153,6 +1164,7 @@ static int sddetach(dev_info_t *devi, ddi_detach_cmd_t cmd); static int sd_unit_attach(dev_info_t *devi); static int sd_unit_detach(dev_info_t *devi); +static void sd_set_unit_attributes(struct sd_lun *un, dev_info_t *devi); static int sd_create_minor_nodes(struct sd_lun *un, dev_info_t *devi); static void sd_create_errstats(struct sd_lun *un, int instance); static void sd_set_errstats(struct sd_lun *un); @@ -1272,6 +1284,12 @@ static void sd_shadow_buf_free(struct buf *bp); static void sd_print_transport_rejected_message(struct sd_lun *un, struct sd_xbuf *xp, int code); +static void sd_print_incomplete_msg(struct sd_lun *un, struct buf *bp, + void *arg, int code); +static void sd_print_sense_failed_msg(struct sd_lun *un, struct buf *bp, + void *arg, int code); +static void sd_print_cmd_incomplete_msg(struct sd_lun *un, struct buf *bp, + void *arg, int code); static void sd_retry_command(struct sd_lun *un, struct buf *bp, int retry_check_flag, @@ -3246,12 +3264,7 @@ sd_read_unit_properties(struct sd_lun *un) /* check for LSI device */ sd_is_lsi(un); - /* - * Set this in sd.conf to 0 in order to disable kstats. The default - * is 1, so they are enabled by default. - */ - un->un_f_pkstats_enabled = (ddi_prop_get_int(DDI_DEV_T_ANY, - SD_DEVINFO(un), DDI_PROP_DONTPASS, "enable-partition-kstats", 1)); + } @@ -4192,12 +4205,7 @@ sd_validate_geometry(struct sd_lun *un, int path_flag) * at this point it is either labeled with a VTOC or it is * under 1TB */ - - /* - * Only DIRECT ACCESS devices will have Sun labels. - * CD's supposedly have a Sun label, too - */ - if (SD_INQUIRY(un)->inq_dtype == DTYPE_DIRECT || ISREMOVABLE(un)) { + if (un->un_f_vtoc_label_supported) { struct dk_label *dkl; offset_t dkl1; offset_t label_addr, real_addr; @@ -4287,17 +4295,9 @@ sd_validate_geometry(struct sd_lun *un, int path_flag) /* * If a valid label was not found, AND if no reservation conflict * was detected, then go ahead and create a default label (4069506). - * - * Note: currently, for VTOC_8 devices, the default label is created - * for removables only. For VTOC_16 devices, the default label will - * be created for both removables and non-removables alike. - * (see sd_build_default_label) */ -#if defined(_SUNOS_VTOC_8) - if (ISREMOVABLE(un) && (label_error != EACCES)) { -#elif defined(_SUNOS_VTOC_16) - if (label_error != EACCES) { -#endif + + if (un->un_f_default_vtoc_supported && (label_error != EACCES)) { if (un->un_f_geometry_is_valid == FALSE) { sd_build_default_label(un); } @@ -4305,9 +4305,10 @@ sd_validate_geometry(struct sd_lun *un, int path_flag) } no_solaris_partition: - if ((!ISREMOVABLE(un) || - (ISREMOVABLE(un) && un->un_mediastate == DKIO_EJECTED)) && - (un->un_state == SD_STATE_NORMAL && gvalid == FALSE)) { + if ((!un->un_f_has_removable_media || + (un->un_f_has_removable_media && + un->un_mediastate == DKIO_EJECTED)) && + (un->un_state == SD_STATE_NORMAL && !gvalid)) { /* * Print out a message indicating who and what we are. * We do this only when we happen to really validate the @@ -5255,8 +5256,8 @@ sd_use_efi(struct sd_lun *un, int path_flag) */ if ((rval = sd_send_scsi_READ(un, buf, lbasize, cap - 1, (ISCD(un)) ? SD_PATH_DIRECT_PRIORITY : - path_flag)) != 0) { - goto done_err; + path_flag)) != 0) { + goto done_err; } sd_swap_efi_gpt((efi_gpt_t *)buf); @@ -5375,7 +5376,7 @@ sd_uselabel(struct sd_lun *un, struct dk_label *labp, int path_flag) if (labp->dkl_magic != DKL_MAGIC) { #if defined(__sparc) if ((un->un_state == SD_STATE_NORMAL) && - !ISREMOVABLE(un)) { + un->un_f_vtoc_errlog_supported) { scsi_log(SD_DEVINFO(un), sd_label, CE_WARN, "Corrupt label; wrong magic number\n"); } @@ -5392,10 +5393,11 @@ sd_uselabel(struct sd_lun *un, struct dk_label *labp, int path_flag) } if (sum != 0) { -#if defined(_SUNOS_VTOC_16) - if (un->un_state == SD_STATE_NORMAL && !ISCD(un)) { +#if defined(_SUNOS_VTOC_16) + if ((un->un_state == SD_STATE_NORMAL) && !ISCD(un)) { #elif defined(_SUNOS_VTOC_8) - if (un->un_state == SD_STATE_NORMAL && !ISREMOVABLE(un)) { + if ((un->un_state == SD_STATE_NORMAL) && + un->un_f_vtoc_errlog_supported) { #endif scsi_log(SD_DEVINFO(un), sd_label, CE_WARN, "Corrupt label - label checksum failed\n"); @@ -5640,10 +5642,10 @@ sd_build_default_label(struct sd_lun *un) /* * Note: This is a legacy check for non-removable devices on VTOC_8 * only. This may be a valid check for VTOC_16 as well. + * Once we understand why there is this difference between SPARC and + * x86 platform, we could remove this legacy check. */ - if (!ISREMOVABLE(un)) { - return; - } + ASSERT(un->un_f_default_vtoc_supported); #endif bzero(&un->un_g, sizeof (struct dk_geom)); @@ -5797,7 +5799,6 @@ sd_build_default_label(struct sd_lun *un) un->un_g.dkg_apc = 0; un->un_vtoc.v_nparts = V_NUMPAR; - un->un_vtoc.v_version = V_VERSION; /* Add backup slice */ un->un_vtoc.v_part[2].p_start = 0; @@ -5822,6 +5823,7 @@ sd_build_default_label(struct sd_lun *un) un->un_g.dkg_intrlv = 1; + un->un_vtoc.v_version = V_VERSION; un->un_vtoc.v_sanity = VTOC_SANE; un->un_f_geometry_is_valid = TRUE; @@ -5989,7 +5991,6 @@ sd_register_devid(struct sd_lun *un, dev_info_t *devi, int reservation_flag) /* collect page 83 data if available */ if (un->un_vpd_page_mask & SD_VPD_DEVID_WWN_PG) { - mutex_exit(SD_MUTEX(un)); inq83 = kmem_zalloc(inq83_len, KM_SLEEP); rval = sd_send_scsi_INQUIRY(un, inq83, inq83_len, @@ -6420,56 +6421,17 @@ sd_setup_pm(struct sd_lun *un, dev_info_t *devi) "pm-hardware-state", "needs-suspend-resume"); /* - * Check if HBA has set the "pm-capable" property. - * If "pm-capable" exists and is non-zero then we can - * power manage the device without checking the start/stop - * cycle count log sense page. - * - * If "pm-capable" exists and is SD_PM_CAPABLE_FALSE (0) - * then we should not power manage the device. - * - * If "pm-capable" doesn't exist then un->un_pm_capable_prop will - * be set to SD_PM_CAPABLE_UNDEFINED (-1). In this case, sd will - * check the start/stop cycle count log sense page and power manage - * the device if the cycle count limit has not been exceeded. - */ - un->un_pm_capable_prop = - ddi_prop_get_int(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, - "pm-capable", SD_PM_CAPABLE_UNDEFINED); - if (un->un_pm_capable_prop != SD_PM_CAPABLE_UNDEFINED) { - /* - * pm-capable property exists. - * - * Convert "TRUE" values for un_pm_capable_prop to - * SD_PM_CAPABLE_TRUE (1) to make it easier to check later. - * "TRUE" values are any values except SD_PM_CAPABLE_FALSE (0) - * and SD_PM_CAPABLE_UNDEFINED (-1) - */ - if (un->un_pm_capable_prop != SD_PM_CAPABLE_FALSE) { - un->un_pm_capable_prop = SD_PM_CAPABLE_TRUE; - } - - SD_INFO(SD_LOG_ATTACH_DETACH, un, - "sd_unit_attach: un:0x%p pm-capable " - "property set to %d.\n", un, un->un_pm_capable_prop); - } - - /* * This complies with the new power management framework * for certain desktop machines. Create the pm_components * property as a string array property. - * - * If this is a removable device or if the pm-capable property - * is SD_PM_CAPABLE_TRUE (1) then we should create the - * pm_components property without checking for the existance of - * the start-stop cycle counter log page */ - if (ISREMOVABLE(un) || - un->un_pm_capable_prop == SD_PM_CAPABLE_TRUE) { + if (un->un_f_pm_supported) { /* * not all devices have a motor, try it first. * some devices may return ILLEGAL REQUEST, some * will hang + * The following START_STOP_UNIT is used to check if target + * device has a motor. */ un->un_f_start_stop_supported = TRUE; if (sd_send_scsi_START_STOP_UNIT(un, SD_TARGET_START, @@ -6483,19 +6445,12 @@ sd_setup_pm(struct sd_lun *un, dev_info_t *devi) */ (void) sd_create_pm_components(devi, un); un->un_f_pm_is_enabled = TRUE; + return; + } - /* - * Need to create a zero length (Boolean) property - * removable-media for the removable media devices. - * Note that the return value of the property is not being - * checked, since if unable to create the property - * then do not want the attach to fail altogether. Consistent - * with other property creation in attach. - */ - if (ISREMOVABLE(un)) { - (void) ddi_prop_create(DDI_DEV_T_NONE, devi, - DDI_PROP_CANSLEEP, "removable-media", NULL, 0); - } + if (!un->un_f_log_sense_supported) { + un->un_power_level = SD_SPINDLE_ON; + un->un_f_pm_is_enabled = FALSE; return; } @@ -6513,7 +6468,7 @@ sd_setup_pm(struct sd_lun *un, dev_info_t *devi) * or if the pm-capable property is SD_PM_CAPABLE_FALSE (0) * then we should not create the pm_components property. */ - if (rval == -1 || un->un_pm_capable_prop == SD_PM_CAPABLE_FALSE) { + if (rval == -1) { /* * Error. * Reading log sense failed, most likely this is @@ -6613,7 +6568,7 @@ sd_create_pm_components(dev_info_t *devi, struct sd_lun *un) * fails. In the case of removable media, the start/stop * will fail if the media is not present. */ - if ((!ISREMOVABLE(un)) && (pm_raise_power(SD_DEVINFO(un), 0, + if (un->un_f_attach_spinup && (pm_raise_power(SD_DEVINFO(un), 0, SD_SPINDLE_ON) == DDI_SUCCESS)) { mutex_enter(SD_MUTEX(un)); un->un_power_level = SD_SPINDLE_ON; @@ -6934,7 +6889,7 @@ sd_ddi_resume(dev_info_t *devi) * inserted and hence there is a chance that raise power will fail with * media not present. */ - if (!ISREMOVABLE(un)) { + if (un->un_f_attach_spinup) { mutex_exit(SD_MUTEX(un)); (void) pm_raise_power(SD_DEVINFO(un), 0, SD_SPINDLE_ON); mutex_enter(SD_MUTEX(un)); @@ -7073,7 +7028,7 @@ sd_pm_idletimeout_handler(void *arg) * Update the chain types. * This takes affect on the next new command received. */ - if (ISREMOVABLE(un)) { + if (un->un_f_non_devbsize_supported) { un->un_buf_chain_type = SD_CHAIN_INFO_RMMEDIA; } else { un->un_buf_chain_type = SD_CHAIN_INFO_DISK; @@ -7224,13 +7179,11 @@ sdpower(dev_info_t *devi, int component, int level) mutex_exit(SD_MUTEX(un)); /* - * Bypass checking the log sense information for removables - * and devices for which the HBA set the pm-capable property. - * If un->un_pm_capable_prop is SD_PM_CAPABLE_UNDEFINED (-1) - * then the HBA did not create the property. + * If "pm-capable" property is set to TRUE by HBA drivers, + * bypass the following checking, otherwise, check the log + * sense information for this device */ - if ((level == SD_SPINDLE_OFF) && (!ISREMOVABLE(un)) && - un->un_pm_capable_prop == SD_PM_CAPABLE_UNDEFINED) { + if ((level == SD_SPINDLE_OFF) && un->un_f_log_sense_supported) { /* * Get the log sense information to understand whether the * the powercycle counts have gone beyond the threshhold. @@ -7446,7 +7399,7 @@ sdpower(dev_info_t *devi, int component, int level) ((level == SD_SPINDLE_ON) ? SD_TARGET_START : SD_TARGET_STOP), SD_PATH_DIRECT); /* Command failed, check for media present. */ - if ((sval == ENXIO) && ISREMOVABLE(un)) { + if ((sval == ENXIO) && un->un_f_has_removable_media) { medium_present = FALSE; } @@ -7479,7 +7432,7 @@ sdpower(dev_info_t *devi, int component, int level) /* * The stop command from above succeeded. */ - if (ISREMOVABLE(un)) { + if (un->un_f_monitor_media_state) { /* * Terminate watch thread in case of removable media * devices going into low power state. This is as per @@ -7524,7 +7477,7 @@ sdpower(dev_info_t *devi, int component, int level) * Resume the watch thread since it was suspended * when the device went into low power mode. */ - if (ISREMOVABLE(un)) { + if (un->un_f_monitor_media_state) { mutex_enter(SD_MUTEX(un)); if (un->un_f_watcht_stopped == TRUE) { opaque_t temp_token; @@ -8010,12 +7963,6 @@ sd_unit_attach(dev_info_t *devi) ddi_prop_free(variantp); } - /* - * Assume doorlock commands are supported. If not, the first - * call to sd_send_scsi_DOORLOCK() will set to FALSE - */ - un->un_f_doorlock_supported = TRUE; - un->un_cmd_timeout = SD_IO_TIME; /* Info on current states, statuses, etc. (Updated frequently) */ @@ -8071,7 +8018,23 @@ sd_unit_attach(dev_info_t *devi) "sd_unit_attach: un:0x%p property configuration complete.\n", un); /* - * By default, we mark the capacity, lbazize, and geometry + * Only if a device has "hotpluggable" property, it is + * treated as hotpluggable device. Otherwise, it is + * regarded as non-hotpluggable one. + */ + if (ddi_prop_get_int(DDI_DEV_T_ANY, devi, 0, "hotpluggable", + -1) != -1) { + un->un_f_is_hotpluggable = TRUE; + } + + /* + * set unit's attributes(flags) according to "hotpluggable" and + * RMB bit in INQUIRY data. + */ + sd_set_unit_attributes(un, devi); + + /* + * By default, we mark the capacity, lbasize, and geometry * as invalid. Only if we successfully read a valid capacity * will we update the un_blockcount and un_tgt_blocksize with the * valid values (the geometry will be validated later). @@ -8096,7 +8059,7 @@ sd_unit_attach(dev_info_t *devi) /* * Set up the IO chains to use, based upon the target type. */ - if (ISREMOVABLE(un)) { + if (un->un_f_non_devbsize_supported) { un->un_buf_chain_type = SD_CHAIN_INFO_RMMEDIA; } else { un->un_buf_chain_type = SD_CHAIN_INFO_DISK; @@ -8276,7 +8239,7 @@ sd_unit_attach(dev_info_t *devi) * of these could fail and in some cases we would continue with * the attach despite the failure (see below). */ - if (devp->sd_inq->inq_dtype == DTYPE_DIRECT && !ISREMOVABLE(un)) { + if (un->un_f_descr_format_supported) { switch (sd_spin_up_unit(un)) { case 0: /* @@ -8419,7 +8382,7 @@ sd_unit_attach(dev_info_t *devi) * layers are added to the command chain, these values will * have to be re-evaluated for correctness. */ - if (ISREMOVABLE(un)) { + if (un->un_f_non_devbsize_supported) { un->un_buf_chain_type = SD_CHAIN_INFO_RMMEDIA_NO_PM; } else { un->un_buf_chain_type = SD_CHAIN_INFO_DISK_NO_PM; @@ -8475,38 +8438,37 @@ sd_unit_attach(dev_info_t *devi) un->un_f_geometry_is_valid = FALSE; un->un_mediastate = DKIO_NONE; un->un_reserved = -1; - if (!ISREMOVABLE(un)) { + + /* + * Read and validate the device's geometry (ie, disk label) + * A new unformatted drive will not have a valid geometry, but + * the driver needs to successfully attach to this device so + * the drive can be formatted via ioctls. + */ + if (((sd_validate_geometry(un, SD_PATH_DIRECT) == + ENOTSUP)) && + (un->un_blockcount < DK_MAX_BLOCKS)) { /* - * Read and validate the device's geometry (ie, disk label) - * A new unformatted drive will not have a valid geometry, but - * the driver needs to successfully attach to this device so - * the drive can be formatted via ioctls. + * We found a small disk with an EFI label on it; + * we need to fix up the minor nodes accordingly. */ - if (((sd_validate_geometry(un, SD_PATH_DIRECT) == - ENOTSUP)) && - (un->un_blockcount < DK_MAX_BLOCKS)) { - /* - * We found a small disk with an EFI label on it; - * we need to fix up the minor nodes accordingly. - */ - ddi_remove_minor_node(devi, "h"); - ddi_remove_minor_node(devi, "h,raw"); - (void) ddi_create_minor_node(devi, "wd", - S_IFBLK, - (instance << SDUNIT_SHIFT) | WD_NODE, - un->un_node_type, NULL); - (void) ddi_create_minor_node(devi, "wd,raw", - S_IFCHR, - (instance << SDUNIT_SHIFT) | WD_NODE, - un->un_node_type, NULL); - } + ddi_remove_minor_node(devi, "h"); + ddi_remove_minor_node(devi, "h,raw"); + (void) ddi_create_minor_node(devi, "wd", + S_IFBLK, + (instance << SDUNIT_SHIFT) | WD_NODE, + un->un_node_type, NULL); + (void) ddi_create_minor_node(devi, "wd,raw", + S_IFCHR, + (instance << SDUNIT_SHIFT) | WD_NODE, + un->un_node_type, NULL); } /* * Read and initialize the devid for the unit. */ ASSERT(un->un_errstats != NULL); - if (!ISREMOVABLE(un)) { + if (un->un_f_devid_supported) { sd_register_devid(un, devi, reservation_flag); } mutex_exit(SD_MUTEX(un)); @@ -8560,7 +8522,7 @@ sd_unit_attach(dev_info_t *devi) * stats (sd_set_pstats)here, following sd_validate_geometry(), * sd_register_devid(), and sd_disable_caching(). */ - if (!ISREMOVABLE(un) && (un->un_f_pkstats_enabled == TRUE)) { + if (un->un_f_pkstats_enabled) { sd_set_pstats(un); SD_TRACE(SD_LOG_ATTACH_DETACH, un, "sd_unit_attach: un:0x%p pstats created and set\n", un); @@ -9104,8 +9066,8 @@ sd_unit_detach(dev_info_t *devi) un->un_errstats = NULL; } - /* Remove partition stats (not created for removables) */ - if (!ISREMOVABLE(un)) { + /* Remove partition stats */ + if (un->un_f_pkstats_enabled) { for (i = 0; i < NSDMAP; i++) { if (un->un_pstats[i] != NULL) { kstat_delete(un->un_pstats[i]); @@ -9983,7 +9945,7 @@ sd_pm_entry(struct sd_lun *un) "sd_pm_entry: changing uscsi_chain_type from %d\n", un->un_uscsi_chain_type); - if (ISREMOVABLE(un)) { + if (un->un_f_non_devbsize_supported) { un->un_buf_chain_type = SD_CHAIN_INFO_RMMEDIA_NO_PM; } else { @@ -10227,7 +10189,7 @@ sdopen(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) * more permissive implementation that allows the open to succeed and * WRITE attempts to fail when appropriate. */ - if (ISREMOVABLE(un)) { + if (un->un_f_chk_wp_open) { if ((flag & FWRITE) && (!nodelay)) { mutex_exit(SD_MUTEX(un)); /* @@ -10264,11 +10226,7 @@ sdopen(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) */ if ((rval != SD_READY_VALID) || (!ISCD(un) && un->un_map[part].dkl_nblk <= 0)) { - if (ISREMOVABLE(un)) { - rval = ENXIO; - } else { - rval = EIO; - } + rval = un->un_f_has_removable_media ? ENXIO : EIO; SD_ERROR(SD_LOG_OPEN_CLOSE, un, "sdopen: " "device not ready or invalid disk block value\n"); goto open_fail; @@ -10457,7 +10415,7 @@ sdclose(dev_t dev, int flag, int otyp, cred_t *cred_p) * supported device. */ #if defined(__i386) || defined(__amd64) - if (!ISREMOVABLE(un) || + if (un->un_f_sync_cache_supported || un->un_f_dvdram_writable_device == TRUE) { #else if (un->un_f_dvdram_writable_device == TRUE) { @@ -10481,13 +10439,12 @@ sdclose(dev_t dev, int flag, int otyp, cred_t *cred_p) } /* - * For removable media devices, send an ALLOW MEDIA - * REMOVAL command, but don't get upset if it fails. - * Also invalidate the geometry. We need to raise - * the power of the drive before we can call - * sd_send_scsi_DOORLOCK() + * For devices which supports DOOR_LOCK, send an ALLOW + * MEDIA REMOVAL command, but don't get upset if it + * fails. We need to raise the power of the drive before + * we can call sd_send_scsi_DOORLOCK() */ - if (ISREMOVABLE(un)) { + if (un->un_f_doorlock_supported) { mutex_exit(SD_MUTEX(un)); if (sd_pm_entry(un) == DDI_SUCCESS) { rval = sd_send_scsi_DOORLOCK(un, @@ -10502,31 +10459,40 @@ sdclose(dev_t dev, int flag, int otyp, cred_t *cred_p) rval = EIO; } mutex_enter(SD_MUTEX(un)); + } + /* + * If a device has removable media, invalidate all + * parameters related to media, such as geometry, + * blocksize, and blockcount. + */ + if (un->un_f_has_removable_media) { sr_ejected(un); - /* - * Destroy the cache (if it exists) which was - * allocated for the write maps since this is - * the last close for this media. - */ - if (un->un_wm_cache) { - /* - * Check if there are pending commands. - * and if there are give a warning and - * do not destroy the cache. - */ - if (un->un_ncmds_in_driver > 0) { - scsi_log(SD_DEVINFO(un), - sd_label, CE_WARN, - "Unable to clean up memory " - "because of pending I/O\n"); - } else { - kmem_cache_destroy( - un->un_wm_cache); - un->un_wm_cache = NULL; - } - } } + + } + } + + /* + * Destroy the cache (if it exists) which was + * allocated for the write maps since this is + * the last close for this media. + */ + if (un->un_wm_cache) { + /* + * Check if there are pending commands. + * and if there are give a warning and + * do not destroy the cache. + */ + if (un->un_ncmds_in_driver > 0) { + scsi_log(SD_DEVINFO(un), + sd_label, CE_WARN, + "Unable to clean up memory " + "because of pending I/O\n"); + } else { + kmem_cache_destroy( + un->un_wm_cache); + un->un_wm_cache = NULL; } } @@ -10575,7 +10541,11 @@ sd_ready_and_valid(struct sd_lun *un) ASSERT(!mutex_owned(SD_MUTEX(un))); mutex_enter(SD_MUTEX(un)); - if (ISREMOVABLE(un)) { + /* + * If a device has removable media, we must check if media is + * ready when checking if this device is ready and valid. + */ + if (un->un_f_has_removable_media) { mutex_exit(SD_MUTEX(un)); if (sd_send_scsi_TEST_UNIT_READY(un, 0) != 0) { rval = SD_NOT_READY_VALID; @@ -10603,30 +10573,6 @@ sd_ready_and_valid(struct sd_lun *un) } /* - * If this is a non 512 block device, allocate space for - * the wmap cache. This is being done here since every time - * a media is changed this routine will be called and the - * block size is a function of media rather than device. - */ - if (NOT_DEVBSIZE(un)) { - if (!(un->un_wm_cache)) { - (void) snprintf(name_str, sizeof (name_str), - "%s%d_cache", - ddi_driver_name(SD_DEVINFO(un)), - ddi_get_instance(SD_DEVINFO(un))); - un->un_wm_cache = kmem_cache_create( - name_str, sizeof (struct sd_w_map), - 8, sd_wm_cache_constructor, - sd_wm_cache_destructor, NULL, - (void *)un, NULL, 0); - if (!(un->un_wm_cache)) { - rval = ENOMEM; - goto done; - } - } - } - - /* * Check if the media in the device is writable or not. */ if ((un->un_f_geometry_is_valid == FALSE) && ISCD(un)) { @@ -10644,6 +10590,30 @@ sd_ready_and_valid(struct sd_lun *un) } + /* + * If this is a non 512 block device, allocate space for + * the wmap cache. This is being done here since every time + * a media is changed this routine will be called and the + * block size is a function of media rather than device. + */ + if (un->un_f_non_devbsize_supported && NOT_DEVBSIZE(un)) { + if (!(un->un_wm_cache)) { + (void) snprintf(name_str, sizeof (name_str), + "%s%d_cache", + ddi_driver_name(SD_DEVINFO(un)), + ddi_get_instance(SD_DEVINFO(un))); + un->un_wm_cache = kmem_cache_create( + name_str, sizeof (struct sd_w_map), + 8, sd_wm_cache_constructor, + sd_wm_cache_destructor, NULL, + (void *)un, NULL, 0); + if (!(un->un_wm_cache)) { + rval = ENOMEM; + goto done; + } + } + } + if (un->un_state == SD_STATE_NORMAL) { /* * If the target is not yet ready here (defined by a TUR @@ -10710,11 +10680,11 @@ sd_ready_and_valid(struct sd_lun *un) #endif /* - * If this is a removable media device, try and send - * a PREVENT MEDIA REMOVAL command, but don't get upset + * If this device supports DOOR_LOCK command, try and send + * this command to PREVENT MEDIA REMOVAL, but don't get upset * if it fails. For a CD, however, it is an error */ - if (ISREMOVABLE(un)) { + if (un->un_f_doorlock_supported) { mutex_exit(SD_MUTEX(un)); if ((sd_send_scsi_DOORLOCK(un, SD_REMOVAL_PREVENT, SD_PATH_DIRECT) != 0) && ISCD(un)) { @@ -10736,7 +10706,6 @@ done: * Initialize the capacity kstat value, if no media previously * (capacity kstat is 0) and a media has been inserted * (un_blockcount > 0). - * This is a more generic way then checking for ISREMOVABLE. */ if (un->un_errstats != NULL) { stp = (struct sd_errstats *)un->un_errstats->ks_data; @@ -12095,7 +12064,7 @@ sd_mapblockaddr_iostart(int index, struct sd_lun *un, struct buf *bp) * issue a read() just because it can see TOC on the CD. So * do not print a message for removables. */ - if (!ISREMOVABLE(un)) { + if (!un->un_f_has_removable_media) { scsi_log(SD_DEVINFO(un), sd_label, CE_WARN, "i/o to invalid geometry\n"); } @@ -12988,7 +12957,7 @@ sd_init_cdb_limits(struct sd_lun *un) un->un_mincdb = SD_CDB_GROUP1; #if !defined(__fibre) if (!un->un_f_is_fibre && !un->un_f_cfg_is_atapi && !ISROD(un) && - !ISREMOVABLE(un)) { + !un->un_f_has_removable_media) { un->un_mincdb = SD_CDB_GROUP0; } #endif @@ -12999,9 +12968,11 @@ sd_init_cdb_limits(struct sd_lun *un) * kernel. */ #ifdef _LP64 - un->un_maxcdb = (ISREMOVABLE(un)) ? SD_CDB_GROUP5 : SD_CDB_GROUP4; + un->un_maxcdb = (un->un_f_has_removable_media) ? SD_CDB_GROUP5 : + SD_CDB_GROUP4; #else - un->un_maxcdb = (ISREMOVABLE(un)) ? SD_CDB_GROUP5 : SD_CDB_GROUP1; + un->un_maxcdb = (un->un_f_has_removable_media) ? SD_CDB_GROUP5 : + SD_CDB_GROUP1; #endif /* @@ -15215,6 +15186,14 @@ sd_retry_command(struct sd_lun *un, struct buf *bp, int retry_check_flag, if (user_funcp != NULL) { (*user_funcp)(un, bp, user_arg, SD_IMMEDIATE_RETRY_ISSUED); +#ifdef __lock_lint + sd_print_incomplete_msg(un, bp, user_arg, + SD_IMMEDIATE_RETRY_ISSUED); + sd_print_cmd_incomplete_msg(un, bp, user_arg, + SD_IMMEDIATE_RETRY_ISSUED); + sd_print_sense_failed_msg(un, bp, user_arg, + SD_IMMEDIATE_RETRY_ISSUED); +#endif } SD_TRACE(SD_LOG_IO_CORE | SD_LOG_ERROR, un, @@ -17395,7 +17374,7 @@ sd_sense_key_not_ready(struct sd_lun *un, */ if (xp->xb_retry_count >= un->un_notready_retry_count) { /* Special check for error message printing for removables. */ - if ((ISREMOVABLE(un)) && (asc == 0x04) && + if (un->un_f_has_removable_media && (asc == 0x04) && (ascq >= 0x04)) { si.ssi_severity = SCSI_ERR_ALL; } @@ -17516,7 +17495,7 @@ sd_sense_key_not_ready(struct sd_lun *un, * mainly represent a user-initiated operation * instead of a system failure. */ - if (ISREMOVABLE(un)) { + if (un->un_f_has_removable_media) { si.ssi_severity = SCSI_ERR_ALL; goto fail_command; } @@ -17772,6 +17751,7 @@ sd_sense_key_unit_attention(struct sd_lun *un, * under certain conditions. */ int retry_check_flag = SD_RETRIES_UA; + boolean_t kstat_updated = B_FALSE; struct sd_sense_info si; ASSERT(un != NULL); @@ -17802,7 +17782,7 @@ sd_sense_key_unit_attention(struct sd_lun *un, /* FALLTHRU */ case 0x28: /* NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED */ - if (!ISREMOVABLE(un)) { + if (!un->un_f_has_removable_media) { break; } @@ -17827,6 +17807,15 @@ sd_sense_key_unit_attention(struct sd_lun *un, sd_print_sense_msg(un, bp, &si, SD_NO_RETRY_ISSUED); sd_return_failed_command(un, bp, EIO); } + + /* + * If failed to dispatch sd_media_change_task(), we already + * updated kstat. If succeed to dispatch sd_media_change_task(), + * we should update kstat later if it encounters an error. So, + * we update kstat_updated flag here. + */ + kstat_updated = B_TRUE; + /* * Either the command has been successfully dispatched to a * task Q for retrying, or the dispatch failed. In either case @@ -17841,13 +17830,10 @@ sd_sense_key_unit_attention(struct sd_lun *un, break; } - if (!ISREMOVABLE(un)) { - /* - * Do not update these here for removables. For removables - * these stats are updated (1) above if we failed to dispatch - * sd_media_change_task(), or (2) sd_media_change_task() may - * update these later if it encounters an error. - */ + /* + * Update kstat if we haven't done that. + */ + if (!kstat_updated) { SD_UPDATE_ERRSTATS(un, sd_harderrs); SD_UPDATE_ERRSTATS(un, sd_rq_nodev_err); } @@ -17914,7 +17900,8 @@ sd_sense_key_blank_check(struct sd_lun *un, struct buf *bp, * Blank check is not fatal for removable devices, therefore * it does not require a console message. */ - si.ssi_severity = (ISREMOVABLE(un)) ? SCSI_ERR_ALL : SCSI_ERR_FATAL; + si.ssi_severity = (un->un_f_has_removable_media) ? SCSI_ERR_ALL : + SCSI_ERR_FATAL; si.ssi_pfa_flag = FALSE; sd_print_sense_msg(un, bp, &si, SD_NO_RETRY_ISSUED); @@ -18777,7 +18764,7 @@ sd_media_change_task(void *arg) un = SD_GET_UN(bp); ASSERT(un != NULL); ASSERT(!mutex_owned(SD_MUTEX(un))); - ASSERT(ISREMOVABLE(un)); + ASSERT(un->un_f_monitor_media_state); si.ssi_severity = SCSI_ERR_INFO; si.ssi_pfa_flag = FALSE; @@ -18845,7 +18832,7 @@ sd_handle_mchange(struct sd_lun *un) int rval; ASSERT(!mutex_owned(SD_MUTEX(un))); - ASSERT(ISREMOVABLE(un)); + ASSERT(un->un_f_monitor_media_state); if ((rval = sd_send_scsi_READ_CAPACITY(un, &capacity, &lbasize, SD_PATH_DIRECT_PRIORITY)) != 0) { @@ -19132,7 +19119,8 @@ sd_send_scsi_READ_CAPACITY(struct sd_lun *un, uint64_t *capp, uint32_t *lbap, * On x86, compensate for off-by-1 error (number of sectors on * media) (1175930) */ - if (!ISREMOVABLE(un) && (lbasize == un->un_sys_blocksize)) { + if (!un->un_f_has_removable_media && !un->un_f_is_hotpluggable && + (lbasize == un->un_sys_blocksize)) { capacity -= 1; } #endif @@ -19366,7 +19354,7 @@ sd_send_scsi_START_STOP_UNIT(struct sd_lun *un, int flag, int path_flag) SD_TRACE(SD_LOG_IO, un, "sd_send_scsi_START_STOP_UNIT: entry: un:0x%p\n", un); - if (ISREMOVABLE(un) && + if (un->un_f_check_start_stop && ((flag == SD_TARGET_START) || (flag == SD_TARGET_STOP)) && (un->un_f_start_stop_supported != TRUE)) { return (0); @@ -20070,7 +20058,7 @@ sd_send_scsi_SYNCHRONIZE_CACHE_biodone(struct buf *bp) (sense_buf->es_key == KEY_ILLEGAL_REQUEST)) { /* Ignore Illegal Request error */ mutex_enter(SD_MUTEX(un)); - un->un_f_sync_cache_unsupported = TRUE; + un->un_f_sync_cache_supported = FALSE; mutex_exit(SD_MUTEX(un)); status = ENOTSUP; goto done; @@ -20840,7 +20828,7 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p) case FDEJECT: case DKIOCEJECT: case CDROMEJECT: - if (!ISREMOVABLE(un)) { + if (!un->un_f_eject_media_supported) { un->un_ncmds_in_driver--; ASSERT(un->un_ncmds_in_driver >= 0); mutex_exit(SD_MUTEX(un)); @@ -20863,6 +20851,7 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p) mutex_enter(SD_MUTEX(un)); /* FALLTHROUGH */ case DKIOCREMOVABLE: + case DKIOCHOTPLUGGABLE: case DKIOCINFO: case DKIOCGMEDIAINFO: case MHIOCENFAILFAST: @@ -20913,11 +20902,12 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p) case DKIOCGETEFI: case DKIOCSGEOM: case DKIOCREMOVABLE: + case DKIOCHOTPLUGGABLE: case DKIOCSAPART: case DKIOCSETEFI: break; default: - if (ISREMOVABLE(un)) { + if (un->un_f_has_removable_media) { err = ENXIO; } else { /* Do not map EACCES to EIO */ @@ -21058,7 +21048,28 @@ skip_ready_valid: case DKIOCREMOVABLE: SD_TRACE(SD_LOG_IOCTL, un, "DKIOCREMOVABLE\n"); - if (ISREMOVABLE(un)) { + /* + * At present, vold only does automount for removable-media + * devices, in order not to break current applications, we + * still let hopluggable devices pretend to be removable media + * devices for vold. In the near future, once vold is EOL'ed, + * we should remove this workaround. + */ + if (un->un_f_has_removable_media || un->un_f_is_hotpluggable) { + i = 1; + } else { + i = 0; + } + if (ddi_copyout(&i, (void *)arg, sizeof (int), flag) != 0) { + err = EFAULT; + } else { + err = 0; + } + break; + + case DKIOCHOTPLUGGABLE: + SD_TRACE(SD_LOG_IOCTL, un, "DKIOCHOTPLUGGABLE\n"); + if (un->un_f_is_hotpluggable) { i = 1; } else { i = 0; @@ -21125,7 +21136,7 @@ skip_ready_valid: SD_TRACE(SD_LOG_IOCTL, un, "MHIOCREREGISTERDEVID\n"); if (drv_priv(cred_p) == EPERM) { err = EPERM; - } else if (ISREMOVABLE(un) || ISCD(un)) { + } else if (!un->un_f_devid_supported) { err = ENOTTY; } else { err = sd_mhdioc_register_devid(dev); @@ -21334,7 +21345,7 @@ skip_ready_valid: case DKIOCEJECT: case CDROMEJECT: SD_TRACE(SD_LOG_IOCTL, un, "EJECT\n"); - if (!ISREMOVABLE(un)) { + if (!un->un_f_eject_media_supported) { err = ENOTTY; } else { err = sr_eject(dev); @@ -21744,10 +21755,10 @@ skip_ready_valid: struct dk_callback *dkc = (struct dk_callback *)arg; mutex_enter(SD_MUTEX(un)); - if (un->un_f_sync_cache_unsupported || - ! un->un_f_write_cache_enabled) { - err = un->un_f_sync_cache_unsupported ? - ENOTSUP : 0; + if (!un->un_f_sync_cache_supported || + !un->un_f_write_cache_enabled) { + err = un->un_f_sync_cache_supported ? + 0 : ENOTSUP; mutex_exit(SD_MUTEX(un)); if ((flag & FKIOCTL) && dkc != NULL && dkc->dkc_callback != NULL) { @@ -22908,7 +22919,7 @@ sd_dkio_set_vtoc(dev_t dev, caddr_t arg, int flag) * writing to the disk acyl for the case where a devid has been * fabricated. */ - if (!ISREMOVABLE(un) && !ISCD(un) && + if (un->un_f_devid_supported && (un->un_f_opt_fab_devid == TRUE)) { if (un->un_devid == NULL) { sd_register_devid(un, SD_DEVINFO(un), @@ -23118,7 +23129,7 @@ sd_clear_efi(struct sd_lun *un) */ if ((rval = sd_send_scsi_READ(un, gpt, lbasize, cap - 1, ISCD(un) ? SD_PATH_DIRECT_PRIORITY : - SD_PATH_DIRECT)) != 0) { + SD_PATH_DIRECT)) != 0) { goto done; } sd_swap_efi_gpt(gpt); @@ -23462,11 +23473,7 @@ sd_dkio_get_mboot(dev_t dev, caddr_t arg, int flag) return (ENXIO); } -#if defined(_SUNOS_VTOC_8) - if ((!ISREMOVABLE(un)) || (arg == NULL)) { -#elif defined(_SUNOS_VTOC_16) - if (arg == NULL) { -#endif + if (!un->un_f_mboot_supported || arg == NULL) { return (EINVAL); } @@ -23524,11 +23531,9 @@ sd_dkio_set_mboot(dev_t dev, caddr_t arg, int flag) ASSERT(!mutex_owned(SD_MUTEX(un))); -#if defined(_SUNOS_VTOC_8) - if (!ISREMOVABLE(un)) { + if (!un->un_f_mboot_supported) { return (EINVAL); } -#endif if (arg == NULL) { return (EINVAL); @@ -23572,8 +23577,7 @@ sd_dkio_set_mboot(dev_t dev, caddr_t arg, int flag) * Also preserve the device id by writing to the disk acyl for the case * where a devid has been fabricated. */ - if (!ISREMOVABLE(un) && !ISCD(un) && - (un->un_f_opt_fab_devid == TRUE)) { + if (un->un_f_devid_supported && un->un_f_opt_fab_devid) { if (un->un_devid == NULL) { sd_register_devid(un, SD_DEVINFO(un), SD_TARGET_IS_UNRESERVED); @@ -23592,6 +23596,11 @@ sd_dkio_set_mboot(dev_t dev, caddr_t arg, int flag) } } } + +#ifdef __lock_lint + sd_setup_default_geometry(un); +#endif + #else if (rval == 0) { /* @@ -23749,7 +23758,7 @@ sd_update_fdisk_and_vtoc(struct sd_lun *un) * Only DIRECT ACCESS devices will have Sun labels. * CD's supposedly have a Sun label, too */ - if (SD_INQUIRY(un)->inq_dtype == DTYPE_DIRECT || ISREMOVABLE(un)) { + if (un->un_f_vtoc_label_supported) { fdisk_rval = sd_read_fdisk(un, capacity, lbasize, SD_PATH_DIRECT); if (fdisk_rval == SD_CMD_FAILURE) { @@ -23798,9 +23807,10 @@ sd_update_fdisk_and_vtoc(struct sd_lun *un) } no_solaris_partition: - if ((!ISREMOVABLE(un) || - (ISREMOVABLE(un) && un->un_mediastate == DKIO_EJECTED)) && - (un->un_state == SD_STATE_NORMAL && gvalid == FALSE)) { + if ((!un->un_f_has_removable_media || + (un->un_f_has_removable_media && + un->un_mediastate == DKIO_EJECTED)) && + (un->un_state == SD_STATE_NORMAL && !gvalid)) { /* * Print out a message indicating who and what we are. * We do this only when we happen to really validate the @@ -24056,7 +24066,6 @@ done: * Update the capacity kstat value, if no media previously * (capacity kstat is 0) and a media has been inserted * (un_f_blockcount_is_valid == TRUE) - * This is a more generic way then checking for ISREMOVABLE. */ if (un->un_errstats) { struct sd_errstats *stp = NULL; @@ -30419,3 +30428,534 @@ sd_faultinjection(struct scsi_pkt *pktp) } #endif /* SD_FAULT_INJECTION */ + +/* + * This routine is invoked in sd_unit_attach(). Before calling it, the + * properties in conf file should be processed already, and "hotpluggable" + * property was processed also. + * + * The sd driver distinguishes 3 different type of devices: removable media, + * non-removable media, and hotpluggable. Below the differences are defined: + * + * 1. Device ID + * + * The device ID of a device is used to identify this device. Refer to + * ddi_devid_register(9F). + * + * For a non-removable media disk device which can provide 0x80 or 0x83 + * VPD page (refer to INQUIRY command of SCSI SPC specification), a unique + * device ID is created to identify this device. For other non-removable + * media devices, a default device ID is created only if this device has + * at least 2 alter cylinders. Otherwise, this device has no devid. + * + * ------------------------------------------------------- + * removable media hotpluggable | Can Have Device ID + * ------------------------------------------------------- + * false false | Yes + * false true | Yes + * true x | No + * ------------------------------------------------------ + * + * + * 2. SCSI group 4 commands + * + * In SCSI specs, only some commands in group 4 command set can use + * 8-byte addresses that can be used to access >2TB storage spaces. + * Other commands have no such capability. Without supporting group4, + * it is impossible to make full use of storage spaces of a disk with + * capacity larger than 2TB. + * + * ----------------------------------------------- + * removable media hotpluggable LP64 | Group + * ----------------------------------------------- + * false false false | 1 + * false false true | 4 + * false true false | 1 + * false true true | 4 + * true x x | 5 + * ----------------------------------------------- + * + * + * 3. Check for VTOC Label + * + * If a direct-access disk has no EFI label, sd will check if it has a + * valid VTOC label. Now, sd also does that check for removable media + * and hotpluggable devices. + * + * -------------------------------------------------------------- + * Direct-Access removable media hotpluggable | Check Label + * ------------------------------------------------------------- + * false false false | No + * false false true | No + * false true false | Yes + * false true true | Yes + * true x x | Yes + * -------------------------------------------------------------- + * + * + * 4. Building default VTOC label + * + * As section 3 says, sd checks if some kinds of devices have VTOC label. + * If those devices have no valid VTOC label, sd(7d) will attempt to + * create default VTOC for them. Currently sd creates default VTOC label + * for all devices on x86 platform (VTOC_16), but only for removable + * media devices on SPARC (VTOC_8). + * + * ----------------------------------------------------------- + * removable media hotpluggable platform | Default Label + * ----------------------------------------------------------- + * false false sparc | No + * false true x86 | Yes + * false true sparc | Yes + * true x x | Yes + * ---------------------------------------------------------- + * + * + * 5. Supported blocksizes of target devices + * + * Sd supports non-512-byte blocksize for removable media devices only. + * For other devices, only 512-byte blocksize is supported. This may be + * changed in near future because some RAID devices require non-512-byte + * blocksize + * + * ----------------------------------------------------------- + * removable media hotpluggable | non-512-byte blocksize + * ----------------------------------------------------------- + * false false | No + * false true | No + * true x | Yes + * ----------------------------------------------------------- + * + * + * 6. Automatic mount & unmount (i.e. vold) + * + * Sd(7d) driver provides DKIOCREMOVABLE ioctl. This ioctl is used to query + * if a device is removable media device. It return 1 for removable media + * devices, and 0 for others. + * + * Vold treats a device as removable one only if DKIOREMOVABLE returns 1. + * And it does automounting only for removable media devices. In order to + * preserve users' experience and let vold continue to do automounting for + * USB disk devices, DKIOCREMOVABLE ioctl still returns 1 for USB/1394 disk + * devices. + * + * ------------------------------------------------------ + * removable media hotpluggable | automatic mount + * ------------------------------------------------------ + * false false | No + * false true | Yes + * true x | Yes + * ------------------------------------------------------ + * + * + * 7. fdisk partition management + * + * Fdisk is traditional partition method on x86 platform. Sd(7d) driver + * just supports fdisk partitions on x86 platform. On sparc platform, sd + * doesn't support fdisk partitions at all. Note: pcfs(7fs) can recognize + * fdisk partitions on both x86 and SPARC platform. + * + * ----------------------------------------------------------- + * platform removable media USB/1394 | fdisk supported + * ----------------------------------------------------------- + * x86 X X | true + * ------------------------------------------------------------ + * sparc X X | false + * ------------------------------------------------------------ + * + * + * 8. MBOOT/MBR + * + * Although sd(7d) doesn't support fdisk on SPARC platform, it does support + * read/write mboot for removable media devices on sparc platform. + * + * ----------------------------------------------------------- + * platform removable media USB/1394 | mboot supported + * ----------------------------------------------------------- + * x86 X X | true + * ------------------------------------------------------------ + * sparc false false | false + * sparc false true | true + * sparc true false | true + * sparc true true | true + * ------------------------------------------------------------ + * + * + * 9. error handling during opening device + * + * If failed to open a disk device, an errno is returned. For some kinds + * of errors, different errno is returned depending on if this device is + * a removable media device. This brings USB/1394 hard disks in line with + * expected hard disk behavior. It is not expected that this breaks any + * application. + * + * ------------------------------------------------------ + * removable media hotpluggable | errno + * ------------------------------------------------------ + * false false | EIO + * false true | EIO + * true x | ENXIO + * ------------------------------------------------------ + * + * + * 10. off-by-1 workaround (bug 1175930, and 4996920) (x86 only) + * + * [ this is a bit of very ugly history, soon to be removed ] + * + * SCSI READ_CAPACITY command returns the last valid logical block number + * which starts from 0. So real capacity is larger than the returned + * value by 1. However, because scdk.c (which was EOL'ed) directly used + * the logical block number as capacity of disk devices, off-by-1 work- + * around was applied. This workaround causes fixed SCSI disk to loss a + * sector on x86 platform, and precludes exchanging fixed hard disks + * between sparc and x86. + * + * ------------------------------------------------------ + * removable media hotplug | Off-by-1 works + * ------------------------------------------------------- + * false false | Yes + * false true | No + * true false | No + * true true | No + * ------------------------------------------------------ + * + * + * 11. ioctls: DKIOCEJECT, CDROMEJECT + * + * These IOCTLs are applicable only to removable media devices. + * + * ----------------------------------------------------------- + * removable media hotpluggable |DKIOCEJECT, CDROMEJECT + * ----------------------------------------------------------- + * false false | No + * false true | No + * true x | Yes + * ----------------------------------------------------------- + * + * + * 12. Kstats for partitions + * + * sd creates partition kstat for non-removable media devices. USB and + * Firewire hard disks now have partition kstats + * + * ------------------------------------------------------ + * removable media hotplugable | kstat + * ------------------------------------------------------ + * false false | Yes + * false true | Yes + * true x | No + * ------------------------------------------------------ + * + * + * 13. Removable media & hotpluggable properties + * + * Sd driver creates a "removable-media" property for removable media + * devices. Parent nexus drivers create a "hotpluggable" property if + * it supports hotplugging. + * + * --------------------------------------------------------------------- + * removable media hotpluggable | "removable-media" " hotpluggable" + * --------------------------------------------------------------------- + * false false | No No + * false true | No Yes + * true false | Yes No + * true true | Yes Yes + * --------------------------------------------------------------------- + * + * + * 14. Power Management + * + * sd only power manages removable media devices or devices that support + * LOG_SENSE or have a "pm-capable" property (PSARC/2002/250) + * + * A parent nexus that supports hotplugging can also set "pm-capable" + * if the disk can be power managed. + * + * ------------------------------------------------------------ + * removable media hotpluggable pm-capable | power manage + * ------------------------------------------------------------ + * false false false | No + * false false true | Yes + * false true false | No + * false true true | Yes + * true x x | Yes + * ------------------------------------------------------------ + * + * USB and firewire hard disks can now be power managed independently + * of the framebuffer + * + * + * 15. Support for USB disks with capacity larger than 1TB + * + * Currently, sd doesn't permit a fixed disk device with capacity + * larger than 1TB to be used in a 32-bit operating system environment. + * However, sd doesn't do that for removable media devices. Instead, it + * assumes that removable media devices cannot have a capacity larger + * than 1TB. Therefore, using those devices on 32-bit system is partially + * supported, which can cause some unexpected results. + * + * --------------------------------------------------------------------- + * removable media USB/1394 | Capacity > 1TB | Used in 32-bit env + * --------------------------------------------------------------------- + * false false | true | no + * false true | true | no + * true false | true | Yes + * true true | true | Yes + * --------------------------------------------------------------------- + * + * + * 16. Check write-protection at open time + * + * When a removable media device is being opened for writing without NDELAY + * flag, sd will check if this device is writable. If attempting to open + * without NDELAY flag a write-protected device, this operation will abort. + * + * ------------------------------------------------------------ + * removable media USB/1394 | WP Check + * ------------------------------------------------------------ + * false false | No + * false true | No + * true false | Yes + * true true | Yes + * ------------------------------------------------------------ + * + * + * 17. syslog when corrupted VTOC is encountered + * + * Currently, if an invalid VTOC is encountered, sd only print syslog + * for fixed SCSI disks. + * ------------------------------------------------------------ + * removable media USB/1394 | print syslog + * ------------------------------------------------------------ + * false false | Yes + * false true | No + * true false | No + * true true | No + * ------------------------------------------------------------ + */ +static void +sd_set_unit_attributes(struct sd_lun *un, dev_info_t *devi) +{ + int pm_capable_prop; + + ASSERT(un->un_sd); + ASSERT(un->un_sd->sd_inq); + +#if defined(_SUNOS_VTOC_16) + /* + * For VTOC_16 devices, the default label will be created for all + * devices. (see sd_build_default_label) + */ + un->un_f_default_vtoc_supported = TRUE; +#endif + + if (un->un_sd->sd_inq->inq_rmb) { + /* + * The media of this device is removable. And for this kind + * of devices, it is possible to change medium after openning + * devices. Thus we should support this operation. + */ + un->un_f_has_removable_media = TRUE; + +#if defined(_SUNOS_VTOC_8) + /* + * Note: currently, for VTOC_8 devices, default label is + * created for removable and hotpluggable devices only. + */ + un->un_f_default_vtoc_supported = TRUE; +#endif + /* + * support non-512-byte blocksize of removable media devices + */ + un->un_f_non_devbsize_supported = TRUE; + + /* + * Assume that all removable media devices support DOOR_LOCK + */ + un->un_f_doorlock_supported = TRUE; + + /* + * For a removable media device, it is possible to be opened + * with NDELAY flag when there is no media in drive, in this + * case we don't care if device is writable. But if without + * NDELAY flag, we need to check if media is write-protected. + */ + un->un_f_chk_wp_open = TRUE; + + /* + * need to start a SCSI watch thread to monitor media state, + * when media is being inserted or ejected, notify syseventd. + */ + un->un_f_monitor_media_state = TRUE; + + /* + * Some devices don't support START_STOP_UNIT command. + * Therefore, we'd better check if a device supports it + * before sending it. + */ + un->un_f_check_start_stop = TRUE; + + /* + * support eject media ioctl: + * FDEJECT, DKIOCEJECT, CDROMEJECT + */ + un->un_f_eject_media_supported = TRUE; + + /* + * Because many removable-media devices don't support + * LOG_SENSE, we couldn't use this command to check if + * a removable media device support power-management. + * We assume that they support power-management via + * START_STOP_UNIT command and can be spun up and down + * without limitations. + */ + un->un_f_pm_supported = TRUE; + + /* + * Need to create a zero length (Boolean) property + * removable-media for the removable media devices. + * Note that the return value of the property is not being + * checked, since if unable to create the property + * then do not want the attach to fail altogether. Consistent + * with other property creation in attach. + */ + (void) ddi_prop_create(DDI_DEV_T_NONE, devi, + DDI_PROP_CANSLEEP, "removable-media", NULL, 0); + + } else { + /* + * create device ID for device + */ + un->un_f_devid_supported = TRUE; + + /* + * Spin up non-removable-media devices once it is attached + */ + un->un_f_attach_spinup = TRUE; + + /* + * According to SCSI specification, Sense data has two kinds of + * format: fixed format, and descriptor format. At present, we + * don't support descriptor format sense data for removable + * media. + */ + if (SD_INQUIRY(un)->inq_dtype == DTYPE_DIRECT) { + un->un_f_descr_format_supported = TRUE; + } + + /* + * kstats are created only for non-removable media devices. + * + * Set this in sd.conf to 0 in order to disable kstats. The + * default is 1, so they are enabled by default. + */ + un->un_f_pkstats_enabled = (ddi_prop_get_int(DDI_DEV_T_ANY, + SD_DEVINFO(un), DDI_PROP_DONTPASS, + "enable-partition-kstats", 1)); + + /* + * Check if HBA has set the "pm-capable" property. + * If "pm-capable" exists and is non-zero then we can + * power manage the device without checking the start/stop + * cycle count log sense page. + * + * If "pm-capable" exists and is SD_PM_CAPABLE_FALSE (0) + * then we should not power manage the device. + * + * If "pm-capable" doesn't exist then pm_capable_prop will + * be set to SD_PM_CAPABLE_UNDEFINED (-1). In this case, + * sd will check the start/stop cycle count log sense page + * and power manage the device if the cycle count limit has + * not been exceeded. + */ + pm_capable_prop = ddi_prop_get_int(DDI_DEV_T_ANY, devi, + DDI_PROP_DONTPASS, "pm-capable", SD_PM_CAPABLE_UNDEFINED); + if (pm_capable_prop == SD_PM_CAPABLE_UNDEFINED) { + un->un_f_log_sense_supported = TRUE; + } else { + /* + * pm-capable property exists. + * + * Convert "TRUE" values for pm_capable_prop to + * SD_PM_CAPABLE_TRUE (1) to make it easier to check + * later. "TRUE" values are any values except + * SD_PM_CAPABLE_FALSE (0) and + * SD_PM_CAPABLE_UNDEFINED (-1) + */ + if (pm_capable_prop == SD_PM_CAPABLE_FALSE) { + un->un_f_log_sense_supported = FALSE; + } else { + un->un_f_pm_supported = TRUE; + } + + SD_INFO(SD_LOG_ATTACH_DETACH, un, + "sd_unit_attach: un:0x%p pm-capable " + "property set to %d.\n", un, un->un_f_pm_supported); + } + } + + if (un->un_f_is_hotpluggable) { +#if defined(_SUNOS_VTOC_8) + /* + * Note: currently, for VTOC_8 devices, default label is + * created for removable and hotpluggable devices only. + */ + un->un_f_default_vtoc_supported = TRUE; +#endif + + /* + * Temporarily, let hotpluggable devices pretend to be + * removable-media devices for vold. + */ + un->un_f_monitor_media_state = TRUE; + + un->un_f_check_start_stop = TRUE; + + } + + /* + * By default, only DIRECT ACCESS devices and CDs will have Sun + * labels. + */ + if ((SD_INQUIRY(un)->inq_dtype == DTYPE_DIRECT) || + (un->un_sd->sd_inq->inq_rmb)) { + /* + * Direct access devices have disk label + */ + un->un_f_vtoc_label_supported = TRUE; + } + + /* + * Fdisk partitions are supported for all direct access devices on + * x86 platform, and just for removable media and hotpluggable + * devices on SPARC platform. Later, we will set the following flag + * to FALSE if current device is not removable media or hotpluggable + * device and if sd works on SAPRC platform. + */ + if (SD_INQUIRY(un)->inq_dtype == DTYPE_DIRECT) { + un->un_f_mboot_supported = TRUE; + } + + if (!un->un_f_is_hotpluggable && + !un->un_sd->sd_inq->inq_rmb) { + +#if defined(_SUNOS_VTOC_8) + /* + * Don't support fdisk on fixed disk + */ + un->un_f_mboot_supported = FALSE; +#endif + + /* + * Fixed disk support SYNC CACHE + */ + un->un_f_sync_cache_supported = TRUE; + + /* + * For fixed disk, if its VTOC is not valid, we will write + * errlog into system log + */ + if (un->un_f_vtoc_label_supported) + un->un_f_vtoc_errlog_supported = TRUE; + } +} diff --git a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c index b9f420ea7c..e0091a80df 100644 --- a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c +++ b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1386,16 +1386,16 @@ scsa2usb_override(scsa2usb_state_t *scsa2usbp) scsa2usbp->scsa2usb_log_handle, "vid=0x%x pid=0x%x rev=0x%x subclass=0x%x " "protocol=0x%x " - "pmoff=%d not_removable=%d modesense=%d " + "pmoff=%d fake_removable=%d modesense=%d " "reduced-cmd-support=%d", ov.vid, ov.pid, ov.rev, ov.subclass, ov.protocol, - ov.pmoff, ov.not_removable, ov.no_modesense, + ov.pmoff, ov.fake_removable, ov.no_modesense, ov.reduced_cmd_support); if (ov.pmoff) { scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_PM; } - if (ov.not_removable) { + if (ov.fake_removable) { scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_RMB; } @@ -1509,8 +1509,8 @@ scsa2usb_parse_input_str(char *str, scsa2usb_ov_t *ovp, return (USB_FAILURE); } } else if (strcasecmp(input_field, "removable") == 0) { - if (strcasecmp(input_value, "false") == 0) { - ovp->not_removable = 1; + if (strcasecmp(input_value, "true") == 0) { + ovp->fake_removable = 1; break; } else { scsa2usb_override_error("removable", scsa2usbp); @@ -1774,6 +1774,32 @@ scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp) continue; } + rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, + "hotpluggable"); + if (rval != DDI_PROP_SUCCESS) { + USB_DPRINTF_L2(DPRINT_MASK_SCSA, + scsa2usbp->scsa2usb_log_handle, + "ndi_prop_create_boolean hotpluggable failed %d", + rval); + ddi_prop_remove_all(cdip); + (void) ndi_devi_free(cdip); + continue; + } + /* + * Some devices don't support LOG SENSE, so tells + * sd driver not to send this command. + */ + rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, + "pm-capable", 1); + if (rval != DDI_PROP_SUCCESS) { + USB_DPRINTF_L2(DPRINT_MASK_SCSA, + scsa2usbp->scsa2usb_log_handle, + "ndi_prop_update_int pm-capable failed %d", rval); + ddi_prop_remove_all(cdip); + (void) ndi_devi_free(cdip); + continue; + } + rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", lun); if (rval != DDI_PROP_SUCCESS) { USB_DPRINTF_L2(DPRINT_MASK_SCSA, @@ -2099,7 +2125,7 @@ scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void)) scsi_hba_tran_t *tran; scsa2usb_state_t *scsa2usbp; dev_info_t *dip = ddi_get_parent(sd->sd_dev); - int rval; + int rval; ASSERT(dip); @@ -2125,11 +2151,11 @@ scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void)) if ((rval = scsi_hba_probe(sd, waitfunc)) == SCSIPROBE_EXISTS) { /* - * fake the removable bit on all USB storage devices + * respect the removable bit on all USB storage devices * unless overridden by a scsa2usb.conf entry */ mutex_enter(&scsa2usbp->scsa2usb_mutex); - if (scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB) { + if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB)) { _NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry)) sd->sd_inq->inq_rmb = 1; } diff --git a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf index 61c4716e94..cb98a2a1dc 100644 --- a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf +++ b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf @@ -19,7 +19,7 @@ # # CDDL HEADER END # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -42,7 +42,7 @@ # # A record in this file has the following format:- # "vid=vId pid=pId rev=revision subclass=override protocol=override pm=pmvalue -# removable=remvalue modesense=modesensevalue" +# removable=remvalue modesense=modesensevalue" # # where: # vId/pId/revision: are obtained from @@ -85,32 +85,35 @@ # will not respond after having their power lowered. # If this is the case, the device should have power # management disabled by setting this to "off". -# -# remvalue - "false" if the device's removable media information -# in its hardware inquiry data is not to be ignored. This -# is the only legal value for this parameter. There is a -# removable media status bit in the USB storage device's -# inquiry data to indicate if the device has a media that -# can be removed. Usually only devices like floppy drives +# +# remvalue - "true" if the device's removable media information +# in its hardware inquiry data is to be overridden. This +# is the only legal value for this parameter. +# +# NOTE: In previous releases, the removable media information +# was always overridden and the only legal value was "false". +# +# There is a removable media status bit in the USB storage +# device's inquiry data to indicate if the device has a media +# that can be removed. Usually only devices like floppy drives # or CD/DVD drives that really have a removable media can # have this bit set and be called removable media devices. -# Solaris treats removable media devices and non- -# removable media devices differently. Refer to "System -# Administration Guide: Devices and File Systems" - -# "Using USB Devices (Tasks)" - "Using USB Mass Storage -# Devices" section for the differences in system behavior -# of treating removable media devices and non-removable -# media devices. -# -# By default, Solaris will treat all USB storage devices -# as removable media devices irrespective of the removable -# media bit value. The advantage is a consistent user -# experience. In some cases this may be undesirable and -# the removable media bit value should not be ignored. By -# setting "remvalue" to "false", the information provided -# by the device is preserved. Consequently a USB hard disk -# is treated as a real hard disk and will show in -# format(1M) disk list and no longer in rmformat(1M) list. +# Solaris treats removable media devices and non-removable +# media devices differently. Refer to "System Administration +# Guide: Devices and File Systems" - "Using USB Devices +# (Tasks)" - "Using USB Mass Storage Devices" section for +# the differences in system behavior of treating removable +# media devices and non-removable media devices. +# +# By default, Solaris will treat USB storage devices as +# removable media devices depending on the removable media +# bit value. In some cases this may be undesirable and the +# behavior of the previous releases should be preserved. In +# this case the removable media bit value should be overridden. +# By setting "remvalue" to "true", the information provided +# by the device is ignored. Consequently a USB hard disk +# is treated as a removable media disk and will not show in +# format(1M) disk list. # # modesensevalue - "false" if the device cannot handle mode sense # requests. This is the only legal value for this diff --git a/usr/src/uts/common/sys/dkio.h b/usr/src/uts/common/sys/dkio.h index b3de6726c8..4bd2ca0f99 100644 --- a/usr/src/uts/common/sys/dkio.h +++ b/usr/src/uts/common/sys/dkio.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -212,6 +212,12 @@ struct dk_callback { #define DKIOCSTATE (DKIOC|13) /* Inquire insert/eject state */ #define DKIOCREMOVABLE (DKIOC|16) /* is media removable */ + +/* + * ioctl for hotpluggable devices + */ +#define DKIOCHOTPLUGGABLE (DKIOC|35) /* is hotpluggable */ + /* * Ioctl to force driver to re-read the alternate partition and rebuild * the internal defect map. diff --git a/usr/src/uts/common/sys/scsi/targets/sddef.h b/usr/src/uts/common/sys/scsi/targets/sddef.h index 3b2a45b099..17123c3b72 100644 --- a/usr/src/uts/common/sys/scsi/targets/sddef.h +++ b/usr/src/uts/common/sys/scsi/targets/sddef.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -422,7 +422,7 @@ struct sd_lun { /* a part of error recovery. */ un_f_is_fibre :1, /* The device supports fibre */ /* channel */ - un_f_sync_cache_unsupported :1, /* sync cache cmd not */ + un_f_sync_cache_supported :1, /* sync cache cmd supported */ /* supported */ un_f_format_in_progress :1, /* The device is currently */ /* executing a FORMAT cmd. */ @@ -462,6 +462,34 @@ struct sd_lun { un_f_doorlock_supported :1, /* Device supports Doorlock */ un_f_start_stop_supported :1; /* device has motor */ + uint32_t + un_f_vtoc_label_supported :1, /* have vtoc disk label */ + un_f_vtoc_errlog_supported :1, /* write error in system */ + /* log if VTOC is not valid */ + un_f_default_vtoc_supported :1, /* build default */ + /* label if disk has */ + /* no valid one */ + un_f_mboot_supported :1, /* mboot supported */ + un_f_is_hotpluggable :1, /* hotpluggable */ + un_f_has_removable_media :1, /* has removable media */ + un_f_non_devbsize_supported :1, /* non-512 blocksize */ + un_f_devid_supported :1, /* device ID supported */ + un_f_eject_media_supported :1, /* media can be ejected */ + un_f_chk_wp_open :1, /* check if write-protected */ + /* when being opened */ + un_f_descr_format_supported :1, /* support descriptor format */ + /* for sense data */ + un_f_check_start_stop :1, /* needs to check if */ + /* START-STOP command is */ + /* supported by hardware */ + /* before issuing it */ + un_f_monitor_media_state :1, /* need a watch thread to */ + /* monitor device state */ + un_f_attach_spinup :1, /* spin up once the */ + /* device is attached */ + un_f_log_sense_supported :1, /* support log sense */ + un_f_pm_supported :1, /* support power-management */ + un_f_reserved :16; /* Ptr to table of strings for ASC/ASCQ error message printing */ struct scsi_asq_key_strings *un_additional_codes; @@ -485,7 +513,6 @@ struct sd_lun { timeout_id_t un_pm_timeid; /* timeout id for pm */ uint_t un_pm_busy; kcondvar_t un_pm_busy_cv; - int un_pm_capable_prop; /* "pm-capable" prop value */ short un_power_level; /* Power Level */ uchar_t un_save_state; kcondvar_t un_suspend_cv; /* power management */ @@ -620,35 +647,18 @@ struct sd_lun { #endif #define SD_MAX_XFER_SIZE (1024 * 1024) - -#if defined(__i386) || defined(__amd64) -#ifndef _lock_lint -#undef _NOTE -#define _NOTE(s) -#endif -#endif - - /* * Warlock annotations */ - _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, sd_lun)) _NOTE(READ_ONLY_DATA(sd_lun::un_sd)) _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_reservation_type)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_pm_capable_prop)) _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_mincdb)) _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_maxcdb)) _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_status_len)) - - -#if defined(__i386) || defined(__amd64) -_NOTE(READ_ONLY_DATA(sd_lun::un_f_arq_enabled)) -#else _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_f_arq_enabled)) -#endif - _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_ctype)) +_NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_solaris_offset)) _NOTE(SCHEME_PROTECTS_DATA("safe sharing", sd_lun::un_mhd_token @@ -743,7 +753,6 @@ _NOTE(MUTEX_PROTECTS_DATA(sd_lun::un_fi_mutex, #define ISCD(un) ((un)->un_ctype == CTYPE_CDROM) #define ISROD(un) ((un)->un_ctype == CTYPE_ROD) #define ISPXRE(un) ((un)->un_ctype == CTYPE_PXRE) -#define ISREMOVABLE(un) (ISCD(un) || (un)->un_sd->sd_inq->inq_rmb) /* * This macro checks the vendor of the device to see if it is LSI. Because @@ -769,7 +778,7 @@ _NOTE(MUTEX_PROTECTS_DATA(sd_lun::un_fi_mutex, * Macros for non-512 byte writes to removable devices. */ #define NOT_DEVBSIZE(un) \ - (ISREMOVABLE(un) && ((un)->un_tgt_blocksize != (un)->un_sys_blocksize)) + ((un)->un_tgt_blocksize != (un)->un_sys_blocksize) /* * Check that a write map, used for locking lba ranges for writes, is in diff --git a/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h b/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h index c3ed27e5bb..82f700d18c 100644 --- a/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h +++ b/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h @@ -19,7 +19,7 @@ * * CDDL HEADER END * - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -193,7 +193,7 @@ typedef struct scsa2usb_ov { int subclass; /* subclass override */ int protocol; /* protocol override */ int pmoff; /* power management override */ - int not_removable; /* removable device override */ + int fake_removable; /* removable device override */ int no_modesense; /* no mode sense */ /* no modesense, doorlock, PM, start/stop */ int reduced_cmd_support; |
