Deleted Added
full compact
scsi_ch.c (250792) scsi_ch.c (253274)
1/*-
2 * Copyright (c) 1997 Justin T. Gibbs.
3 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 54 unchanged lines hidden (view full) ---

63 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
64 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
65 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67 * SUCH DAMAGE.
68 */
69
70#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1997 Justin T. Gibbs.
3 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 54 unchanged lines hidden (view full) ---

63 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
64 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
65 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67 * SUCH DAMAGE.
68 */
69
70#include <sys/cdefs.h>
71__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_ch.c 250792 2013-05-18 23:36:21Z smh $");
71__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_ch.c 253274 2013-07-12 17:09:50Z ken $");
72
73#include <sys/param.h>
74#include <sys/queue.h>
75#include <sys/systm.h>
76#include <sys/kernel.h>
77#include <sys/types.h>
78#include <sys/malloc.h>
79#include <sys/fcntl.h>

--- 17 unchanged lines hidden (view full) ---

97 * be too short for some devices (especially the timeout for INITIALIZE
98 * ELEMENT STATUS).
99 */
100
101static const u_int32_t CH_TIMEOUT_MODE_SENSE = 6000;
102static const u_int32_t CH_TIMEOUT_MOVE_MEDIUM = 100000;
103static const u_int32_t CH_TIMEOUT_EXCHANGE_MEDIUM = 100000;
104static const u_int32_t CH_TIMEOUT_POSITION_TO_ELEMENT = 100000;
72
73#include <sys/param.h>
74#include <sys/queue.h>
75#include <sys/systm.h>
76#include <sys/kernel.h>
77#include <sys/types.h>
78#include <sys/malloc.h>
79#include <sys/fcntl.h>

--- 17 unchanged lines hidden (view full) ---

