Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 1065
b: refs/heads/master
c: 949bf79
h: refs/heads/master
i:
  1063: 05e8731
v: v3
  • Loading branch information
James Bottomley authored and James Bottomley committed May 5, 2005
1 parent c931f39 commit a45b0cf
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 69b528936b702d4c13ffa0d14215a029dc754e50
refs/heads/master: 949bf797595fc99d4cadf9a294fe6fd32a4474e6
49 changes: 34 additions & 15 deletions trunk/drivers/scsi/scsi_transport_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/blkdev.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
#include "scsi_priv.h"
Expand All @@ -41,6 +42,11 @@

#define SPI_MAX_ECHO_BUFFER_SIZE 4096

#define DV_LOOPS 3
#define DV_TIMEOUT (10*HZ)
#define DV_RETRIES 3 /* should only need at most
* two cc/ua clears */

/* Private data accessors (keep these out of the header file) */
#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem)
Expand Down Expand Up @@ -100,6 +106,29 @@ static int sprint_frac(char *dest, int value, int denom)
return result;
}

/* Modification of scsi_wait_req that will clear UNIT ATTENTION conditions
* resulting from (likely) bus and device resets */
static void spi_wait_req(struct scsi_request *sreq, const void *cmd,
void *buffer, unsigned bufflen)
{
int i;

for(i = 0; i < DV_RETRIES; i++) {
sreq->sr_request->flags |= REQ_FAILFAST;

scsi_wait_req(sreq, cmd, buffer, bufflen,
DV_TIMEOUT, /* retries */ 1);
if (sreq->sr_result & DRIVER_SENSE) {
struct scsi_sense_hdr sshdr;

if (scsi_request_normalize_sense(sreq, &sshdr)
&& sshdr.sense_key == UNIT_ATTENTION)
continue;
}
break;
}
}

static struct {
enum spi_signal_type value;
char *name;
Expand Down Expand Up @@ -378,11 +407,6 @@ static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR,
if(i->f->set_##x) \
i->f->set_##x(sdev->sdev_target, y)

#define DV_LOOPS 3
#define DV_TIMEOUT (10*HZ)
#define DV_RETRIES 3 /* should only need at most
* two cc/ua clears */

enum spi_compare_returns {
SPI_COMPARE_SUCCESS,
SPI_COMPARE_FAILURE,
Expand Down Expand Up @@ -446,8 +470,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
for (r = 0; r < retries; r++) {
sreq->sr_cmd_len = 0; /* wait_req to fill in */
sreq->sr_data_direction = DMA_TO_DEVICE;
scsi_wait_req(sreq, spi_write_buffer, buffer, len,
DV_TIMEOUT, DV_RETRIES);
spi_wait_req(sreq, spi_write_buffer, buffer, len);
if(sreq->sr_result || !scsi_device_online(sdev)) {
struct scsi_sense_hdr sshdr;

Expand All @@ -471,8 +494,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
memset(ptr, 0, len);
sreq->sr_cmd_len = 0; /* wait_req to fill in */
sreq->sr_data_direction = DMA_FROM_DEVICE;
scsi_wait_req(sreq, spi_read_buffer, ptr, len,
DV_TIMEOUT, DV_RETRIES);
spi_wait_req(sreq, spi_read_buffer, ptr, len);
scsi_device_set_state(sdev, SDEV_QUIESCE);

if (memcmp(buffer, ptr, len) != 0)
Expand Down Expand Up @@ -500,8 +522,7 @@ spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer,

memset(ptr, 0, len);

scsi_wait_req(sreq, spi_inquiry, ptr, len,
DV_TIMEOUT, DV_RETRIES);
spi_wait_req(sreq, spi_inquiry, ptr, len);

if(sreq->sr_result || !scsi_device_online(sdev)) {
scsi_device_set_state(sdev, SDEV_QUIESCE);
Expand Down Expand Up @@ -593,8 +614,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer)
* (reservation conflict, device not ready, etc) just
* skip the write tests */
for (l = 0; ; l++) {
scsi_wait_req(sreq, spi_test_unit_ready, NULL, 0,
DV_TIMEOUT, DV_RETRIES);
spi_wait_req(sreq, spi_test_unit_ready, NULL, 0);

if(sreq->sr_result) {
if(l >= 3)
Expand All @@ -608,8 +628,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer)
sreq->sr_cmd_len = 0;
sreq->sr_data_direction = DMA_FROM_DEVICE;

scsi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4,
DV_TIMEOUT, DV_RETRIES);
spi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4);

if (sreq->sr_result)
/* Device has no echo buffer */
Expand Down

0 comments on commit a45b0cf

Please sign in to comment.