LCOV - code coverage report
Current view: top level - include/scsi - scsi_tcq.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 3 0.0 %
Date: 2014-02-18 Functions: 0 0 -
Branches: 0 6 0.0 %

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

Generated by: LCOV version 1.9