Current code allocates a dma-able sense buffer for every scsi command.
This is in 99.9% of cases a waste because:
- Most commands end successfully and do not need any sense space.
- most LLDs have the sense information already in their private data
and do not DMA this information. the sense can go directly to ULD's
buffer.
- Drivers that do synchronous REQUEST_SENSE through the scs_eh_prep_cmnd
mechanism need only one dma buffer per target. (contingent allegiance
condition)
This leaves us with a very few drivers that need dma-able sense-buffer
pre-allocated
per-command. These drivers set the .pre_allocate_sense flag in thier host
template
and the mid-layer will make sure a sense buffer is allocated for them.
So:
- Removed the global sense mem_cache and sense allocation per command.
- Add a per-host sense mempool_t of buffer-size specified by host template in
.sense_buffsize. If .sense_buffsize is not set then no mempool_t is not
allocated.
(Note: This is true for the majority of drivers.)
- If host does not have .pre_allocate_sense set then a reserved sense buffer
is
allocated per scsi-target (LUN).
- If host has .pre_allocate_sense set then a sense buffer is allocated in
get_command() and the code behaves like today.
- Drivers that need a dma sense buffer call
scsi_make_sense()/scsi_return_sense()
Theses drivers where already converted. Here the implementation will
allocate
the sense buffer from above per-host pool. Subsequent calls to
scsi_make_sense()
will return the same buffer. The first call to scsi_return_sense() will do
the
scsi_eh_cpy_sense(), and return the buffer to free store. Subsequent calls
will do nothing.
- The scsi_eh_prep_cmnd()/scsi_eh_return_cmnd() are converted to use the
scsi_make_sense()/scsi_return_sense(). Since these drivers set for
.sense_buffsize
but with .pre_allocate_sense not set, a pre-allocated sense buffer is
guarantied
per target even in a low memory condition situation.
- scsi_cmnd->sense_buffer is removed as it is no longer needed. And
scsi_eh_cpy_sense()
Will copy directly to ULD's supplied buffer at request->sense. Not maxing
->sense_max_len
and setting ->sense_len to copied count. So scsi_lib sense handling code
can also be
removed.
Signed-off-by: Boaz Harrosh <[EMAIL PROTECTED]>
---
drivers/scsi/scsi.c | 207 ++++++++++++++++++++++++++++++---------------
drivers/scsi/scsi_error.c | 45 +++++++---
drivers/scsi/scsi_lib.c | 15 +---
drivers/scsi/scsi_priv.h | 3 +-
drivers/scsi/scsi_scan.c | 6 ++
include/scsi/scsi_cmnd.h | 5 +-
include/scsi/scsi_eh.h | 14 +++-
include/scsi/scsi_host.h | 3 +
8 files changed, 194 insertions(+), 104 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index af29ccc..3f1bb9d 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -132,24 +132,20 @@ const char * scsi_device_type(unsigned type)
EXPORT_SYMBOL(scsi_device_type);
struct scsi_host_cmd_pool {
- struct kmem_cache *cmd_slab;
- struct kmem_cache *sense_slab;
- unsigned int users;
- char *cmd_name;
- char *sense_name;
- unsigned int slab_flags;
- gfp_t gfp_mask;
+ struct kmem_cache *slab;
+ unsigned int users;
+ char *name;
+ unsigned int slab_flags;
+ gfp_t gfp_mask;
};
static struct scsi_host_cmd_pool scsi_cmd_pool = {
- .cmd_name = "scsi_cmd_cache",
- .sense_name = "scsi_sense_cache",
+ .name = "scsi_cmd_cache",
.slab_flags = SLAB_HWCACHE_ALIGN,
};
static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
- .cmd_name = "scsi_cmd_cache(DMA)",
- .sense_name = "scsi_sense_cache(DMA)",
+ .name = "scsi_cmd_cache(DMA)",
.slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA,
.gfp_mask = __GFP_DMA,
};
@@ -167,10 +163,9 @@ static DEFINE_MUTEX(host_cmd_pool_mutex);
struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
- unsigned char *buf;
- cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab,
- gfp_mask | shost->cmd_pool->gfp_mask);
+ cmd = kmem_cache_alloc(shost->cmd_pool->slab,
+ gfp_mask | shost->cmd_pool->gfp_mask);
if (unlikely(!cmd)) {
unsigned long flags;
@@ -182,22 +177,6 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host
*shost, gfp_t gfp_mask)
list_del_init(&cmd->list);
}
spin_unlock_irqrestore(&shost->free_list_lock, flags);
-
- if (cmd) {
- buf = cmd->sense_buffer;
- memset(cmd, 0, sizeof(*cmd));
- cmd->sense_buffer = buf;
- }
- } else {
- buf = kmem_cache_alloc(shost->cmd_pool->sense_slab,
- gfp_mask | shost->cmd_pool->gfp_mask);
- if (likely(buf)) {
- memset(cmd, 0, sizeof(*cmd));
- cmd->sense_buffer = buf;
- } else {
- kmem_cache_free(shost->cmd_pool->cmd_slab, cmd);
- cmd = NULL;
- }
}
return cmd;
@@ -224,6 +203,7 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev,
gfp_t gfp_mask)
if (likely(cmd != NULL)) {
unsigned long flags;
+ memset(cmd, 0, sizeof(*cmd));
cmd->device = dev;
init_timer(&cmd->eh_timeout);
INIT_LIST_HEAD(&cmd->list);
@@ -231,6 +211,16 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device
*dev, gfp_t gfp_mask)
list_add_tail(&cmd->list, &dev->cmd_list);
spin_unlock_irqrestore(&dev->list_lock, flags);
cmd->jiffies_at_alloc = jiffies;
+
+ if (cmd->device->host->hostt->pre_allocate_sense) {
+ u8 *sb;
+
+ sb = scsi_make_sense(cmd);
+ if (unlikely(!sb)) {
+ scsi_put_command(cmd);
+ cmd = NULL;
+ }
+ }
} else
put_device(&dev->sdev_gendev);
@@ -258,9 +248,11 @@ void __scsi_put_command(struct Scsi_Host *shost, struct
scsi_cmnd *cmd,
spin_unlock_irqrestore(&shost->free_list_lock, flags);
if (likely(cmd != NULL)) {
- kmem_cache_free(shost->cmd_pool->sense_slab,
- cmd->sense_buffer);
- kmem_cache_free(shost->cmd_pool->cmd_slab, cmd);
+ if (cmd->dma_sense_check) {
+ WARN_ON(1); /* driver did not call scsi_return_sense */
+ scsi_return_sense(cmd, cmd->dma_sense_check);
+ }
+ kmem_cache_free(shost->cmd_pool->slab, cmd);
}
put_device(dev);
@@ -290,15 +282,106 @@ void scsi_put_command(struct scsi_cmnd *cmd)
}
EXPORT_SYMBOL(scsi_put_command);
+static int scsi_setup_sense_pool(struct Scsi_Host *shost)
+{
+ if (!shost->sense_buffsize && shost->hostt->sense_buffsize)
+ shost->sense_buffsize = shost->hostt->sense_buffsize;
+ else if (!shost->hostt->sense_buffsize)
+ return 0; /* Host doesn't need a sense_pool */
+
+ shost->sense_slab = kmem_cache_create(shost->hostt->name,
+ shost->sense_buffsize, 0, shost->cmd_pool->slab_flags, NULL);
+ if (!shost->sense_slab) {
+ printk(KERN_ERR "SCSI: can't init sense_slab %s\n",
+ shost->hostt->name);
+ return -ENOMEM;
+ }
+
+ shost->sense_pool = mempool_create_slab_pool(1, shost->sense_slab);
+ if (!shost->sense_pool) {
+ printk(KERN_ERR "SCSI: can't init sense_pool %s\n",
+ shost->hostt->name);
+ kmem_cache_destroy(shost->sense_slab);
+ shost->sense_slab = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void scsi_destroy_sense_pool(struct Scsi_Host *shost)
+{
+ if (shost->sense_pool)
+ mempool_destroy(shost->sense_pool);
+ shost->sense_pool = NULL;
+ if (shost->sense_slab)
+ kmem_cache_destroy(shost->sense_slab);
+ shost->sense_slab = NULL;
+}
+
+int scsi_resize_sense_pool(struct Scsi_Host *shost, int inc_dec)
+{
+ if (inc_dec > 0) {
+ u8 *sense_per_queue;
+
+ if (mempool_resize(shost->sense_pool,
+ shost->sense_pool->min_nr + 1, GFP_KERNEL))
+ goto out;
+ /* Resize might not guaranty reserved allocation.
+ * This here will
+ */
+ sense_per_queue = mempool_alloc(shost->sense_pool,
+ shost->cmd_pool->gfp_mask | GFP_KERNEL);
+ if (!sense_per_queue) {
+ mempool_resize(shost->sense_pool,
+ shost->sense_pool->min_nr - 1,
+ shost->cmd_pool->gfp_mask | GFP_KERNEL);
+ goto out;
+ }
+ mempool_free(sense_per_queue, shost->sense_pool);
+ } else
+ mempool_resize(shost->sense_pool,
+ shost->sense_pool->min_nr - 1,
+ shost->cmd_pool->gfp_mask | GFP_KERNEL);
+ return 0;
+
+out:
+ return -ENOMEM;
+}
+
u8 *scsi_make_sense(struct scsi_cmnd *cmd)
{
- return cmd->sense_buffer;
+ if (!cmd->dma_sense_check) {
+ struct Scsi_Host *shost = cmd->device->host;
+ if (!shost->sense_pool) {
+ /* did you not set .sense_buffsize in host template */
+ WARN_ON(1);
+ shost->sense_buffsize = SCSI_SENSE_BUFFERSIZE;
+ scsi_setup_sense_pool(shost);
+ BUG_ON(!shost->sense_pool);
+ }
+
+ cmd->dma_sense_check =
+ mempool_alloc(shost->sense_pool,
+ shost->cmd_pool->gfp_mask);
+ if (cmd->dma_sense_check)
+ memset(cmd->dma_sense_check, 0, shost->sense_buffsize);
+ }
+ return cmd->dma_sense_check;
}
EXPORT_SYMBOL(scsi_make_sense);
void scsi_return_sense(struct scsi_cmnd *cmd, u8 *sb)
{
- BUG_ON(cmd->sense_buffer != sb);
+ struct Scsi_Host *shost = cmd->device->host;
+
+ if (!cmd->dma_sense_check) /* reentrant */
+ return;
+
+ BUG_ON(cmd->dma_sense_check != sb);
+
+ scsi_eh_cpy_sense(cmd, sb, shost->sense_buffsize);
+ cmd->dma_sense_check = NULL;
+ mempool_free(sb, shost->sense_pool);
}
EXPORT_SYMBOL(scsi_return_sense);
@@ -327,50 +410,36 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
mutex_lock(&host_cmd_pool_mutex);
pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool);
if (!pool->users) {
- pool->cmd_slab = kmem_cache_create(pool->cmd_name,
- sizeof(struct scsi_cmnd), 0,
- pool->slab_flags, NULL);
- if (!pool->cmd_slab)
+ pool->slab = kmem_cache_create(pool->name,
+ sizeof(struct scsi_cmnd), 0,
+ pool->slab_flags, NULL);
+ if (!pool->slab)
goto fail;
-
- pool->sense_slab = kmem_cache_create(pool->sense_name,
- SCSI_SENSE_BUFFERSIZE, 0,
- pool->slab_flags, NULL);
- if (!pool->sense_slab) {
- kmem_cache_destroy(pool->cmd_slab);
- goto fail;
- }
}
pool->users++;
shost->cmd_pool = pool;
mutex_unlock(&host_cmd_pool_mutex);
+ if (scsi_setup_sense_pool(shost))
+ goto fail2;
+
/*
* Get one backup command for this host.
*/
- cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab,
- GFP_KERNEL | shost->cmd_pool->gfp_mask);
+ cmd = kmem_cache_alloc(shost->cmd_pool->slab,
+ GFP_KERNEL | shost->cmd_pool->gfp_mask);
if (!cmd)
- goto fail2;
-
- cmd->sense_buffer = kmem_cache_alloc(shost->cmd_pool->sense_slab,
- GFP_KERNEL |
- shost->cmd_pool->gfp_mask);
- if (!cmd->sense_buffer)
- goto fail2;
-
+ goto fail3;
list_add(&cmd->list, &shost->free_list);
return 0;
+ fail3:
+ scsi_destroy_sense_pool(shost);
fail2:
- if (cmd)
- kmem_cache_free(shost->cmd_pool->cmd_slab, cmd);
mutex_lock(&host_cmd_pool_mutex);
- if (!--pool->users) {
- kmem_cache_destroy(pool->cmd_slab);
- kmem_cache_destroy(pool->sense_slab);
- }
+ if (!--pool->users)
+ kmem_cache_destroy(pool->slab);
fail:
mutex_unlock(&host_cmd_pool_mutex);
return -ENOMEM;
@@ -387,16 +456,14 @@ void scsi_destroy_command_freelist(struct Scsi_Host
*shost)
cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
list_del_init(&cmd->list);
- kmem_cache_free(shost->cmd_pool->sense_slab,
- cmd->sense_buffer);
- kmem_cache_free(shost->cmd_pool->cmd_slab, cmd);
+ kmem_cache_free(shost->cmd_pool->slab, cmd);
}
+ scsi_destroy_sense_pool(shost);
+
mutex_lock(&host_cmd_pool_mutex);
- if (!--shost->cmd_pool->users) {
- kmem_cache_destroy(shost->cmd_pool->cmd_slab);
- kmem_cache_destroy(shost->cmd_pool->sense_slab);
- }
+ if (!--shost->cmd_pool->users)
+ kmem_cache_destroy(shost->cmd_pool->slab);
mutex_unlock(&host_cmd_pool_mutex);
}
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index dc8cd2b..ed7a49d 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -299,6 +299,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host
*shost,
static int scsi_check_sense(struct scsi_cmnd *scmd)
{
struct scsi_sense_hdr sshdr;
+ const u8 *sense;
if (! scsi_command_normalize_sense(scmd, &sshdr))
return FAILED; /* no valid sense data */
@@ -306,13 +307,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
if (scsi_sense_is_deferred(&sshdr))
return NEEDS_RETRY;
+ sense = scsi_sense(scmd);
/*
* Previous logic looked for FILEMARK, EOM or ILI which are
* mainly associated with tapes and returned SUCCESS.
*/
if (sshdr.response_code == 0x70) {
/* fixed format */
- if (scmd->sense_buffer[2] & 0xe0)
+ if (sense[2] & 0xe0)
return SUCCESS;
} else {
/*
@@ -321,8 +323,8 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
* descriptor. Ignore ILI from SBC-2 READ LONG and WRITE LONG.
*/
if ((sshdr.additional_length > 3) &&
- (scmd->sense_buffer[8] == 0x4) &&
- (scmd->sense_buffer[11] & 0xe0))
+ (sense[8] == 0x4) &&
+ (sense[11] & 0xe0))
return SUCCESS;
}
@@ -590,8 +592,18 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
void scsi_eh_cpy_sense(struct scsi_cmnd *cmd, void *sense, unsigned
sense_bytes)
{
- unsigned len = min_t(unsigned, sense_bytes, SCSI_SENSE_BUFFERSIZE);
- memcpy(cmd->sense_buffer, sense, len);
+ u8 *sb = sense;
+ unsigned len = min_t(unsigned, sense_bytes,
+ cmd->request->sense_max_len);
+ if (len > 7)
+ len = min_t(unsigned, len, 8 + sb[7]);
+
+ memcpy(cmd->request->sense, sense, len);
+
+ if (len < cmd->request->sense_max_len)
+ memset(cmd->request->sense + len, 0,
+ cmd->request->sense_max_len - len);
+ cmd->request->sense_len = len;
}
EXPORT_SYMBOL(scsi_eh_cpy_sense);
@@ -627,6 +639,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct
scsi_eh_save *ses,
ses->sdb = scmd->sdb;
ses->next_rq = scmd->request->next_rq;
ses->result = scmd->result;
+ ses->sense_buff = NULL;
scmd->cmnd = ses->eh_cmnd;
memset(scmd->cmnd, 0, BLK_MAX_CDB);
@@ -634,9 +647,17 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct
scsi_eh_save *ses,
scmd->request->next_rq = NULL;
if (sense_bytes) {
- scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE,
+ ses->sense_buff = scsi_make_sense(scmd);
+ /*
+ * properly templated LLD will not fail here.
+ * Did you set your .sense_buffsize in host template?
+ * either that or you're reentering scsi_eh_prep_cmnd()
+ * which is not allowed.
+ */
+ BUG_ON(!ses->sense_buff);
+ scmd->sdb.length = min_t(unsigned, sdev->host->sense_buffsize,
sense_bytes);
- sg_init_one(&ses->sense_sgl, scmd->sense_buffer,
+ sg_init_one(&ses->sense_sgl, ses->sense_buff,
scmd->sdb.length);
scmd->sdb.table.sgl = &ses->sense_sgl;
scmd->sc_data_direction = DMA_FROM_DEVICE;
@@ -659,11 +680,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct
scsi_eh_save *ses,
scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
(sdev->lun << 5 & 0xe0);
- /*
- * Zero the sense buffer. The scsi spec mandates that any
- * untransferred sense data should be interpreted as being zero.
- */
- memset(scmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ scsi_eh_reset_sense(scmd);
}
EXPORT_SYMBOL(scsi_eh_prep_cmnd);
@@ -676,6 +693,8 @@ EXPORT_SYMBOL(scsi_eh_prep_cmnd);
*/
void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
{
+ if (ses->sense_buff)
+ scsi_return_sense(scmd, ses->sense_buff);
/*
* Restore original data
*/
@@ -1823,7 +1842,7 @@ EXPORT_SYMBOL(scsi_normalize_sense);
int scsi_command_normalize_sense(struct scsi_cmnd *cmd,
struct scsi_sense_hdr *sshdr)
{
- return scsi_normalize_sense(cmd->sense_buffer,
+ return scsi_normalize_sense(scsi_sense(cmd),
SCSI_SENSE_BUFFERSIZE, sshdr);
}
EXPORT_SYMBOL(scsi_command_normalize_sense);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 3720b4e..e9f5a88 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -452,7 +452,7 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
{
cmd->serial_number = 0;
scsi_set_resid(cmd, 0);
- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ scsi_eh_reset_sense(cmd);
if (cmd->cmd_len == 0)
cmd->cmd_len = scsi_command_size(cmd->cmnd);
}
@@ -861,20 +861,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned
int good_bytes)
if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
req->errors = result;
- if (result) {
+ if (result)
clear_errors = 0;
- if (sense_valid && req->sense) {
- /*
- * SG_IO wants current and deferred errors
- */
- int len = 8 + cmd->sense_buffer[7];
- if (len > SCSI_SENSE_BUFFERSIZE)
- len = SCSI_SENSE_BUFFERSIZE;
- memcpy(req->sense, cmd->sense_buffer, len);
- req->sense_len = len;
- }
- }
if (scsi_bidi_cmnd(cmd)) {
/* will also release_buffers */
scsi_end_bidi_request(cmd);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 3f34e93..b64681e 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -17,7 +17,7 @@ struct scsi_nl_hdr;
#define SCSI_EH_CANCEL_CMD 0x0001 /* Cancel this cmd */
#define SCSI_SENSE_VALID(scmd) \
- (((scmd)->sense_buffer[0] & 0x70) == 0x70)
+ ((scsi_sense(scmd)[0] & 0x70) == 0x70)
/* hosts.c */
extern int scsi_init_hosts(void);
@@ -37,6 +37,7 @@ static inline void scsi_log_send(struct scsi_cmnd *cmd)
static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
{ };
#endif
+extern int scsi_resize_sense_pool(struct Scsi_Host *shost, int inc_dec);
/* scsi_scan.c */
int scsi_complete_async_scans(void);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 1dc165a..3c151f2 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -311,6 +311,10 @@ static struct scsi_device *scsi_alloc_sdev(struct
scsi_target *starget,
}
}
+ if (!shost->hostt->pre_allocate_sense &&
+ scsi_resize_sense_pool(shost, 1))
+ goto out_device_destroy;
+
return sdev;
out_device_destroy:
@@ -922,6 +926,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned
char *inq_result,
static inline void scsi_destroy_sdev(struct scsi_device *sdev)
{
scsi_device_set_state(sdev, SDEV_DEL);
+ if (!sdev->host->hostt->pre_allocate_sense)
+ scsi_resize_sense_pool(sdev->host, -1);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(&sdev->sdev_gendev);
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 000a544..a3e535a 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -88,10 +88,7 @@ struct scsi_cmnd {
struct request *request; /* The command we are
working on */
- unsigned char *sense_buffer;
- /* obtained by REQUEST SENSE when
- * CHECK CONDITION is received on original
- * command (auto-sense) */
+ u8 *dma_sense_check;
/* Low-level done function - can be used by low-level driver to point
* to completion function. Not used by mid/upper level code. */
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index 97a6180..c547900 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -4,7 +4,6 @@
#include <linux/scatterlist.h>
#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi.h>
struct scsi_device;
struct Scsi_Host;
@@ -79,6 +78,7 @@ struct scsi_eh_save {
/* new command support */
unsigned char eh_cmnd[BLK_MAX_CDB];
struct scatterlist sense_sgl;
+ u8 *sense_buff;
};
extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd,
@@ -97,12 +97,20 @@ extern void scsi_return_sense(struct scsi_cmnd *cmd, u8
*sb);
/*FIXME: don't use, it's temporary */
static inline void scsi_eh_reset_sense(struct scsi_cmnd *cmd)
{
- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ memset(cmd->request->sense, 0, cmd->request->sense_max_len);
}
static inline const u8 *scsi_sense(struct scsi_cmnd *cmd)
{
- return cmd->sense_buffer;
+ if (cmd->dma_sense_check) {
+ /* Betwwen the call to scsi_make_sense()
+ * and scsi_return_sense()
+ */
+ WARN_ON(1);
+ return cmd->dma_sense_check;
+ }
+
+ return cmd->request->sense;
}
#endif /* _SCSI_SCSI_EH_H */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index f232768..747e372 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -6,6 +6,7 @@
#include <linux/types.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include <linux/mempool.h>
struct request_queue;
struct block_device;
@@ -623,6 +624,8 @@ struct Scsi_Host {
/* actual allocated sense_buffsize for this host */
unsigned sense_buffsize;
+ struct kmem_cache *sense_slab;
+ mempool_t *sense_pool;
/*
* Optional work queue to be utilized by the transport
--
1.5.3.3
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html