97 * be too short for some devices (especially the timeout for INITIALIZE
98 * ELEMENT STATUS).
99 */
100
101static const u_int32_t CH_TIMEOUT_MODE_SENSE = 6000;
102static const u_int32_t CH_TIMEOUT_MOVE_MEDIUM = 100000;
103static const u_int32_t CH_TIMEOUT_EXCHANGE_MEDIUM = 100000;
104static const u_int32_t CH_TIMEOUT_POSITION_TO_ELEMENT = 100000;
105static const u_int32_t CH_TIMEOUT_READ_ELEMENT_STATUS = 10000;
105static const u_int32_t CH_TIMEOUT_READ_ELEMENT_STATUS = 60000;
106static const u_int32_t CH_TIMEOUT_SEND_VOLTAG = 10000;
107static const u_int32_t CH_TIMEOUT_INITIALIZE_ELEMENT_STATUS = 500000;
108
109typedef enum {
110 CH_FLAG_INVALID = 0x001
111} ch_flags;
112
113typedef enum {
114 CH_STATE_PROBE,
115 CH_STATE_NORMAL
116} ch_state;
117
118typedef enum {
119 CH_CCB_PROBE,
120 CH_CCB_WAITING
121} ch_ccb_types;
122
123typedef enum {
124 CH_Q_NONE = 0x00,
106static const u_int32_t CH_TIMEOUT_SEND_VOLTAG = 10000;
107static const u_int32_t CH_TIMEOUT_INITIALIZE_ELEMENT_STATUS = 500000;
108
109typedef enum {
110 CH_FLAG_INVALID = 0x001
111} ch_flags;
112
113typedef enum {
114 CH_STATE_PROBE,
115 CH_STATE_NORMAL
116} ch_state;
117
118typedef enum {
119 CH_CCB_PROBE,
120 CH_CCB_WAITING
121} ch_ccb_types;
122
123typedef enum {
124 CH_Q_NONE = 0x00,
125 CH_Q_NO_DBD = 0x01
125 CH_Q_NO_DBD = 0x01,
126 CH_Q_NO_DVCID = 0x02
126} ch_quirks;
127
128#define CH_Q_BIT_STRING \
129 "\020" \
127} ch_quirks;
128
129#define CH_Q_BIT_STRING \
130 "\020" \
130 "\001NO_DBD"
131 "\001NO_DBD" \
132 "\002NO_DVCID"
131
132#define ccb_state ppriv_field0
133#define ccb_bp ppriv_ptr1
134
135struct scsi_mode_sense_data {
136 struct scsi_mode_header_6 header;
137 struct scsi_mode_blk_desc blk_desc;
138 union {

--- 252 unchanged lines hidden (view full) ---

391 return(CAM_REQ_CMP_ERR);
392 }
393
394 bzero(softc, sizeof(*softc));
395 softc->state = CH_STATE_PROBE;
396 periph->softc = softc;
397 softc->quirks = CH_Q_NONE;
398
133
134#define ccb_state ppriv_field0
135#define ccb_bp ppriv_ptr1
136
137struct scsi_mode_sense_data {
138 struct scsi_mode_header_6 header;
139 struct scsi_mode_blk_desc blk_desc;
140 union {

--- 252 unchanged lines hidden (view full) ---

393 return(CAM_REQ_CMP_ERR);
394 }
395
396 bzero(softc, sizeof(*softc));
397 softc->state = CH_STATE_PROBE;
398 periph->softc = softc;
399 softc->quirks = CH_Q_NONE;
400
401 /*
402 * The DVCID and CURDATA bits were not introduced until the SMC
403 * spec. If this device claims SCSI-2 or earlier support, then it
404 * very likely does not support these bits.
405 */
406 if (cgd->inq_data.version <= SCSI_REV_2)
407 softc->quirks |= CH_Q_NO_DVCID;
408
399 bzero(&cpi, sizeof(cpi));
400 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
401 cpi.ccb_h.func_code = XPT_PATH_INQ;
402 xpt_action((union ccb *)&cpi);
403
404 /*
405 * Changers don't have a blocksize, and obviously don't support
406 * tagged queueing.

--- 796 unchanged lines hidden (view full) ---

1203 struct changer_element_status_request *cesr)
1204{
1205 struct read_element_status_header *st_hdr;
1206 struct read_element_status_page_header *pg_hdr;
1207 struct read_element_status_descriptor *desc;
1208 caddr_t data = NULL;
1209 size_t size, desclen;
1210 int avail, i, error = 0;
409 bzero(&cpi, sizeof(cpi));
410 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
411 cpi.ccb_h.func_code = XPT_PATH_INQ;
412 xpt_action((union ccb *)&cpi);
413
414 /*
415 * Changers don't have a blocksize, and obviously don't support
416 * tagged queueing.

--- 796 unchanged lines hidden (view full) ---

1213 struct changer_element_status_request *cesr)
1214{
1215 struct read_element_status_header *st_hdr;
1216 struct read_element_status_page_header *pg_hdr;
1217 struct read_element_status_descriptor *desc;
1218 caddr_t data = NULL;
1219 size_t size, desclen;
1220 int avail, i, error = 0;
1221 int curdata, dvcid, sense_flags;
1222 int try_no_dvcid = 0;
1211 struct changer_element_status *user_data = NULL;
1212 struct ch_softc *softc;
1213 union ccb *ccb;
1214 int chet = cesr->cesr_element_type;
1215 int want_voltags = (cesr->cesr_flags & CESR_VOLTAGS) ? 1 : 0;
1216
1217 softc = (struct ch_softc *)periph->softc;
1218

--- 15 unchanged lines hidden (view full) ---

1234 * that the first one can fit into 1k.
1235 */
1236 cam_periph_unlock(periph);
1237 data = (caddr_t)malloc(1024, M_DEVBUF, M_WAITOK);
1238
1239 cam_periph_lock(periph);
1240 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1241
1223 struct changer_element_status *user_data = NULL;
1224 struct ch_softc *softc;
1225 union ccb *ccb;
1226 int chet = cesr->cesr_element_type;
1227 int want_voltags = (cesr->cesr_flags & CESR_VOLTAGS) ? 1 : 0;
1228
1229 softc = (struct ch_softc *)periph->softc;
1230

--- 15 unchanged lines hidden (view full) ---

1246 * that the first one can fit into 1k.
1247 */
1248 cam_periph_unlock(periph);
1249 data = (caddr_t)malloc(1024, M_DEVBUF, M_WAITOK);
1250
1251 cam_periph_lock(periph);
1252 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1253
1254 sense_flags = SF_RETRY_UA;
1255 if (softc->quirks & CH_Q_NO_DVCID) {
1256 dvcid = 0;
1257 curdata = 0;
1258 } else {
1259 dvcid = 1;
1260 curdata = 1;
1261 /*
1262 * Don't print anything for an Illegal Request, because
1263 * these flags can cause some changers to complain. We'll
1264 * retry without them if we get an error.
1265 */
1266 sense_flags |= SF_QUIET_IR;
1267 }
1268
1269retry_einval:
1270
1242 scsi_read_element_status(&ccb->csio,
1243 /* retries */ 1,
1244 /* cbfcnp */ chdone,
1245 /* tag_action */ MSG_SIMPLE_Q_TAG,
1246 /* voltag */ want_voltags,
1247 /* sea */ softc->sc_firsts[chet],
1271 scsi_read_element_status(&ccb->csio,
1272 /* retries */ 1,
1273 /* cbfcnp */ chdone,
1274 /* tag_action */ MSG_SIMPLE_Q_TAG,
1275 /* voltag */ want_voltags,
1276 /* sea */ softc->sc_firsts[chet],
1248 /* dvcid */ 1,
1249 /* curdata */ 1,
1277 /* dvcid */ dvcid,
1278 /* curdata */ curdata,
1250 /* count */ 1,
1251 /* data_ptr */ data,
1252 /* dxfer_len */ 1024,
1253 /* sense_len */ SSD_FULL_SIZE,
1254 /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS);
1255
1256 error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ CAM_RETRY_SELTO,
1279 /* count */ 1,
1280 /* data_ptr */ data,
1281 /* dxfer_len */ 1024,
1282 /* sense_len */ SSD_FULL_SIZE,
1283 /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS);
1284
1285 error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ CAM_RETRY_SELTO,
1257 /*sense_flags*/ SF_RETRY_UA,
1286 /*sense_flags*/ sense_flags,
1258 softc->device_stats);
1259
1287 softc->device_stats);
1288
1289 /*
1290 * An Illegal Request sense key (only used if there is no asc/ascq)
1291 * or 0x24,0x00 for an ASC/ASCQ both map to EINVAL. If dvcid or
1292 * curdata are set (we set both or neither), try turning them off
1293 * and see if the command is successful.
1294 */
1295 if ((error == EINVAL)
1296 && (dvcid || curdata)) {
1297 dvcid = 0;
1298 curdata = 0;
1299 error = 0;
1300 /* At this point we want to report any Illegal Request */
1301 sense_flags &= ~SF_QUIET_IR;
1302 try_no_dvcid = 1;
1303 goto retry_einval;
1304 }
1305
1306 /*
1307 * In this case, we tried a read element status with dvcid and
1308 * curdata set, and it failed. We retried without those bits, and
1309 * it succeeded. Suggest to the user that he set a quirk, so we
1310 * don't go through the retry process the first time in the future.
1311 * This should only happen on changers that claim SCSI-3 or higher,
1312 * but don't support these bits.
1313 */
1314 if ((try_no_dvcid != 0)
1315 && (error == 0))
1316 softc->quirks |= CH_Q_NO_DVCID;
1317
1260 if (error)
1261 goto done;
1262 cam_periph_unlock(periph);
1263
1264 st_hdr = (struct read_element_status_header *)data;
1265 pg_hdr = (struct read_element_status_page_header *)((uintptr_t)st_hdr +
1266 sizeof(struct read_element_status_header));
1267 desclen = scsi_2btoul(pg_hdr->edl);

