svn commit: r251477 - in stable/8/sys/cam: . scsi
Steven Hartland
smh at FreeBSD.org
Thu Jun 6 22:31:54 UTC 2013
Author: smh
Date: Thu Jun 6 22:31:52 2013
New Revision: 251477
URL: http://svnweb.freebsd.org/changeset/base/251477
Log:
MFC r216088:
Manual partial MFC of only basic VPD support for scsi_xpt
MFC r249937:
Refactored scsi_xpt use of device_has_vpd
Modified:
stable/8/sys/cam/cam_xpt.c
stable/8/sys/cam/cam_xpt_internal.h
stable/8/sys/cam/scsi/scsi_all.c
stable/8/sys/cam/scsi/scsi_all.h
stable/8/sys/cam/scsi/scsi_xpt.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/cam/ (props changed)
Modified: stable/8/sys/cam/cam_xpt.c
==============================================================================
--- stable/8/sys/cam/cam_xpt.c Thu Jun 6 22:02:03 2013 (r251476)
+++ stable/8/sys/cam/cam_xpt.c Thu Jun 6 22:31:52 2013 (r251477)
@@ -4497,7 +4497,7 @@ xpt_alloc_device(struct cam_eb *bus, str
device = NULL;
} else {
device = (struct cam_ed *)malloc(sizeof(*device),
- M_CAMXPT, M_NOWAIT);
+ M_CAMXPT, M_NOWAIT|M_ZERO);
}
if (device != NULL) {
@@ -4568,6 +4568,14 @@ xpt_release_device(struct cam_ed *device
cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
camq_fini(&device->drvq);
cam_ccbq_fini(&device->ccbq);
+ /*
+ * Free allocated memory. free(9) does nothing if the
+ * supplied pointer is NULL, so it is safe to call without
+ * checking.
+ */
+ free(device->supported_vpds, M_CAMXPT);
+ free(device->serial_num, M_CAMXPT);
+
xpt_release_target(device->target);
free(device, M_CAMXPT);
} else
Modified: stable/8/sys/cam/cam_xpt_internal.h
==============================================================================
--- stable/8/sys/cam/cam_xpt_internal.h Thu Jun 6 22:02:03 2013 (r251476)
+++ stable/8/sys/cam/cam_xpt_internal.h Thu Jun 6 22:31:52 2013 (r251477)
@@ -93,6 +93,8 @@ struct cam_ed {
cam_xport transport;
u_int transport_version;
struct scsi_inquiry_data inq_data;
+ uint8_t *supported_vpds;
+ uint8_t supported_vpds_len;
struct ata_params ident_data;
u_int8_t inq_flags; /*
* Current settings for inquiry flags.
Modified: stable/8/sys/cam/scsi/scsi_all.c
==============================================================================
--- stable/8/sys/cam/scsi/scsi_all.c Thu Jun 6 22:02:03 2013 (r251476)
+++ stable/8/sys/cam/scsi/scsi_all.c Thu Jun 6 22:31:52 2013 (r251477)
@@ -38,6 +38,9 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/libkern.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
#include <sys/sysctl.h>
#else
#include <errno.h>
@@ -53,7 +56,13 @@ __FBSDID("$FreeBSD$");
#include <cam/scsi/scsi_all.h>
#include <sys/ata.h>
#include <sys/sbuf.h>
-#ifndef _KERNEL
+
+#ifdef _KERNEL
+#include <cam/cam_periph.h>
+#include <cam/cam_xpt_sim.h>
+#include <cam/cam_xpt_periph.h>
+#include <cam/cam_xpt_internal.h>
+#else
#include <camlib.h>
#ifndef FALSE
@@ -4605,6 +4614,28 @@ scsi_static_inquiry_match(caddr_t inqbuf
}
#ifdef _KERNEL
+int
+scsi_vpd_supported_page(struct cam_periph *periph, uint8_t page_id)
+{
+ struct cam_ed *device;
+ struct scsi_vpd_supported_pages *vpds;
+ int i, num_pages;
+
+ device = periph->path->device;
+ vpds = (struct scsi_vpd_supported_pages *)device->supported_vpds;
+
+ if (vpds != NULL) {
+ num_pages = device->supported_vpds_len -
+ SVPD_SUPPORTED_PAGES_HDR_LEN;
+ for (i = 0; i < num_pages; i++) {
+ if (vpds->page_list[i] == page_id)
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
static void
init_scsi_delay(void)
{
Modified: stable/8/sys/cam/scsi/scsi_all.h
==============================================================================
--- stable/8/sys/cam/scsi/scsi_all.h Thu Jun 6 22:02:03 2013 (r251476)
+++ stable/8/sys/cam/scsi/scsi_all.h Thu Jun 6 22:31:52 2013 (r251477)
@@ -857,13 +857,28 @@ struct scsi_vpd_supported_page_list
{
u_int8_t device;
u_int8_t page_code;
-#define SVPD_SUPPORTED_PAGE_LIST 0x00
+#define SVPD_SUPPORTED_PAGE_LIST 0x00
+#define SVPD_SUPPORTED_PAGES_HDR_LEN 4
u_int8_t reserved;
u_int8_t length; /* number of VPD entries */
#define SVPD_SUPPORTED_PAGES_SIZE 251
u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE];
};
+/*
+ * This structure is more suited to target operation, because the
+ * number of supported pages is left to the user to allocate.
+ */
+struct scsi_vpd_supported_pages
+{
+ u_int8_t device;
+ u_int8_t page_code;
+ u_int8_t reserved;
+#define SVPD_SUPPORTED_PAGES 0x00
+ u_int8_t length;
+ u_int8_t page_list[0];
+};
+
struct scsi_vpd_unit_serial_number
{
u_int8_t device;
@@ -1250,6 +1265,8 @@ int scsi_sense_sbuf(struct ccb_scsiio *
char * scsi_sense_string(struct ccb_scsiio *csio,
char *str, int str_len);
void scsi_sense_print(struct ccb_scsiio *csio);
+int scsi_vpd_supported_page(struct cam_periph *periph,
+ uint8_t page_id);
#else /* _KERNEL */
int scsi_command_string(struct cam_device *device,
struct ccb_scsiio *csio, struct sbuf *sb);
Modified: stable/8/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- stable/8/sys/cam/scsi/scsi_xpt.c Thu Jun 6 22:02:03 2013 (r251476)
+++ stable/8/sys/cam/scsi/scsi_xpt.c Thu Jun 6 22:31:52 2013 (r251477)
@@ -134,8 +134,8 @@ typedef enum {
PROBE_FULL_INQUIRY,
PROBE_REPORT_LUNS,
PROBE_MODE_SENSE,
- PROBE_SERIAL_NUM_0,
- PROBE_SERIAL_NUM_1,
+ PROBE_SUPPORTED_VPD_LIST,
+ PROBE_SERIAL_NUM,
PROBE_TUR_FOR_NEGOTIATION,
PROBE_INQUIRY_BASIC_DV1,
PROBE_INQUIRY_BASIC_DV2,
@@ -150,8 +150,8 @@ static char *probe_action_text[] = {
"PROBE_FULL_INQUIRY",
"PROBE_REPORT_LUNS",
"PROBE_MODE_SENSE",
- "PROBE_SERIAL_NUM_0",
- "PROBE_SERIAL_NUM_1",
+ "PROBE_SUPPORTED_VPD_LIST",
+ "PROBE_SERIAL_NUM",
"PROBE_TUR_FOR_NEGOTIATION",
"PROBE_INQUIRY_BASIC_DV1",
"PROBE_INQUIRY_BASIC_DV2",
@@ -824,7 +824,8 @@ again:
if (INQ_DATA_TQ_ENABLED(inq_buf))
PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
else
- PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+ PROBE_SET_ACTION(softc,
+ PROBE_SUPPORTED_VPD_LIST);
goto again;
}
scsi_report_luns(csio, 5, probedone, MSG_SIMPLE_Q_TAG,
@@ -857,10 +858,10 @@ again:
}
xpt_print(periph->path, "Unable to mode sense control page - "
"malloc failure\n");
- PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+ PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
}
/* FALLTHROUGH */
- case PROBE_SERIAL_NUM_0:
+ case PROBE_SUPPORTED_VPD_LIST:
{
struct scsi_vpd_supported_page_list *vpd_list = NULL;
struct cam_ed *device;
@@ -892,7 +893,7 @@ again:
probedone(periph, start_ccb);
return;
}
- case PROBE_SERIAL_NUM_1:
+ case PROBE_SERIAL_NUM:
{
struct scsi_vpd_unit_serial_number *serial_buf;
struct cam_ed* device;
@@ -905,8 +906,10 @@ again:
device->serial_num_len = 0;
}
- serial_buf = (struct scsi_vpd_unit_serial_number *)
- malloc(sizeof(*serial_buf), M_CAMXPT, M_NOWAIT|M_ZERO);
+ if (scsi_vpd_supported_page(periph, SVPD_UNIT_SERIAL_NUMBER))
+ serial_buf = (struct scsi_vpd_unit_serial_number *)
+ malloc(sizeof(*serial_buf), M_CAMXPT,
+ M_NOWAIT|M_ZERO);
if (serial_buf != NULL) {
scsi_inquiry(csio,
@@ -1144,7 +1147,7 @@ probedone(struct cam_periph *periph, uni
PROBE_MODE_SENSE);
else
PROBE_SET_ACTION(softc,
- PROBE_SERIAL_NUM_0);
+ PROBE_SUPPORTED_VPD_LIST);
if (path->device->flags & CAM_DEV_UNCONFIGURED) {
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
@@ -1303,7 +1306,8 @@ probedone(struct cam_periph *periph, uni
if (INQ_DATA_TQ_ENABLED(inq_buf))
PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
else
- PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+ PROBE_SET_ACTION(softc,
+ PROBE_SUPPORTED_VPD_LIST);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
return;
@@ -1339,36 +1343,40 @@ probedone(struct cam_periph *periph, uni
}
xpt_release_ccb(done_ccb);
free(mode_hdr, M_CAMXPT);
- PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+ PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
xpt_schedule(periph, priority);
return;
}
- case PROBE_SERIAL_NUM_0:
+ case PROBE_SUPPORTED_VPD_LIST:
{
struct ccb_scsiio *csio;
struct scsi_vpd_supported_page_list *page_list;
- int length, serialnum_supported, i;
- serialnum_supported = 0;
csio = &done_ccb->csio;
page_list =
(struct scsi_vpd_supported_page_list *)csio->data_ptr;
+ if (path->device->supported_vpds != NULL) {
+ free(path->device->supported_vpds, M_CAMXPT);
+ path->device->supported_vpds = NULL;
+ path->device->supported_vpds_len = 0;
+ }
+
if (page_list == NULL) {
/*
* Don't process the command as it was never sent
*/
- } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
- && (page_list->length > 0)) {
- length = min(page_list->length,
- SVPD_SUPPORTED_PAGES_SIZE);
- for (i = 0; i < length; i++) {
- if (page_list->list[i] ==
- SVPD_UNIT_SERIAL_NUMBER) {
- serialnum_supported = 1;
- break;
- }
- }
+ } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+ /* Got vpd list */
+ path->device->supported_vpds_len = page_list->length +
+ SVPD_SUPPORTED_PAGES_HDR_LEN;
+ path->device->supported_vpds = (uint8_t *)page_list;
+
+ xpt_release_ccb(done_ccb);
+ PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM);
+ xpt_schedule(periph, priority);
+ return;
+
} else if (cam_periph_error(done_ccb, 0,
SF_RETRY_UA|SF_NO_PRINT,
&softc->saved_ccb) == ERESTART) {
@@ -1382,18 +1390,12 @@ probedone(struct cam_periph *periph, uni
if (page_list != NULL)
free(page_list, M_CAMXPT);
- if (serialnum_supported) {
- xpt_release_ccb(done_ccb);
- PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_1);
- xpt_schedule(periph, priority);
- return;
- }
-
+ /* No VPDs available, skip to device check. */
csio->data_ptr = NULL;
/* FALLTHROUGH */
}
- case PROBE_SERIAL_NUM_1:
+ case PROBE_SERIAL_NUM:
{
struct ccb_scsiio *csio;
struct scsi_vpd_unit_serial_number *serial_buf;
@@ -2245,6 +2247,8 @@ scsi_alloc_device(struct cam_eb *bus, st
device->queue_flags = 0;
device->serial_num = NULL;
device->serial_num_len = 0;
+ device->supported_vpds = NULL;
+ device->supported_vpds_len = 0;
/*
* XXX should be limited by number of CCBs this bus can
More information about the svn-src-all
mailing list