Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137014016
D13360.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D13360.id.diff
View Options
Index: head/sys/cam/scsi/scsi_da.c
===================================================================
--- head/sys/cam/scsi/scsi_da.c
+++ head/sys/cam/scsi/scsi_da.c
@@ -81,6 +81,7 @@
* ATA -> LOGDIR -> IDDIR -> SUP -> ATA_ZONE
*/
typedef enum {
+ DA_STATE_PROBE_WP,
DA_STATE_PROBE_RC,
DA_STATE_PROBE_RC16,
DA_STATE_PROBE_LBP,
@@ -157,6 +158,7 @@
DA_CCB_PROBE_ATA_IDDIR = 0x0F,
DA_CCB_PROBE_ATA_SUP = 0x10,
DA_CCB_PROBE_ATA_ZONE = 0x11,
+ DA_CCB_PROBE_WP = 0x12,
DA_CCB_TYPE_MASK = 0x1F,
DA_CCB_RETRY_UA = 0x20
} da_ccb_state;
@@ -2427,7 +2429,7 @@
}
LIST_INIT(&softc->pending_ccbs);
- softc->state = DA_STATE_PROBE_RC;
+ softc->state = DA_STATE_PROBE_WP;
bioq_init(&softc->delete_run_queue);
if (SID_IS_REMOVABLE(&cgd->inq_data))
softc->flags |= DA_FLAG_PACK_REMOVABLE;
@@ -2526,7 +2528,6 @@
if (SID_ANSI_REV(&cgd->inq_data) >= SCSI_REV_SPC3 &&
(softc->quirks & DA_Q_NO_RC16) == 0) {
softc->flags |= DA_FLAG_CAN_RC16;
- softc->state = DA_STATE_PROBE_RC16;
}
/*
@@ -3095,6 +3096,36 @@
daschedule(periph);
break;
}
+ case DA_STATE_PROBE_WP:
+ {
+ void *mode_buf;
+ int mode_buf_len;
+
+ mode_buf_len = 192;
+ mode_buf = malloc(mode_buf_len, M_SCSIDA, M_NOWAIT);
+ if (mode_buf == NULL) {
+ xpt_print(periph->path, "Unable to send mode sense - "
+ "malloc failure\n");
+ softc->state = DA_STATE_PROBE_RC;
+ goto skipstate;
+ }
+ scsi_mode_sense_len(&start_ccb->csio,
+ /*retries*/ da_retry_count,
+ /*cbfcnp*/ dadone,
+ /*tag_action*/ MSG_SIMPLE_Q_TAG,
+ /*dbd*/ FALSE,
+ /*pc*/ SMS_PAGE_CTRL_CURRENT,
+ /*page*/ SMS_ALL_PAGES_PAGE,
+ /*param_buf*/ mode_buf,
+ /*param_len*/ mode_buf_len,
+ /*minimum_cmd_size*/ softc->minimum_cmd_size,
+ /*sense_len*/ SSD_FULL_SIZE,
+ /*timeout*/ da_default_timeout * 1000);
+ start_ccb->ccb_h.ccb_bp = NULL;
+ start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_WP;
+ xpt_action(start_ccb);
+ break;
+ }
case DA_STATE_PROBE_RC:
{
struct scsi_read_capacity_data *rcap;
@@ -4255,6 +4286,52 @@
biodone(bp);
return;
}
+ case DA_CCB_PROBE_WP:
+ {
+ struct scsi_mode_header_6 *mode_hdr6;
+ struct scsi_mode_header_10 *mode_hdr10;
+ uint8_t dev_spec;
+
+ if (softc->minimum_cmd_size > 6) {
+ mode_hdr10 = (struct scsi_mode_header_10 *)csio->data_ptr;
+ dev_spec = mode_hdr10->dev_spec;
+ } else {
+ mode_hdr6 = (struct scsi_mode_header_6 *)csio->data_ptr;
+ dev_spec = mode_hdr6->dev_spec;
+ }
+ if (cam_ccb_status(done_ccb) == CAM_REQ_CMP) {
+ if ((dev_spec & 0x80) != 0)
+ softc->disk->d_flags |= DISKFLAG_WRITE_PROTECT;
+ else
+ softc->disk->d_flags &= ~DISKFLAG_WRITE_PROTECT;
+ } else {
+ int error;
+
+ error = daerror(done_ccb, CAM_RETRY_SELTO,
+ SF_RETRY_UA|SF_NO_PRINT);
+ if (error == ERESTART)
+ return;
+ else if (error != 0) {
+ if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+ /* Don't wedge this device's queue */
+ cam_release_devq(done_ccb->ccb_h.path,
+ /*relsim_flags*/0,
+ /*reduction*/0,
+ /*timeout*/0,
+ /*getcount_only*/0);
+ }
+ }
+ }
+
+ free(csio->data_ptr, M_SCSIDA);
+ xpt_release_ccb(done_ccb);
+ if ((softc->flags & DA_FLAG_CAN_RC16) != 0)
+ softc->state = DA_STATE_PROBE_RC16;
+ else
+ softc->state = DA_STATE_PROBE_RC;
+ xpt_schedule(periph, priority);
+ return;
+ }
case DA_CCB_PROBE_RC:
case DA_CCB_PROBE_RC16:
{
@@ -5340,11 +5417,7 @@
KASSERT(status == CAM_REQ_CMP,
("dareprobe: cam_periph_acquire failed"));
- if (softc->flags & DA_FLAG_CAN_RC16)
- softc->state = DA_STATE_PROBE_RC16;
- else
- softc->state = DA_STATE_PROBE_RC;
-
+ softc->state = DA_STATE_PROBE_WP;
xpt_schedule(periph, CAM_PRIORITY_DEV);
}
Index: head/sys/geom/geom_disk.h
===================================================================
--- head/sys/geom/geom_disk.h
+++ head/sys/geom/geom_disk.h
@@ -126,13 +126,14 @@
LIST_HEAD(,disk_alias) d_aliases;
};
-#define DISKFLAG_RESERVED 0x1 /* Was NEEDSGIANT */
-#define DISKFLAG_OPEN 0x2
-#define DISKFLAG_CANDELETE 0x4
-#define DISKFLAG_CANFLUSHCACHE 0x8
-#define DISKFLAG_UNMAPPED_BIO 0x10
-#define DISKFLAG_DIRECT_COMPLETION 0x20
-#define DISKFLAG_CANZONE 0x80
+#define DISKFLAG_RESERVED 0x0001 /* Was NEEDSGIANT */
+#define DISKFLAG_OPEN 0x0002
+#define DISKFLAG_CANDELETE 0x0004
+#define DISKFLAG_CANFLUSHCACHE 0x0008
+#define DISKFLAG_UNMAPPED_BIO 0x0010
+#define DISKFLAG_DIRECT_COMPLETION 0x0020
+#define DISKFLAG_CANZONE 0x0080
+#define DISKFLAG_WRITE_PROTECT 0x0100
struct disk *disk_alloc(void);
void disk_create(struct disk *disk, int version);
Index: head/sys/geom/geom_disk.c
===================================================================
--- head/sys/geom/geom_disk.c
+++ head/sys/geom/geom_disk.c
@@ -122,14 +122,18 @@
e += pp->ace;
error = 0;
if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
- if (dp->d_open != NULL) {
+ /*
+ * It would be better to defer this decision to d_open if
+ * it was able to take flags.
+ */
+ if (w > 0 && (dp->d_flags & DISKFLAG_WRITE_PROTECT) != 0)
+ error = EROFS;
+ if (error == 0 && dp->d_open != NULL)
error = dp->d_open(dp);
- if (bootverbose && error != 0)
- printf("Opened disk %s -> %d\n",
- pp->name, error);
- if (error != 0)
- return (error);
- }
+ if (bootverbose && error != 0)
+ printf("Opened disk %s -> %d\n", pp->name, error);
+ if (error != 0)
+ return (error);
pp->sectorsize = dp->d_sectorsize;
if (dp->d_maxsize == 0) {
printf("WARNING: Disk drive %s%d has no d_maxsize\n",
@@ -1043,7 +1047,8 @@
"\4CANFLUSHCACHE"
"\5UNMAPPEDBIO"
"\6DIRECTCOMPLETION"
- "\10CANZONE");
+ "\10CANZONE"
+ "\11WRITEPROTECT");
sbuf_finish(sb);
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 21, 11:52 PM (11 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25829610
Default Alt Text
D13360.id.diff (5 KB)
Attached To
Mode
D13360: geom_disk / scsi_da: deny opening write-protected disks for writing
Attached
Detach File
Event Timeline
Log In to Comment