Files
@ bd21c8aa7237
Branch filter:
Location: vmkdrivers/vmkdrivers/src_9/drivers/scsi/fnic/fnic_tag_map.c - annotation
bd21c8aa7237
5.1 KiB
text/x-csrc
ESXi-6.0.0b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 763922b5834e 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 763922b5834e 95e39e5412bd 763922b5834e 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 95e39e5412bd 763922b5834e 95e39e5412bd 763922b5834e 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e 95e39e5412bd 763922b5834e 763922b5834e 763922b5834e 763922b5834e 763922b5834e | /*
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
*
* This file is derived from block/blk-tag.c, scsi/scsi_tcq.h, bitops.h and
* others from Linux release 2.6.27-rc5, and shares copyright with the
* original authors (Jens Axboe and others).
*
* This program is free software; you may redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* [Insert appropriate license here when releasing outside of Cisco]
* $Id: fnic_tag_map.c 122966 2013-02-07 20:43:04Z hiralpat $
*/
#include "fnic_tag_map.h"
static int fnic_init_tag_map(struct fnic_host_tag *fht, int depth)
{
struct scsi_cmnd **tag_index = NULL;
unsigned long *tag_map = NULL;
int nr_ulongs;
tag_index = kzalloc(depth * sizeof(struct scsi_cmnd *), GFP_ATOMIC);
if (!tag_index)
return -ENOMEM;
/* goto fail; */
nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;
tag_map = kzalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
if (!tag_map)
goto fail;
fht->max_depth = depth;
fht->tag_index = tag_index;
fht->tag_map = tag_map;
fht->next_tag = 1;
return 0;
fail:
if (tag_index) {
kfree(tag_index);
}
if (tag_map) {
kfree(tag_map);
}
return -ENOMEM;
}
int fnic_init_shared_tag_map(struct Scsi_Host *shost, int depth)
{
struct fnic_host_tag *fht;
struct fc_lport *lp = shost_priv(shost);
struct fnic *fnic = lport_priv(lp);
fht = kmalloc(sizeof(struct fnic_host_tag), GFP_ATOMIC);
if (!fht)
goto fail;
if (fnic_init_tag_map(fht, depth))
goto fail;
fnic->tags = fht;
return 0;
fail:
kfree(fht);
return 1;
}
static inline void fnic_free_tags(struct fnic_host_tag *fht)
{
BUG_ON(find_first_bit(fht->tag_map, fht->max_depth) <
fht->max_depth);
kfree(fht->tag_index);
fht->tag_index = NULL;
kfree(fht->tag_map);
fht->tag_map = NULL;
kfree(fht);
}
void fnic_free_shared_tag_map(struct Scsi_Host *shost)
{
struct fc_lport *lp = shost_priv(shost);
struct fnic *fnic = lport_priv(lp);
fnic_free_tags(fnic->tags);
}
int fnic_host_start_tag(struct Scsi_Host *shost, struct scsi_cmnd *sc)
{
struct fc_lport *lp = shost_priv(shost);
struct fnic *fnic = lport_priv(lp);
struct fnic_host_tag *fht = fnic->tags;
struct fnic_stats fnic_stats = fnic->fnic_stats;
int tag;
unsigned long flags;
spin_lock_irqsave(&fnic->fnic_lock, flags);
tag = find_next_zero_bit(fht->tag_map, fht->max_depth, fht->next_tag);
if (((tag < 1) || (tag >= fht->max_depth)) && (fht->next_tag > 1)) {
tag = find_next_zero_bit(fht->tag_map, fht->max_depth, 1);
}
if ((tag < 1) || (tag >= fht->max_depth)) {
atomic64_inc(&fnic_stats.io_stats.tag_alloc_failures);
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
printk(KERN_ERR "Tag allocation failure next_tag (0x%x)\n",
fht->next_tag);
return SCSI_NO_TAG;
}
fht->next_tag = (tag < (fht->max_depth - 1)) ? tag + 1 : 1;
set_bit(tag, fht->tag_map);
fht->tag_index[tag] = sc;
CMD_TAG(sc) = tag;
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
return tag;
}
void fnic_host_end_tag(struct Scsi_Host *shost, struct scsi_cmnd *sc)
{
struct fc_lport *lp = shost_priv(shost);
struct fnic *fnic = lport_priv(lp);
struct fnic_host_tag *fht = fnic->tags;
int tag = CMD_TAG(sc);
unsigned long flags;
BUG_ON(tag == SCSI_NO_TAG);
if (unlikely((tag < 1) || (tag >= fht->max_depth))) {
printk(KERN_ERR "Tag 0x%x is out of range for sc 0x%p\n",
tag, sc);
return;
}
spin_lock_irqsave(&fnic->fnic_lock, flags);
if (unlikely(fht->tag_index[tag] == NULL)) {
printk(KERN_ERR "Tag 0x%x is missing sc 0x%p\n",
tag, sc);
}
if (unlikely(fht->tag_index[tag] != sc)) {
printk(KERN_ERR "Tag 0x%x does not match sc 0x%p 0x%p\n",
tag, sc, fht->tag_index[tag]);
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
return;
}
fht->tag_index[tag] = NULL;
CMD_TAG(sc) = SCSI_NO_TAG;
if (unlikely(!test_bit(tag, fht->tag_map))) {
printk(KERN_ERR "Attempt to clear non-busy tag (0x%x)\n", tag);
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
return;
}
clear_bit(tag, fht->tag_map);
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
}
static inline struct scsi_cmnd *fnic_find_tag(struct fnic_host_tag *fht,
int tag)
{
/* Called with fnic_lock held */
if (unlikely(fht == NULL || tag >= fht->max_depth || tag < 1))
return NULL;
return fht->tag_index[tag];
}
struct scsi_cmnd *fnic_host_find_tag(struct Scsi_Host *shost, int tag)
{
struct fc_lport *lp = shost_priv(shost);
struct fnic *fnic = lport_priv(lp);
/* Called with fnic_lock held */
if (tag != SCSI_NO_TAG)
return fnic_find_tag(fnic->tags, tag);
return NULL;
}
|