Release 4.11 drivers/scsi/esp_scsi.c
/* esp_scsi.c: ESP SCSI driver.
*
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/completion.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/irqreturn.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_transport_spi.h>
#include "esp_scsi.h"
#define DRV_MODULE_NAME "esp"
#define PFX DRV_MODULE_NAME ": "
#define DRV_VERSION "2.000"
#define DRV_MODULE_RELDATE "April 19, 2007"
/* SCSI bus reset settle time in seconds. */
static int esp_bus_reset_settle = 3;
static u32 esp_debug;
#define ESP_DEBUG_INTR 0x00000001
#define ESP_DEBUG_SCSICMD 0x00000002
#define ESP_DEBUG_RESET 0x00000004
#define ESP_DEBUG_MSGIN 0x00000008
#define ESP_DEBUG_MSGOUT 0x00000010
#define ESP_DEBUG_CMDDONE 0x00000020
#define ESP_DEBUG_DISCONNECT 0x00000040
#define ESP_DEBUG_DATASTART 0x00000080
#define ESP_DEBUG_DATADONE 0x00000100
#define ESP_DEBUG_RECONNECT 0x00000200
#define ESP_DEBUG_AUTOSENSE 0x00000400
#define ESP_DEBUG_EVENT 0x00000800
#define ESP_DEBUG_COMMAND 0x00001000
#define esp_log_intr(f, a...) \
do { if (esp_debug & ESP_DEBUG_INTR) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_reset(f, a...) \
do { if (esp_debug & ESP_DEBUG_RESET) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_msgin(f, a...) \
do { if (esp_debug & ESP_DEBUG_MSGIN) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_msgout(f, a...) \
do { if (esp_debug & ESP_DEBUG_MSGOUT) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_cmddone(f, a...) \
do { if (esp_debug & ESP_DEBUG_CMDDONE) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_disconnect(f, a...) \
do { if (esp_debug & ESP_DEBUG_DISCONNECT) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_datastart(f, a...) \
do { if (esp_debug & ESP_DEBUG_DATASTART) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_datadone(f, a...) \
do { if (esp_debug & ESP_DEBUG_DATADONE) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_reconnect(f, a...) \
do { if (esp_debug & ESP_DEBUG_RECONNECT) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_autosense(f, a...) \
do { if (esp_debug & ESP_DEBUG_AUTOSENSE) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_event(f, a...) \
do { if (esp_debug & ESP_DEBUG_EVENT) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_command(f, a...) \
do { if (esp_debug & ESP_DEBUG_COMMAND) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_read8(REG) esp->ops->esp_read8(esp, REG)
#define esp_write8(VAL,REG) esp->ops->esp_write8(esp, VAL, REG)
static void esp_log_fill_regs(struct esp *esp,
struct esp_event_ent *p)
{
p->sreg = esp->sreg;
p->seqreg = esp->seqreg;
p->sreg2 = esp->sreg2;
p->ireg = esp->ireg;
p->select_state = esp->select_state;
p->event = esp->event;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 64 | 100.00% | 1 | 100.00% |
Total | 64 | 100.00% | 1 | 100.00% |
void scsi_esp_cmd(struct esp *esp, u8 val)
{
struct esp_event_ent *p;
int idx = esp->esp_event_cur;
p = &esp->esp_event_log[idx];
p->type = ESP_EVENT_TYPE_CMD;
p->val = val;
esp_log_fill_regs(esp, p);
esp->esp_event_cur = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);
esp_log_command("cmd[%02x]\n", val);
esp_write8(val, ESP_CMD);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 77 | 91.67% | 1 | 50.00% |
Hannes Reinecke | 7 | 8.33% | 1 | 50.00% |
Total | 84 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(scsi_esp_cmd);
static void esp_send_dma_cmd(struct esp *esp, int len, int max_len, int cmd)
{
if (esp->flags & ESP_FLAG_USE_FIFO) {
int i;
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
for (i = 0; i < len; i++)
esp_write8(esp->command_block[i], ESP_FDATA);
scsi_esp_cmd(esp, cmd);
} else {
if (esp->rev == FASHME)
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
cmd |= ESP_CMD_DMA;
esp->ops->send_dma_cmd(esp, esp->command_block_dma,
len, max_len, 0, cmd);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Hannes Reinecke | 115 | 100.00% | 1 | 100.00% |
Total | 115 | 100.00% | 1 | 100.00% |
static void esp_event(struct esp *esp, u8 val)
{
struct esp_event_ent *p;
int idx = esp->esp_event_cur;
p = &esp->esp_event_log[idx];
p->type = ESP_EVENT_TYPE_EVENT;
p->val = val;
esp_log_fill_regs(esp, p);
esp->esp_event_cur = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);
esp->event = val;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 77 | 100.00% | 1 | 100.00% |
Total | 77 | 100.00% | 1 | 100.00% |
static void esp_dump_cmd_log(struct esp *esp)
{
int idx = esp->esp_event_cur;
int stop = idx;
shost_printk(KERN_INFO, esp->host, "Dumping command log\n");
do {
struct esp_event_ent *p = &esp->esp_event_log[idx];
shost_printk(KERN_INFO, esp->host,
"ent[%d] %s val[%02x] sreg[%02x] seqreg[%02x] "
"sreg2[%02x] ireg[%02x] ss[%02x] event[%02x]\n",
idx,
p->type == ESP_EVENT_TYPE_CMD ? "CMD" : "EVENT",
p->val, p->sreg, p->seqreg,
p->sreg2, p->ireg, p->select_state, p->event);
idx = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);
} while (idx != stop);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 99 | 80.49% | 1 | 50.00% |
Hannes Reinecke | 24 | 19.51% | 1 | 50.00% |
Total | 123 | 100.00% | 2 | 100.00% |
static void esp_flush_fifo(struct esp *esp)
{
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
if (esp->rev == ESP236) {
int lim = 1000;
while (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES) {
if (--lim == 0) {
shost_printk(KERN_ALERT, esp->host,
"ESP_FF_BYTES will not clear!\n");
break;
}
udelay(1);
}
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 62 | 88.57% | 1 | 50.00% |
Hannes Reinecke | 8 | 11.43% | 1 | 50.00% |
Total | 70 | 100.00% | 2 | 100.00% |
static void hme_read_fifo(struct esp *esp)
{
int fcnt = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
int idx = 0;
while (fcnt--) {
esp->fifo[idx++] = esp_read8(ESP_FDATA);
esp->fifo[idx++] = esp_read8(ESP_FDATA);
}
if (esp->sreg2 & ESP_STAT2_F1BYTE) {
esp_write8(0, ESP_FDATA);
esp->fifo[idx++] = esp_read8(ESP_FDATA);
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
}
esp->fifo_cnt = idx;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 102 | 100.00% | 1 | 100.00% |
Total | 102 | 100.00% | 1 | 100.00% |
static void esp_set_all_config3(struct esp *esp, u8 val)
{
int i;
for (i = 0; i < ESP_MAX_TARGET; i++)
esp->target[i].esp_config3 = val;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 41 | 100.00% | 1 | 100.00% |
Total | 41 | 100.00% | 1 | 100.00% |
/* Reset the ESP chip, _not_ the SCSI bus. */
static void esp_reset_esp(struct esp *esp)
{
u8 family_code, version;
/* Now reset the ESP chip */
scsi_esp_cmd(esp, ESP_CMD_RC);
scsi_esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);
if (esp->rev == FAST)
esp_write8(ESP_CONFIG2_FENAB, ESP_CFG2);
scsi_esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);
/* This is the only point at which it is reliable to read
* the ID-code for a fast ESP chip variants.
*/
esp->max_period = ((35 * esp->ccycle) / 1000);
if (esp->rev == FAST) {
version = esp_read8(ESP_UID);
family_code = (version & 0xf8) >> 3;
if (family_code == 0x02)
esp->rev = FAS236;
else if (family_code == 0x0a)
esp->rev = FASHME; /* Version is usually '5'. */
else
esp->rev = FAS100A;
esp->min_period = ((4 * esp->ccycle) / 1000);
} else {
esp->min_period = ((5 * esp->ccycle) / 1000);
}
if (esp->rev == FAS236) {
/*
* The AM53c974 chip returns the same ID as FAS236;
* try to configure glitch eater.
*/
u8 config4 = ESP_CONFIG4_GE1;
esp_write8(config4, ESP_CFG4);
config4 = esp_read8(ESP_CFG4);
if (config4 & ESP_CONFIG4_GE1) {
esp->rev = PCSCSI;
esp_write8(esp->config4, ESP_CFG4);
}
}
esp->max_period = (esp->max_period + 3)>>2;
esp->min_period = (esp->min_period + 3)>>2;
esp_write8(esp->config1, ESP_CFG1);
switch (esp->rev) {
case ESP100:
/* nothing to do */
break;
case ESP100A:
esp_write8(esp->config2, ESP_CFG2);
break;
case ESP236:
/* Slow 236 */
esp_write8(esp->config2, ESP_CFG2);
esp->prev_cfg3 = esp->target[0].esp_config3;
esp_write8(esp->prev_cfg3, ESP_CFG3);
break;
case FASHME:
esp->config2 |= (ESP_CONFIG2_HME32 | ESP_CONFIG2_HMEFENAB);
/* fallthrough... */
case FAS236:
case PCSCSI:
/* Fast 236, AM53c974 or HME */
esp_write8(esp->config2, ESP_CFG2);
if (esp->rev == FASHME) {
u8 cfg3 = esp->target[0].esp_config3;
cfg3 |= ESP_CONFIG3_FCLOCK | ESP_CONFIG3_OBPUSH;
if (esp->scsi_id >= 8)
cfg3 |= ESP_CONFIG3_IDBIT3;
esp_set_all_config3(esp, cfg3);
} else {
u32 cfg3 = esp->target[0].esp_config3;
cfg3 |= ESP_CONFIG3_FCLK;
esp_set_all_config3(esp, cfg3);
}
esp->prev_cfg3 = esp->target[0].esp_config3;
esp_write8(esp->prev_cfg3, ESP_CFG3);
if (esp->rev == FASHME) {
esp->radelay = 80;
} else {
if (esp->flags & ESP_FLAG_DIFFERENTIAL)
esp->radelay = 0;
else
esp->radelay = 96;
}
break;
case FAS100A:
/* Fast 100a */
esp_write8(esp->config2, ESP_CFG2);
esp_set_all_config3(esp,
(esp->target[0].esp_config3 |
ESP_CONFIG3_FCLOCK));
esp->prev_cfg3 = esp->target[0].esp_config3;
esp_write8(esp->prev_cfg3, ESP_CFG3);
esp->radelay = 32;
break;
default:
break;
}
/* Reload the configuration registers */
esp_write8(esp->cfact, ESP_CFACT);
esp->prev_stp = 0;
esp_write8(esp->prev_stp, ESP_STP);
esp->prev_soff = 0;
esp_write8(esp->prev_soff, ESP_SOFF);
esp_write8(esp->neg_defp, ESP_TIMEO);
/* Eat any bitrot in the chip */
esp_read8(ESP_INTRPT);
udelay(100);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 552 | 90.64% | 2 | 66.67% |
Hannes Reinecke | 57 | 9.36% | 1 | 33.33% |
Total | 609 | 100.00% | 3 | 100.00% |
static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
{
struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
struct scatterlist *sg = scsi_sglist(cmd);
int dir = cmd->sc_data_direction;
int total, i;
if (dir == DMA_NONE)
return;
spriv->u.num_sg = esp->ops->map_sg(esp, sg, scsi_sg_count(cmd), dir);
spriv->cur_residue = sg_dma_len(sg);
spriv->cur_sg = sg;
total = 0;
for (i = 0; i < spriv->u.num_sg; i++)
total += sg_dma_len(&sg[i]);
spriv->tot_residue = total;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 126 | 95.45% | 1 | 50.00% |
FUJITA Tomonori | 6 | 4.55% | 1 | 50.00% |
Total | 132 | 100.00% | 2 | 100.00% |
static dma_addr_t esp_cur_dma_addr(struct esp_cmd_entry *ent,
struct scsi_cmnd *cmd)
{
struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);
if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
return ent->sense_dma +
(ent->sense_ptr - cmd->sense_buffer);
}
return sg_dma_address(p->cur_sg) +
(sg_dma_len(p->cur_sg) -
p->cur_residue);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 72 | 100.00% | 1 | 100.00% |
Total | 72 | 100.00% | 1 | 100.00% |
static unsigned int esp_cur_dma_len(struct esp_cmd_entry *ent,
struct scsi_cmnd *cmd)
{
struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);
if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
return SCSI_SENSE_BUFFERSIZE -
(ent->sense_ptr - cmd->sense_buffer);
}
return p->cur_residue;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 55 | 100.00% | 1 | 100.00% |
Total | 55 | 100.00% | 1 | 100.00% |
static void esp_advance_dma(struct esp *esp, struct esp_cmd_entry *ent,
struct scsi_cmnd *cmd, unsigned int len)
{
struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);
if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
ent->sense_ptr += len;
return;
}
p->cur_residue -= len;
p->tot_residue -= len;
if (p->cur_residue < 0 || p->tot_residue < 0) {
shost_printk(KERN_ERR, esp->host,
"Data transfer overflow.\n");
shost_printk(KERN_ERR, esp->host,
"cur_residue[%d] tot_residue[%d] len[%u]\n",
p->cur_residue, p->tot_residue, len);
p->cur_residue = 0;
p->tot_residue = 0;
}
if (!p->cur_residue && p->tot_residue) {
p->cur_sg++;
p->cur_residue = sg_dma_len(p->cur_sg);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 130 | 84.97% | 1 | 50.00% |
Hannes Reinecke | 23 | 15.03% | 1 | 50.00% |
Total | 153 | 100.00% | 2 | 100.00% |
static void esp_unmap_dma(struct esp *esp, struct scsi_cmnd *cmd)
{
struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
int dir = cmd->sc_data_direction;
if (dir == DMA_NONE)
return;
esp->ops->unmap_sg(esp, scsi_sglist(cmd), spriv->u.num_sg, dir);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 59 | 95.16% | 1 | 50.00% |
FUJITA Tomonori | 3 | 4.84% | 1 | 50.00% |
Total | 62 | 100.00% | 2 | 100.00% |
static void esp_save_pointers(struct esp *esp, struct esp_cmd_entry *ent)
{
struct scsi_cmnd *cmd = ent->cmd;
struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
ent->saved_sense_ptr = ent->sense_ptr;
return;
}
ent->saved_cur_residue = spriv->cur_residue;
ent->saved_cur_sg = spriv->cur_sg;
ent->saved_tot_residue = spriv->tot_residue;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 78 | 100.00% | 1 | 100.00% |
Total | 78 | 100.00% | 1 | 100.00% |
static void esp_restore_pointers(struct esp *esp, struct esp_cmd_entry *ent)
{
struct scsi_cmnd *cmd = ent->cmd;
struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
ent->sense_ptr = ent->saved_sense_ptr;
return;
}
spriv->cur_residue = ent->saved_cur_residue;
spriv->cur_sg = ent->saved_cur_sg;
spriv->tot_residue = ent->saved_tot_residue;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 78 | 100.00% | 1 | 100.00% |
Total | 78 | 100.00% | 1 | 100.00% |
static void esp_check_command_len(struct esp *esp, struct scsi_cmnd *cmd)
{
if (cmd->cmd_len == 6 ||
cmd->cmd_len == 10 ||
cmd->cmd_len == 12) {
esp->flags &= ~ESP_FLAG_DOING_SLOWCMD;
} else {
esp->flags |= ESP_FLAG_DOING_SLOWCMD;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 54 | 100.00% | 1 | 100.00% |
Total | 54 | 100.00% | 1 | 100.00% |
static void esp_write_tgt_config3(struct esp *esp, int tgt)
{
if (esp->rev > ESP100A) {
u8 val = esp->target[tgt].esp_config3;
if (val != esp->prev_cfg3) {
esp->prev_cfg3 = val;
esp_write8(val, ESP_CFG3);
}
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 59 | 100.00% | 1 | 100.00% |
Total | 59 | 100.00% | 1 | 100.00% |
static void esp_write_tgt_sync(struct esp *esp, int tgt)
{
u8 off = esp->target[tgt].esp_offset;
u8 per = esp->target[tgt].esp_period;
if (off != esp->prev_soff) {
esp->prev_soff = off;
esp_write8(off, ESP_SOFF);
}
if (per != esp->prev_stp) {
esp->prev_stp = per;
esp_write8(per, ESP_STP);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 84 | 100.00% | 1 | 100.00% |
Total | 84 | 100.00% | 1 | 100.00% |
static u32 esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len)
{
if (esp->rev == FASHME) {
/* Arbitrary segment boundaries, 24-bit counts. */
if (dma_len > (1U << 24))
dma_len = (1U << 24);
} else {
u32 base, end;
/* ESP chip limits other variants by 16-bits of transfer
* count. Actually on FAS100A and FAS236 we could get
* 24-bits of transfer count by enabling ESP_CONFIG2_FENAB
* in the ESP_CFG2 register but that causes other unwanted
* changes so we don't use it currently.
*/
if (dma_len > (1U << 16))
dma_len = (1U << 16);
/* All of the DMA variants hooked up to these chips
* cannot handle crossing a 24-bit address boundary.
*/
base = dma_addr & ((1U << 24) - 1U);
end = base + dma_len;
if (end > (1U << 24))
end = (1U <<24);
dma_len = end - base;
}
return dma_len;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 121 | 100.00% | 1 | 100.00% |
Total | 121 | 100.00% | 1 | 100.00% |
static int esp_need_to_nego_wide(struct esp_target_data *tp)
{
struct scsi_target *target = tp->starget;
return spi_width(target) != tp->nego_goal_width;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 30 | 100.00% | 1 | 100.00% |
Total | 30 | 100.00% | 1 | 100.00% |
static int esp_need_to_nego_sync(struct esp_target_data *tp)
{
struct scsi_target *target = tp->starget;
/* When offset is zero, period is "don't care". */
if (!spi_offset(target) && !tp->nego_goal_offset)
return 0;
if (spi_offset(target) == tp->nego_goal_offset &&
spi_period(target) == tp->nego_goal_period)
return 0;
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 63 | 100.00% | 1 | 100.00% |
Total | 63 | 100.00% | 1 | 100.00% |
static int esp_alloc_lun_tag(struct esp_cmd_entry *ent,
struct esp_lun_data *lp)
{
if (!ent->orig_tag[0]) {
/* Non-tagged, slot already taken? */
if (lp->non_tagged_cmd)
return -EBUSY;
if (lp->hold) {
/* We are being held by active tagged
* commands.
*/
if (lp->num_tagged)
return -EBUSY;
/* Tagged commands completed, we can unplug
* the queue and run this untagged command.
*/
lp->hold = 0;
} else if (lp->num_tagged) {
/* Plug the queue until num_tagged decreases
* to zero in esp_free_lun_tag.
*/
lp->hold = 1;
return -EBUSY;
}
lp->non_tagged_cmd = ent;
return 0;
} else {
/* Tagged command, see if blocked by a
* non-tagged one.
*/
if (lp->non_tagged_cmd || lp->hold)
return -EBUSY;
}
BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]);
lp->tagged_cmds[ent->orig_tag[1]] = ent;
lp->num_tagged++;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 149 | 100.00% | 2 | 100.00% |
Total | 149 | 100.00% | 2 | 100.00% |
static void esp_free_lun_tag(struct esp_cmd_entry *ent,
struct esp_lun_data *lp)
{
if (ent->orig_tag[0]) {
BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent);
lp->tagged_cmds[ent->orig_tag[1]] = NULL;
lp->num_tagged--;
} else {
BUG_ON(lp->non_tagged_cmd != ent);
lp->non_tagged_cmd = NULL;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 81 | 100.00% | 2 | 100.00% |
Total | 81 | 100.00% | 2 | 100.00% |
/* When a contingent allegiance conditon is created, we force feed a
* REQUEST_SENSE command to the device to fetch the sense data. I
* tried many other schemes, relying on the scsi error handling layer
* to send out the REQUEST_SENSE automatically, but this was difficult
* to get right especially in the presence of applications like smartd
* which use SG_IO to send out their own REQUEST_SENSE commands.
*/
static void esp_autosense(struct esp *esp, struct esp_cmd_entry *ent)
{
struct scsi_cmnd *cmd = ent->cmd;
struct scsi_device *dev = cmd->device;
int tgt, lun;
u8 *p, val;
tgt = dev->id;
lun = dev->lun;
if (!ent->sense_ptr) {
esp_log_autosense("Doing auto-sense for tgt[%d] lun[%d]\n",
tgt, lun);
ent->sense_ptr = cmd->sense_buffer;
ent->sense_dma