diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 296 |
1 files changed, 178 insertions, 118 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7a91ca3d32a..77f2d444f7e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -232,23 +232,6 @@ void scsi_do_req(struct scsi_request *sreq, const void *cmnd, | |||
232 | } | 232 | } |
233 | EXPORT_SYMBOL(scsi_do_req); | 233 | EXPORT_SYMBOL(scsi_do_req); |
234 | 234 | ||
235 | static void scsi_wait_done(struct scsi_cmnd *cmd) | ||
236 | { | ||
237 | struct request *req = cmd->request; | ||
238 | struct request_queue *q = cmd->device->request_queue; | ||
239 | unsigned long flags; | ||
240 | |||
241 | req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ | ||
242 | |||
243 | spin_lock_irqsave(q->queue_lock, flags); | ||
244 | if (blk_rq_tagged(req)) | ||
245 | blk_queue_end_tag(q, req); | ||
246 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
247 | |||
248 | if (req->waiting) | ||
249 | complete(req->waiting); | ||
250 | } | ||
251 | |||
252 | /* This is the end routine we get to if a command was never attached | 235 | /* This is the end routine we get to if a command was never attached |
253 | * to the request. Simply complete the request without changing | 236 | * to the request. Simply complete the request without changing |
254 | * rq_status; this will cause a DRIVER_ERROR. */ | 237 | * rq_status; this will cause a DRIVER_ERROR. */ |
@@ -263,21 +246,114 @@ void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer, | |||
263 | unsigned bufflen, int timeout, int retries) | 246 | unsigned bufflen, int timeout, int retries) |
264 | { | 247 | { |
265 | DECLARE_COMPLETION(wait); | 248 | DECLARE_COMPLETION(wait); |
266 | 249 | int write = (sreq->sr_data_direction == DMA_TO_DEVICE); | |
267 | sreq->sr_request->waiting = &wait; | 250 | struct request *req; |
268 | sreq->sr_request->rq_status = RQ_SCSI_BUSY; | 251 | |
269 | sreq->sr_request->end_io = scsi_wait_req_end_io; | 252 | req = blk_get_request(sreq->sr_device->request_queue, write, |
270 | scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done, | 253 | __GFP_WAIT); |
271 | timeout, retries); | 254 | if (bufflen && blk_rq_map_kern(sreq->sr_device->request_queue, req, |
255 | buffer, bufflen, __GFP_WAIT)) { | ||
256 | sreq->sr_result = DRIVER_ERROR << 24; | ||
257 | blk_put_request(req); | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | req->flags |= REQ_NOMERGE; | ||
262 | req->waiting = &wait; | ||
263 | req->end_io = scsi_wait_req_end_io; | ||
264 | req->cmd_len = COMMAND_SIZE(((u8 *)cmnd)[0]); | ||
265 | req->sense = sreq->sr_sense_buffer; | ||
266 | req->sense_len = 0; | ||
267 | memcpy(req->cmd, cmnd, req->cmd_len); | ||
268 | req->timeout = timeout; | ||
269 | req->flags |= REQ_BLOCK_PC; | ||
270 | req->rq_disk = NULL; | ||
271 | blk_insert_request(sreq->sr_device->request_queue, req, | ||
272 | sreq->sr_data_direction == DMA_TO_DEVICE, NULL); | ||
272 | wait_for_completion(&wait); | 273 | wait_for_completion(&wait); |
273 | sreq->sr_request->waiting = NULL; | 274 | sreq->sr_request->waiting = NULL; |
274 | if (sreq->sr_request->rq_status != RQ_SCSI_DONE) | 275 | sreq->sr_result = req->errors; |
276 | if (req->errors) | ||
275 | sreq->sr_result |= (DRIVER_ERROR << 24); | 277 | sreq->sr_result |= (DRIVER_ERROR << 24); |
276 | 278 | ||
277 | __scsi_release_request(sreq); | 279 | blk_put_request(req); |
278 | } | 280 | } |
281 | |||
279 | EXPORT_SYMBOL(scsi_wait_req); | 282 | EXPORT_SYMBOL(scsi_wait_req); |
280 | 283 | ||
284 | /** | ||
285 | * scsi_execute - insert request and wait for the result | ||
286 | * @sdev: scsi device | ||
287 | * @cmd: scsi command | ||
288 | * @data_direction: data direction | ||
289 | * @buffer: data buffer | ||
290 | * @bufflen: len of buffer | ||
291 | * @sense: optional sense buffer | ||
292 | * @timeout: request timeout in seconds | ||
293 | * @retries: number of times to retry request | ||
294 | * @flags: or into request flags; | ||
295 | * | ||
296 | * returns the req->errors value which is the the scsi_cmnd result | ||
297 | * field. | ||
298 | **/ | ||
299 | int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, | ||
300 | int data_direction, void *buffer, unsigned bufflen, | ||
301 | unsigned char *sense, int timeout, int retries, int flags) | ||
302 | { | ||
303 | struct request *req; | ||
304 | int write = (data_direction == DMA_TO_DEVICE); | ||
305 | int ret = DRIVER_ERROR << 24; | ||
306 | |||
307 | req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); | ||
308 | |||
309 | if (bufflen && blk_rq_map_kern(sdev->request_queue, req, | ||
310 | buffer, bufflen, __GFP_WAIT)) | ||
311 | goto out; | ||
312 | |||
313 | req->cmd_len = COMMAND_SIZE(cmd[0]); | ||
314 | memcpy(req->cmd, cmd, req->cmd_len); | ||
315 | req->sense = sense; | ||
316 | req->sense_len = 0; | ||
317 | req->timeout = timeout; | ||
318 | req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET; | ||
319 | |||
320 | /* | ||
321 | * head injection *required* here otherwise quiesce won't work | ||
322 | */ | ||
323 | blk_execute_rq(req->q, NULL, req, 1); | ||
324 | |||
325 | ret = req->errors; | ||
326 | out: | ||
327 | blk_put_request(req); | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | EXPORT_SYMBOL(scsi_execute); | ||
332 | |||
333 | |||
334 | int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, | ||
335 | int data_direction, void *buffer, unsigned bufflen, | ||
336 | struct scsi_sense_hdr *sshdr, int timeout, int retries) | ||
337 | { | ||
338 | char *sense = NULL; | ||
339 | int result; | ||
340 | |||
341 | if (sshdr) { | ||
342 | sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); | ||
343 | if (!sense) | ||
344 | return DRIVER_ERROR << 24; | ||
345 | memset(sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
346 | } | ||
347 | result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen, | ||
348 | sense, timeout, retries, 0); | ||
349 | if (sshdr) | ||
350 | scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr); | ||
351 | |||
352 | kfree(sense); | ||
353 | return result; | ||
354 | } | ||
355 | EXPORT_SYMBOL(scsi_execute_req); | ||
356 | |||
281 | /* | 357 | /* |
282 | * Function: scsi_init_cmd_errh() | 358 | * Function: scsi_init_cmd_errh() |
283 | * | 359 | * |
@@ -348,7 +424,7 @@ void scsi_device_unbusy(struct scsi_device *sdev) | |||
348 | 424 | ||
349 | spin_lock_irqsave(shost->host_lock, flags); | 425 | spin_lock_irqsave(shost->host_lock, flags); |
350 | shost->host_busy--; | 426 | shost->host_busy--; |
351 | if (unlikely(test_bit(SHOST_RECOVERY, &shost->shost_state) && | 427 | if (unlikely((shost->shost_state == SHOST_RECOVERY) && |
352 | shost->host_failed)) | 428 | shost->host_failed)) |
353 | scsi_eh_wakeup(shost); | 429 | scsi_eh_wakeup(shost); |
354 | spin_unlock(shost->host_lock); | 430 | spin_unlock(shost->host_lock); |
@@ -851,17 +927,20 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
851 | scsi_requeue_command(q, cmd); | 927 | scsi_requeue_command(q, cmd); |
852 | return; | 928 | return; |
853 | } | 929 | } |
854 | printk(KERN_INFO "Device %s not ready.\n", | 930 | if (!(req->flags & REQ_QUIET)) |
855 | req->rq_disk ? req->rq_disk->disk_name : ""); | 931 | dev_printk(KERN_INFO, |
932 | &cmd->device->sdev_gendev, | ||
933 | "Device not ready.\n"); | ||
856 | cmd = scsi_end_request(cmd, 0, this_count, 1); | 934 | cmd = scsi_end_request(cmd, 0, this_count, 1); |
857 | return; | 935 | return; |
858 | case VOLUME_OVERFLOW: | 936 | case VOLUME_OVERFLOW: |
859 | printk(KERN_INFO "Volume overflow <%d %d %d %d> CDB: ", | 937 | if (!(req->flags & REQ_QUIET)) { |
860 | cmd->device->host->host_no, | 938 | dev_printk(KERN_INFO, |
861 | (int)cmd->device->channel, | 939 | &cmd->device->sdev_gendev, |
862 | (int)cmd->device->id, (int)cmd->device->lun); | 940 | "Volume overflow, CDB: "); |
863 | __scsi_print_command(cmd->data_cmnd); | 941 | __scsi_print_command(cmd->data_cmnd); |
864 | scsi_print_sense("", cmd); | 942 | scsi_print_sense("", cmd); |
943 | } | ||
865 | cmd = scsi_end_request(cmd, 0, block_bytes, 1); | 944 | cmd = scsi_end_request(cmd, 0, block_bytes, 1); |
866 | return; | 945 | return; |
867 | default: | 946 | default: |
@@ -878,14 +957,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
878 | return; | 957 | return; |
879 | } | 958 | } |
880 | if (result) { | 959 | if (result) { |
881 | printk(KERN_INFO "SCSI error : <%d %d %d %d> return code " | 960 | if (!(req->flags & REQ_QUIET)) { |
882 | "= 0x%x\n", cmd->device->host->host_no, | 961 | dev_printk(KERN_INFO, &cmd->device->sdev_gendev, |
883 | cmd->device->channel, | 962 | "SCSI error: return code = 0x%x\n", result); |
884 | cmd->device->id, | 963 | |
885 | cmd->device->lun, result); | 964 | if (driver_byte(result) & DRIVER_SENSE) |
886 | 965 | scsi_print_sense("", cmd); | |
887 | if (driver_byte(result) & DRIVER_SENSE) | 966 | } |
888 | scsi_print_sense("", cmd); | ||
889 | /* | 967 | /* |
890 | * Mark a single buffer as not uptodate. Queue the remainder. | 968 | * Mark a single buffer as not uptodate. Queue the remainder. |
891 | * We sometimes get this cruft in the event that a medium error | 969 | * We sometimes get this cruft in the event that a medium error |
@@ -1020,6 +1098,12 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, | |||
1020 | return -EOPNOTSUPP; | 1098 | return -EOPNOTSUPP; |
1021 | } | 1099 | } |
1022 | 1100 | ||
1101 | static void scsi_generic_done(struct scsi_cmnd *cmd) | ||
1102 | { | ||
1103 | BUG_ON(!blk_pc_request(cmd->request)); | ||
1104 | scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0); | ||
1105 | } | ||
1106 | |||
1023 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1107 | static int scsi_prep_fn(struct request_queue *q, struct request *req) |
1024 | { | 1108 | { |
1025 | struct scsi_device *sdev = q->queuedata; | 1109 | struct scsi_device *sdev = q->queuedata; |
@@ -1061,7 +1145,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1061 | * these two cases differently. We differentiate by looking | 1145 | * these two cases differently. We differentiate by looking |
1062 | * at request->cmd, as this tells us the real story. | 1146 | * at request->cmd, as this tells us the real story. |
1063 | */ | 1147 | */ |
1064 | if (req->flags & REQ_SPECIAL) { | 1148 | if (req->flags & REQ_SPECIAL && req->special) { |
1065 | struct scsi_request *sreq = req->special; | 1149 | struct scsi_request *sreq = req->special; |
1066 | 1150 | ||
1067 | if (sreq->sr_magic == SCSI_REQ_MAGIC) { | 1151 | if (sreq->sr_magic == SCSI_REQ_MAGIC) { |
@@ -1073,7 +1157,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1073 | cmd = req->special; | 1157 | cmd = req->special; |
1074 | } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { | 1158 | } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { |
1075 | 1159 | ||
1076 | if(unlikely(specials_only)) { | 1160 | if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) { |
1077 | if(specials_only == SDEV_QUIESCE || | 1161 | if(specials_only == SDEV_QUIESCE || |
1078 | specials_only == SDEV_BLOCK) | 1162 | specials_only == SDEV_BLOCK) |
1079 | return BLKPREP_DEFER; | 1163 | return BLKPREP_DEFER; |
@@ -1142,11 +1226,26 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1142 | /* | 1226 | /* |
1143 | * Initialize the actual SCSI command for this request. | 1227 | * Initialize the actual SCSI command for this request. |
1144 | */ | 1228 | */ |
1145 | drv = *(struct scsi_driver **)req->rq_disk->private_data; | 1229 | if (req->rq_disk) { |
1146 | if (unlikely(!drv->init_command(cmd))) { | 1230 | drv = *(struct scsi_driver **)req->rq_disk->private_data; |
1147 | scsi_release_buffers(cmd); | 1231 | if (unlikely(!drv->init_command(cmd))) { |
1148 | scsi_put_command(cmd); | 1232 | scsi_release_buffers(cmd); |
1149 | return BLKPREP_KILL; | 1233 | scsi_put_command(cmd); |
1234 | return BLKPREP_KILL; | ||
1235 | } | ||
1236 | } else { | ||
1237 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | ||
1238 | if (rq_data_dir(req) == WRITE) | ||
1239 | cmd->sc_data_direction = DMA_TO_DEVICE; | ||
1240 | else if (req->data_len) | ||
1241 | cmd->sc_data_direction = DMA_FROM_DEVICE; | ||
1242 | else | ||
1243 | cmd->sc_data_direction = DMA_NONE; | ||
1244 | |||
1245 | cmd->transfersize = req->data_len; | ||
1246 | cmd->allowed = 3; | ||
1247 | cmd->timeout_per_command = req->timeout; | ||
1248 | cmd->done = scsi_generic_done; | ||
1150 | } | 1249 | } |
1151 | } | 1250 | } |
1152 | 1251 | ||
@@ -1207,7 +1306,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q, | |||
1207 | struct Scsi_Host *shost, | 1306 | struct Scsi_Host *shost, |
1208 | struct scsi_device *sdev) | 1307 | struct scsi_device *sdev) |
1209 | { | 1308 | { |
1210 | if (test_bit(SHOST_RECOVERY, &shost->shost_state)) | 1309 | if (shost->shost_state == SHOST_RECOVERY) |
1211 | return 0; | 1310 | return 0; |
1212 | if (shost->host_busy == 0 && shost->host_blocked) { | 1311 | if (shost->host_busy == 0 && shost->host_blocked) { |
1213 | /* | 1312 | /* |
@@ -1539,9 +1638,9 @@ void scsi_exit_queue(void) | |||
1539 | } | 1638 | } |
1540 | } | 1639 | } |
1541 | /** | 1640 | /** |
1542 | * __scsi_mode_sense - issue a mode sense, falling back from 10 to | 1641 | * scsi_mode_sense - issue a mode sense, falling back from 10 to |
1543 | * six bytes if necessary. | 1642 | * six bytes if necessary. |
1544 | * @sreq: SCSI request to fill in with the MODE_SENSE | 1643 | * @sdev: SCSI device to be queried |
1545 | * @dbd: set if mode sense will allow block descriptors to be returned | 1644 | * @dbd: set if mode sense will allow block descriptors to be returned |
1546 | * @modepage: mode page being requested | 1645 | * @modepage: mode page being requested |
1547 | * @buffer: request buffer (may not be smaller than eight bytes) | 1646 | * @buffer: request buffer (may not be smaller than eight bytes) |
@@ -1549,26 +1648,34 @@ void scsi_exit_queue(void) | |||
1549 | * @timeout: command timeout | 1648 | * @timeout: command timeout |
1550 | * @retries: number of retries before failing | 1649 | * @retries: number of retries before failing |
1551 | * @data: returns a structure abstracting the mode header data | 1650 | * @data: returns a structure abstracting the mode header data |
1651 | * @sense: place to put sense data (or NULL if no sense to be collected). | ||
1652 | * must be SCSI_SENSE_BUFFERSIZE big. | ||
1552 | * | 1653 | * |
1553 | * Returns zero if unsuccessful, or the header offset (either 4 | 1654 | * Returns zero if unsuccessful, or the header offset (either 4 |
1554 | * or 8 depending on whether a six or ten byte command was | 1655 | * or 8 depending on whether a six or ten byte command was |
1555 | * issued) if successful. | 1656 | * issued) if successful. |
1556 | **/ | 1657 | **/ |
1557 | int | 1658 | int |
1558 | __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage, | 1659 | scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, |
1559 | unsigned char *buffer, int len, int timeout, int retries, | 1660 | unsigned char *buffer, int len, int timeout, int retries, |
1560 | struct scsi_mode_data *data) { | 1661 | struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) { |
1561 | unsigned char cmd[12]; | 1662 | unsigned char cmd[12]; |
1562 | int use_10_for_ms; | 1663 | int use_10_for_ms; |
1563 | int header_length; | 1664 | int header_length; |
1665 | int result; | ||
1666 | struct scsi_sense_hdr my_sshdr; | ||
1564 | 1667 | ||
1565 | memset(data, 0, sizeof(*data)); | 1668 | memset(data, 0, sizeof(*data)); |
1566 | memset(&cmd[0], 0, 12); | 1669 | memset(&cmd[0], 0, 12); |
1567 | cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */ | 1670 | cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */ |
1568 | cmd[2] = modepage; | 1671 | cmd[2] = modepage; |
1569 | 1672 | ||
1673 | /* caller might not be interested in sense, but we need it */ | ||
1674 | if (!sshdr) | ||
1675 | sshdr = &my_sshdr; | ||
1676 | |||
1570 | retry: | 1677 | retry: |
1571 | use_10_for_ms = sreq->sr_device->use_10_for_ms; | 1678 | use_10_for_ms = sdev->use_10_for_ms; |
1572 | 1679 | ||
1573 | if (use_10_for_ms) { | 1680 | if (use_10_for_ms) { |
1574 | if (len < 8) | 1681 | if (len < 8) |
@@ -1586,36 +1693,31 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage, | |||
1586 | header_length = 4; | 1693 | header_length = 4; |
1587 | } | 1694 | } |
1588 | 1695 | ||
1589 | sreq->sr_cmd_len = 0; | ||
1590 | memset(sreq->sr_sense_buffer, 0, sizeof(sreq->sr_sense_buffer)); | ||
1591 | sreq->sr_data_direction = DMA_FROM_DEVICE; | ||
1592 | |||
1593 | memset(buffer, 0, len); | 1696 | memset(buffer, 0, len); |
1594 | 1697 | ||
1595 | scsi_wait_req(sreq, cmd, buffer, len, timeout, retries); | 1698 | result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, |
1699 | sshdr, timeout, retries); | ||
1596 | 1700 | ||
1597 | /* This code looks awful: what it's doing is making sure an | 1701 | /* This code looks awful: what it's doing is making sure an |
1598 | * ILLEGAL REQUEST sense return identifies the actual command | 1702 | * ILLEGAL REQUEST sense return identifies the actual command |
1599 | * byte as the problem. MODE_SENSE commands can return | 1703 | * byte as the problem. MODE_SENSE commands can return |
1600 | * ILLEGAL REQUEST if the code page isn't supported */ | 1704 | * ILLEGAL REQUEST if the code page isn't supported */ |
1601 | 1705 | ||
1602 | if (use_10_for_ms && !scsi_status_is_good(sreq->sr_result) && | 1706 | if (use_10_for_ms && !scsi_status_is_good(result) && |
1603 | (driver_byte(sreq->sr_result) & DRIVER_SENSE)) { | 1707 | (driver_byte(result) & DRIVER_SENSE)) { |
1604 | struct scsi_sense_hdr sshdr; | 1708 | if (scsi_sense_valid(sshdr)) { |
1605 | 1709 | if ((sshdr->sense_key == ILLEGAL_REQUEST) && | |
1606 | if (scsi_request_normalize_sense(sreq, &sshdr)) { | 1710 | (sshdr->asc == 0x20) && (sshdr->ascq == 0)) { |
1607 | if ((sshdr.sense_key == ILLEGAL_REQUEST) && | ||
1608 | (sshdr.asc == 0x20) && (sshdr.ascq == 0)) { | ||
1609 | /* | 1711 | /* |
1610 | * Invalid command operation code | 1712 | * Invalid command operation code |
1611 | */ | 1713 | */ |
1612 | sreq->sr_device->use_10_for_ms = 0; | 1714 | sdev->use_10_for_ms = 0; |
1613 | goto retry; | 1715 | goto retry; |
1614 | } | 1716 | } |
1615 | } | 1717 | } |
1616 | } | 1718 | } |
1617 | 1719 | ||
1618 | if(scsi_status_is_good(sreq->sr_result)) { | 1720 | if(scsi_status_is_good(result)) { |
1619 | data->header_length = header_length; | 1721 | data->header_length = header_length; |
1620 | if(use_10_for_ms) { | 1722 | if(use_10_for_ms) { |
1621 | data->length = buffer[0]*256 + buffer[1] + 2; | 1723 | data->length = buffer[0]*256 + buffer[1] + 2; |
@@ -1632,73 +1734,31 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage, | |||
1632 | } | 1734 | } |
1633 | } | 1735 | } |
1634 | 1736 | ||
1635 | return sreq->sr_result; | 1737 | return result; |
1636 | } | ||
1637 | EXPORT_SYMBOL(__scsi_mode_sense); | ||
1638 | |||
1639 | /** | ||
1640 | * scsi_mode_sense - issue a mode sense, falling back from 10 to | ||
1641 | * six bytes if necessary. | ||
1642 | * @sdev: scsi device to send command to. | ||
1643 | * @dbd: set if mode sense will disable block descriptors in the return | ||
1644 | * @modepage: mode page being requested | ||
1645 | * @buffer: request buffer (may not be smaller than eight bytes) | ||
1646 | * @len: length of request buffer. | ||
1647 | * @timeout: command timeout | ||
1648 | * @retries: number of retries before failing | ||
1649 | * | ||
1650 | * Returns zero if unsuccessful, or the header offset (either 4 | ||
1651 | * or 8 depending on whether a six or ten byte command was | ||
1652 | * issued) if successful. | ||
1653 | **/ | ||
1654 | int | ||
1655 | scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, | ||
1656 | unsigned char *buffer, int len, int timeout, int retries, | ||
1657 | struct scsi_mode_data *data) | ||
1658 | { | ||
1659 | struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL); | ||
1660 | int ret; | ||
1661 | |||
1662 | if (!sreq) | ||
1663 | return -1; | ||
1664 | |||
1665 | ret = __scsi_mode_sense(sreq, dbd, modepage, buffer, len, | ||
1666 | timeout, retries, data); | ||
1667 | |||
1668 | scsi_release_request(sreq); | ||
1669 | |||
1670 | return ret; | ||
1671 | } | 1738 | } |
1672 | EXPORT_SYMBOL(scsi_mode_sense); | 1739 | EXPORT_SYMBOL(scsi_mode_sense); |
1673 | 1740 | ||
1674 | int | 1741 | int |
1675 | scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries) | 1742 | scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries) |
1676 | { | 1743 | { |
1677 | struct scsi_request *sreq; | ||
1678 | char cmd[] = { | 1744 | char cmd[] = { |
1679 | TEST_UNIT_READY, 0, 0, 0, 0, 0, | 1745 | TEST_UNIT_READY, 0, 0, 0, 0, 0, |
1680 | }; | 1746 | }; |
1747 | struct scsi_sense_hdr sshdr; | ||
1681 | int result; | 1748 | int result; |
1682 | 1749 | ||
1683 | sreq = scsi_allocate_request(sdev, GFP_KERNEL); | 1750 | result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, &sshdr, |
1684 | if (!sreq) | 1751 | timeout, retries); |
1685 | return -ENOMEM; | ||
1686 | |||
1687 | sreq->sr_data_direction = DMA_NONE; | ||
1688 | scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries); | ||
1689 | 1752 | ||
1690 | if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && sdev->removable) { | 1753 | if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) { |
1691 | struct scsi_sense_hdr sshdr; | ||
1692 | 1754 | ||
1693 | if ((scsi_request_normalize_sense(sreq, &sshdr)) && | 1755 | if ((scsi_sense_valid(&sshdr)) && |
1694 | ((sshdr.sense_key == UNIT_ATTENTION) || | 1756 | ((sshdr.sense_key == UNIT_ATTENTION) || |
1695 | (sshdr.sense_key == NOT_READY))) { | 1757 | (sshdr.sense_key == NOT_READY))) { |
1696 | sdev->changed = 1; | 1758 | sdev->changed = 1; |
1697 | sreq->sr_result = 0; | 1759 | result = 0; |
1698 | } | 1760 | } |
1699 | } | 1761 | } |
1700 | result = sreq->sr_result; | ||
1701 | scsi_release_request(sreq); | ||
1702 | return result; | 1762 | return result; |
1703 | } | 1763 | } |
1704 | EXPORT_SYMBOL(scsi_test_unit_ready); | 1764 | EXPORT_SYMBOL(scsi_test_unit_ready); |