--- 11 unchanged lines hidden (view full) ---

1279 cam_periph_lock(periph);
1280 scsi_read_element_status(&ccb->csio,
1281 /* retries */ 1,
1282 /* cbfcnp */ chdone,
1283 /* tag_action */ MSG_SIMPLE_Q_TAG,
1284 /* voltag */ want_voltags,
1285 /* sea */ softc->sc_firsts[chet]
1286 + cesr->cesr_element_base,
1318 if (error)
1319 goto done;
1320 cam_periph_unlock(periph);
1321
1322 st_hdr = (struct read_element_status_header *)data;
1323 pg_hdr = (struct read_element_status_page_header *)((uintptr_t)st_hdr +
1324 sizeof(struct read_element_status_header));
1325 desclen = scsi_2btoul(pg_hdr->edl);

--- 11 unchanged lines hidden (view full) ---

1337 cam_periph_lock(periph);
1338 scsi_read_element_status(&ccb->csio,
1339 /* retries */ 1,
1340 /* cbfcnp */ chdone,
1341 /* tag_action */ MSG_SIMPLE_Q_TAG,
1342 /* voltag */ want_voltags,
1343 /* sea */ softc->sc_firsts[chet]
1344 + cesr->cesr_element_base,
1287 /* dvcid */ 1,
1288 /* curdata */ 1,
1345 /* dvcid */ dvcid,
1346 /* curdata */ curdata,
1289 /* count */ cesr->cesr_element_count,
1290 /* data_ptr */ data,
1291 /* dxfer_len */ size,
1292 /* sense_len */ SSD_FULL_SIZE,
1293 /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS);
1294
1295 error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ CAM_RETRY_SELTO,
1296 /*sense_flags*/ SF_RETRY_UA,

--- 600 unchanged lines hidden ---
1347 /* count */ cesr->cesr_element_count,
1348 /* data_ptr */ data,
1349 /* dxfer_len */ size,
1350 /* sense_len */ SSD_FULL_SIZE,
1351 /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS);
1352
1353 error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ CAM_RETRY_SELTO,
1354 /*sense_flags*/ SF_RETRY_UA,

--- 600 unchanged lines hidden ---