scsi: ncr5380: Pass hostdata pointer to register polling routines

Pass a NCR5380_hostdata struct pointer to the board-specific routines
instead of a Scsi_Host struct pointer. This reduces pointer chasing in
the PIO and PDMA fast paths. The old way was a mistake because it is
slow and the board-specific code is not concerned with the mid-layer.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Finn Thain 2016-10-10 00:46:53 -04:00 committed by Martin K. Petersen
parent 61e1ce588b
commit d5d37a0ab1
3 changed files with 24 additions and 25 deletions

View file

@ -178,7 +178,7 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
/** /**
* NCR5380_poll_politely2 - wait for two chip register values * NCR5380_poll_politely2 - wait for two chip register values
* @instance: controller to poll * @hostdata: host private data
* @reg1: 5380 register to poll * @reg1: 5380 register to poll
* @bit1: Bitmask to check * @bit1: Bitmask to check
* @val1: Expected value * @val1: Expected value
@ -195,12 +195,11 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
* Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT. * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
*/ */
static int NCR5380_poll_politely2(struct Scsi_Host *instance, static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,
unsigned int reg1, u8 bit1, u8 val1, unsigned int reg1, u8 bit1, u8 val1,
unsigned int reg2, u8 bit2, u8 val2, unsigned int reg2, u8 bit2, u8 val2,
unsigned long wait) unsigned long wait)
{ {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned long n = hostdata->poll_loops; unsigned long n = hostdata->poll_loops;
unsigned long deadline = jiffies + wait; unsigned long deadline = jiffies + wait;
@ -561,7 +560,7 @@ static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
case 3: case 3:
case 5: case 5:
shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n"); shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n");
NCR5380_poll_politely(instance, NCR5380_poll_politely(hostdata,
STATUS_REG, SR_BSY, 0, 5 * HZ); STATUS_REG, SR_BSY, 0, 5 * HZ);
break; break;
case 2: case 2:
@ -1076,7 +1075,7 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
*/ */
spin_unlock_irq(&hostdata->lock); spin_unlock_irq(&hostdata->lock);
err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0, err = NCR5380_poll_politely2(hostdata, MODE_REG, MR_ARBITRATE, 0,
INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
ICR_ARBITRATION_PROGRESS, HZ); ICR_ARBITRATION_PROGRESS, HZ);
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
@ -1202,7 +1201,7 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
* selection. * selection.
*/ */
err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY, err = NCR5380_poll_politely(hostdata, STATUS_REG, SR_BSY, SR_BSY,
msecs_to_jiffies(250)); msecs_to_jiffies(250));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
@ -1248,7 +1247,7 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
/* Wait for start of REQ/ACK handshake */ /* Wait for start of REQ/ACK handshake */
err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); err = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ);
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
if (err < 0) { if (err < 0) {
shost_printk(KERN_ERR, instance, "select: REQ timeout\n"); shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
@ -1338,7 +1337,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
* valid * valid
*/ */
if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0) if (NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
break; break;
dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n"); dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
@ -1383,7 +1382,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
} }
if (NCR5380_poll_politely(instance, if (NCR5380_poll_politely(hostdata,
STATUS_REG, SR_REQ, 0, 5 * HZ) < 0) STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
break; break;
@ -1483,7 +1482,7 @@ static int do_abort(struct Scsi_Host *instance)
* the target sees, so we just handshake. * the target sees, so we just handshake.
*/ */
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ); rc = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
if (rc < 0) if (rc < 0)
goto timeout; goto timeout;
@ -1494,7 +1493,7 @@ static int do_abort(struct Scsi_Host *instance)
if (tmp != PHASE_MSGOUT) { if (tmp != PHASE_MSGOUT) {
NCR5380_write(INITIATOR_COMMAND_REG, NCR5380_write(INITIATOR_COMMAND_REG,
ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK); ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ); rc = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, 0, 3 * HZ);
if (rc < 0) if (rc < 0)
goto timeout; goto timeout;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@ -1682,12 +1681,12 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
* byte. * byte.
*/ */
if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
BASR_DRQ, BASR_DRQ, HZ) < 0) { BASR_DRQ, BASR_DRQ, HZ) < 0) {
result = -1; result = -1;
shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n"); shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n");
} }
if (NCR5380_poll_politely(instance, STATUS_REG, if (NCR5380_poll_politely(hostdata, STATUS_REG,
SR_REQ, 0, HZ) < 0) { SR_REQ, 0, HZ) < 0) {
result = -1; result = -1;
shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n"); shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
@ -1698,7 +1697,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
* Wait for the last byte to be sent. If REQ is being asserted for * Wait for the last byte to be sent. If REQ is being asserted for
* the byte we're interested, we'll ACK it and it will go false. * the byte we're interested, we'll ACK it and it will go false.
*/ */
if (NCR5380_poll_politely2(instance, if (NCR5380_poll_politely2(hostdata,
BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ, BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) { BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) {
result = -1; result = -1;
@ -2077,7 +2076,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
} /* switch(phase) */ } /* switch(phase) */
} else { } else {
spin_unlock_irq(&hostdata->lock); spin_unlock_irq(&hostdata->lock);
NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ);
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
} }
} }
@ -2123,7 +2122,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
*/ */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
if (NCR5380_poll_politely(instance, if (NCR5380_poll_politely(hostdata,
STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) { STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
return; return;
@ -2134,7 +2133,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
* Wait for target to go into MSGIN. * Wait for target to go into MSGIN.
*/ */
if (NCR5380_poll_politely(instance, if (NCR5380_poll_politely(hostdata,
STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) { STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
do_abort(instance); do_abort(instance);
return; return;

View file

@ -302,15 +302,15 @@ static void NCR5380_reselect(struct Scsi_Host *instance);
static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *); static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data); static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data); static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
static int NCR5380_poll_politely2(struct Scsi_Host *, static int NCR5380_poll_politely2(struct NCR5380_hostdata *,
unsigned int, u8, u8, unsigned int, u8, u8,
unsigned int, u8, u8, unsigned long); unsigned int, u8, u8, unsigned long);
static inline int NCR5380_poll_politely(struct Scsi_Host *instance, static inline int NCR5380_poll_politely(struct NCR5380_hostdata *hostdata,
unsigned int reg, u8 bit, u8 val, unsigned int reg, u8 bit, u8 val,
unsigned long wait) unsigned long wait)
{ {
return NCR5380_poll_politely2(instance, reg, bit, val, return NCR5380_poll_politely2(hostdata, reg, bit, val,
reg, bit, val, wait); reg, bit, val, wait);
} }

View file

@ -161,7 +161,7 @@ static int macscsi_pread(struct Scsi_Host *instance,
int n = len; int n = len;
int transferred; int transferred;
while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
BASR_DRQ | BASR_PHASE_MATCH, BASR_DRQ | BASR_PHASE_MATCH,
BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) { BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
CP_IO_TO_MEM(s, d, n); CP_IO_TO_MEM(s, d, n);
@ -174,7 +174,7 @@ static int macscsi_pread(struct Scsi_Host *instance,
return 0; return 0;
/* Target changed phase early? */ /* Target changed phase early? */
if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ, if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0) BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
scmd_printk(KERN_ERR, hostdata->connected, scmd_printk(KERN_ERR, hostdata->connected,
"%s: !REQ and !ACK\n", __func__); "%s: !REQ and !ACK\n", __func__);
@ -264,7 +264,7 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
int n = len; int n = len;
int transferred; int transferred;
while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
BASR_DRQ | BASR_PHASE_MATCH, BASR_DRQ | BASR_PHASE_MATCH,
BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) { BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
CP_MEM_TO_IO(s, d, n); CP_MEM_TO_IO(s, d, n);
@ -273,7 +273,7 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
hostdata->pdma_residual = len - transferred; hostdata->pdma_residual = len - transferred;
/* Target changed phase early? */ /* Target changed phase early? */
if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ, if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0) BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
scmd_printk(KERN_ERR, hostdata->connected, scmd_printk(KERN_ERR, hostdata->connected,
"%s: !REQ and !ACK\n", __func__); "%s: !REQ and !ACK\n", __func__);
@ -282,7 +282,7 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
/* No bus error. */ /* No bus error. */
if (n == 0) { if (n == 0) {
if (NCR5380_poll_politely(instance, TARGET_COMMAND_REG, if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
TCR_LAST_BYTE_SENT, TCR_LAST_BYTE_SENT,
TCR_LAST_BYTE_SENT, HZ / 64) < 0) TCR_LAST_BYTE_SENT, HZ / 64) < 0)
scmd_printk(KERN_ERR, hostdata->connected, scmd_printk(KERN_ERR, hostdata->connected,