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 --- |