LCOV - code coverage report
Current view: top level - lkbce/include/scsi - scsi_tcq.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 7 7 100.0 %
Date: 2017-01-25 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #ifndef _SCSI_SCSI_TCQ_H
       2             : #define _SCSI_SCSI_TCQ_H
       3             : 
       4             : #include <linux/blkdev.h>
       5             : #include <scsi/scsi_cmnd.h>
       6             : #include <scsi/scsi_device.h>
       7             : #include <scsi/scsi_host.h>
       8             : 
       9             : #define MSG_SIMPLE_TAG  0x20
      10             : #define MSG_HEAD_TAG    0x21
      11             : #define MSG_ORDERED_TAG 0x22
      12             : 
      13             : #define SCSI_NO_TAG     (-1)    /* identify no tag in use */
      14             : 
      15             : 
      16             : #ifdef CONFIG_BLOCK
      17             : 
      18             : /**
      19             :  * scsi_get_tag_type - get the type of tag the device supports
      20             :  * @sdev:       the scsi device
      21             :  *
      22             :  * Notes:
      23             :  *      If the drive only supports simple tags, returns MSG_SIMPLE_TAG
      24             :  *      if it supports all tag types, returns MSG_ORDERED_TAG.
      25             :  */
      26             : static inline int scsi_get_tag_type(struct scsi_device *sdev)
      27             : {
      28           2 :         if (!sdev->tagged_supported)
      29           1 :                 return 0;
      30           2 :         if (sdev->ordered_tags)
      31           1 :                 return MSG_ORDERED_TAG;
      32           2 :         if (sdev->simple_tags)
      33           1 :                 return MSG_SIMPLE_TAG;
      34           1 :         return 0;
      35             : }
      36             : 
      37             : static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag)
      38             : {
      39             :         switch (tag) {
      40             :         case MSG_ORDERED_TAG:
      41             :                 sdev->ordered_tags = 1;
      42             :                 /* fall through */
      43             :         case MSG_SIMPLE_TAG:
      44             :                 sdev->simple_tags = 1;
      45             :                 break;
      46             :         case 0:
      47             :                 /* fall through */
      48             :         default:
      49             :                 sdev->ordered_tags = 0;
      50             :                 sdev->simple_tags = 0;
      51             :                 break;
      52             :         }
      53             : }
      54             : /**
      55             :  * scsi_activate_tcq - turn on tag command queueing
      56             :  * @SDpnt:      device to turn on TCQ for
      57             :  * @depth:      queue depth
      58             :  *
      59             :  * Notes:
      60             :  *      Eventually, I hope depth would be the maximum depth
      61             :  *      the device could cope with and the real queue depth
      62             :  *      would be adjustable from 0 to depth.
      63             :  **/
      64             : static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
      65             : {
      66             :         if (!sdev->tagged_supported)
      67             :                 return;
      68             : 
      69             :         if (!blk_queue_tagged(sdev->request_queue))
      70             :                 blk_queue_init_tags(sdev->request_queue, depth,
      71             :                                     sdev->host->bqt);
      72             : 
      73             :         scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
      74             : }
      75             : 
      76             : /**
      77             :  * scsi_deactivate_tcq - turn off tag command queueing
      78             :  * @SDpnt:      device to turn off TCQ for
      79             :  **/
      80             : static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
      81             : {
      82             :         if (blk_queue_tagged(sdev->request_queue))
      83             :                 blk_queue_free_tags(sdev->request_queue);
      84             :         scsi_adjust_queue_depth(sdev, 0, depth);
      85             : }
      86             : 
      87             : /**
      88             :  * scsi_populate_tag_msg - place a tag message in a buffer
      89             :  * @SCpnt:      pointer to the Scsi_Cmnd for the tag
      90             :  * @msg:        pointer to the area to place the tag
      91             :  *
      92             :  * Notes:
      93             :  *      designed to create the correct type of tag message for the 
      94             :  *      particular request.  Returns the size of the tag message.
      95             :  *      May return 0 if TCQ is disabled for this device.
      96             :  **/
      97             : static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
      98             : {
      99             :         struct request *req = cmd->request;
     100             :         struct scsi_device *sdev = cmd->device;
     101             : 
     102             :         if (blk_rq_tagged(req)) {
     103             :                 if (sdev->ordered_tags && req->cmd_flags & REQ_HARDBARRIER)
     104             :                         *msg++ = MSG_ORDERED_TAG;
     105             :                 else
     106             :                         *msg++ = MSG_SIMPLE_TAG;
     107             :                 *msg++ = req->tag;
     108             :                 return 2;
     109             :         }
     110             : 
     111             :         return 0;
     112             : }
     113             : 
     114             : /**
     115             :  * scsi_find_tag - find a tagged command by device
     116             :  * @SDpnt:      pointer to the ScSI device
     117             :  * @tag:        the tag number
     118             :  *
     119             :  * Notes:
     120             :  *      Only works with tags allocated by the generic blk layer.
     121             :  **/
     122             : static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
     123             : {
     124             : 
     125             :         struct request *req;
     126             : 
     127             :         if (tag != SCSI_NO_TAG) {
     128             :                 req = blk_queue_find_tag(sdev->request_queue, tag);
     129             :                 return req ? (struct scsi_cmnd *)req->special : NULL;
     130             :         }
     131             : 
     132             :         /* single command, look in space */
     133             :         return sdev->current_cmnd;
     134             : }
     135             : 
     136             : /**
     137             :  * scsi_init_shared_tag_map - create a shared tag map
     138             :  * @shost:      the host to share the tag map among all devices
     139             :  * @depth:      the total depth of the map
     140             :  */
     141             : static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
     142             : {
     143             :         /*
     144             :          * If the shared tag map isn't already initialized, do it now.
     145             :          * This saves callers from having to check ->bqt when setting up
     146             :          * devices on the shared host (for libata)
     147             :          */
     148             :         if (!shost->bqt) {
     149             :                 shost->bqt = blk_init_tags(depth);
     150             :                 if (!shost->bqt)
     151             :                         return -ENOMEM;
     152             :         }
     153             : 
     154             :         return 0;
     155             : }
     156             : 
     157             : /**
     158             :  * scsi_host_find_tag - find the tagged command by host
     159             :  * @shost:      pointer to scsi_host
     160             :  * @tag:        tag of the scsi_cmnd
     161             :  *
     162             :  * Notes:
     163             :  *      Only works with tags allocated by the generic blk layer.
     164             :  **/
     165             : static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost,
     166             :                                                 int tag)
     167             : {
     168             :         struct request *req;
     169             : 
     170             :         if (tag != SCSI_NO_TAG) {
     171             :                 req = blk_map_queue_find_tag(shost->bqt, tag);
     172             :                 return req ? (struct scsi_cmnd *)req->special : NULL;
     173             :         }
     174             :         return NULL;
     175             : }
     176             : 
     177             : #endif /* CONFIG_BLOCK */
     178             : #endif /* _SCSI_SCSI_TCQ_H */

Generated by: LCOV version 1.10