Commit 6ea3c0b2 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by James Bottomley

[SCSI] Add spi_populate_*_msg functions

Introduce new helpers:
 - spi_populate_width_msg()
 - spi_populate_sync_msg()
 - spi_populate_ppr_msg()

and use them in drivers which already enable the SPI transport.
Signed-off-by: default avatarMatthew Wilcox <matthew@wil.cx>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent b0dc1db1
...@@ -238,14 +238,6 @@ static char *NCR_700_SBCL_to_phase[] = { ...@@ -238,14 +238,6 @@ static char *NCR_700_SBCL_to_phase[] = {
"MSG IN", "MSG IN",
}; };
static __u8 NCR_700_SDTR_msg[] = {
0x01, /* Extended message */
0x03, /* Extended message Length */
0x01, /* SDTR Extended message */
NCR_700_MIN_PERIOD,
NCR_700_MAX_OFFSET
};
/* This translates the SDTR message offset and period to a value /* This translates the SDTR message offset and period to a value
* which can be loaded into the SXFER_REG. * which can be loaded into the SXFER_REG.
* *
...@@ -266,7 +258,7 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata, ...@@ -266,7 +258,7 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
return 0; return 0;
if(period < hostdata->min_period) { if(period < hostdata->min_period) {
printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4); printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD*4);
period = hostdata->min_period; period = hostdata->min_period;
} }
XFERP = (period*4 * hostdata->sync_clock)/1000 - 4; XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
...@@ -1434,11 +1426,9 @@ NCR_700_start_command(struct scsi_cmnd *SCp) ...@@ -1434,11 +1426,9 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
if(hostdata->fast && if(hostdata->fast &&
NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) { NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg, count += spi_populate_sync_msg(&hostdata->msgout[count],
sizeof(NCR_700_SDTR_msg)); spi_period(SCp->device->sdev_target),
hostdata->msgout[count+3] = spi_period(SCp->device->sdev_target); spi_offset(SCp->device->sdev_target));
hostdata->msgout[count+4] = spi_offset(SCp->device->sdev_target);
count += sizeof(NCR_700_SDTR_msg);
NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
} }
......
...@@ -1708,12 +1708,7 @@ static void seldo_run(struct Scsi_Host *shpnt) ...@@ -1708,12 +1708,7 @@ static void seldo_run(struct Scsi_Host *shpnt)
ADDMSGO(BUS_DEVICE_RESET); ADDMSGO(BUS_DEVICE_RESET);
} else if (SYNCNEG==0 && SYNCHRONOUS) { } else if (SYNCNEG==0 && SYNCHRONOUS) {
CURRENT_SC->SCp.phase |= syncneg; CURRENT_SC->SCp.phase |= syncneg;
ADDMSGO(EXTENDED_MESSAGE); MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8);
ADDMSGO(3);
ADDMSGO(EXTENDED_SDTR);
ADDMSGO(50); /* 200ns */
ADDMSGO(8); /* 8 byte req/ack offset */
SYNCNEG=1; /* negotiation in progress */ SYNCNEG=1; /* negotiation in progress */
} }
......
...@@ -3762,11 +3762,8 @@ ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ...@@ -3762,11 +3762,8 @@ ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
{ {
if (offset == 0) if (offset == 0)
period = AHD_ASYNC_XFER_PERIOD; period = AHD_ASYNC_XFER_PERIOD;
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; ahd->msgout_index += spi_populate_sync_msg(
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN; ahd->msgout_buf + ahd->msgout_index, period, offset);
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR;
ahd->msgout_buf[ahd->msgout_index++] = period;
ahd->msgout_buf[ahd->msgout_index++] = offset;
ahd->msgout_len += 5; ahd->msgout_len += 5;
if (bootverbose) { if (bootverbose) {
printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
...@@ -3783,10 +3780,8 @@ static void ...@@ -3783,10 +3780,8 @@ static void
ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
u_int bus_width) u_int bus_width)
{ {
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; ahd->msgout_index += spi_populate_width_msg(
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN; ahd->msgout_buf + ahd->msgout_index, bus_width);
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR;
ahd->msgout_buf[ahd->msgout_index++] = bus_width;
ahd->msgout_len += 4; ahd->msgout_len += 4;
if (bootverbose) { if (bootverbose) {
printf("(%s:%c:%d:%d): Sending WDTR %x\n", printf("(%s:%c:%d:%d): Sending WDTR %x\n",
...@@ -3813,14 +3808,9 @@ ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ...@@ -3813,14 +3808,9 @@ ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ppr_options |= MSG_EXT_PPR_PCOMP_EN; ppr_options |= MSG_EXT_PPR_PCOMP_EN;
if (offset == 0) if (offset == 0)
period = AHD_ASYNC_XFER_PERIOD; period = AHD_ASYNC_XFER_PERIOD;
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; ahd->msgout_index += spi_populate_ppr_msg(
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN; ahd->msgout_buf + ahd->msgout_index, period, offset,
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR; bus_width, ppr_options);
ahd->msgout_buf[ahd->msgout_index++] = period;
ahd->msgout_buf[ahd->msgout_index++] = 0;
ahd->msgout_buf[ahd->msgout_index++] = offset;
ahd->msgout_buf[ahd->msgout_index++] = bus_width;
ahd->msgout_buf[ahd->msgout_index++] = ppr_options;
ahd->msgout_len += 8; ahd->msgout_len += 8;
if (bootverbose) { if (bootverbose) {
printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
......
...@@ -2461,11 +2461,8 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ...@@ -2461,11 +2461,8 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
{ {
if (offset == 0) if (offset == 0)
period = AHC_ASYNC_XFER_PERIOD; period = AHC_ASYNC_XFER_PERIOD;
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_index += spi_populate_sync_msg(
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN; ahc->msgout_buf + ahc->msgout_index, period, offset);
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
ahc->msgout_buf[ahc->msgout_index++] = period;
ahc->msgout_buf[ahc->msgout_index++] = offset;
ahc->msgout_len += 5; ahc->msgout_len += 5;
if (bootverbose) { if (bootverbose) {
printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
...@@ -2482,10 +2479,8 @@ static void ...@@ -2482,10 +2479,8 @@ static void
ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
u_int bus_width) u_int bus_width)
{ {
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_index += spi_populate_width_msg(
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN; ahc->msgout_buf + ahc->msgout_index, bus_width);
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
ahc->msgout_buf[ahc->msgout_index++] = bus_width;
ahc->msgout_len += 4; ahc->msgout_len += 4;
if (bootverbose) { if (bootverbose) {
printf("(%s:%c:%d:%d): Sending WDTR %x\n", printf("(%s:%c:%d:%d): Sending WDTR %x\n",
...@@ -2505,14 +2500,9 @@ ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ...@@ -2505,14 +2500,9 @@ ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
{ {
if (offset == 0) if (offset == 0)
period = AHC_ASYNC_XFER_PERIOD; period = AHC_ASYNC_XFER_PERIOD;
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_index += spi_populate_ppr_msg(
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN; ahc->msgout_buf + ahc->msgout_index, period, offset,
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR; bus_width, ppr_options);
ahc->msgout_buf[ahc->msgout_index++] = period;
ahc->msgout_buf[ahc->msgout_index++] = 0;
ahc->msgout_buf[ahc->msgout_index++] = offset;
ahc->msgout_buf[ahc->msgout_index++] = bus_width;
ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
ahc->msgout_len += 8; ahc->msgout_len += 8;
if (bootverbose) { if (bootverbose) {
printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
......
...@@ -4105,17 +4105,11 @@ static int ncr_prepare_nego(struct ncb *np, struct ccb *cp, u_char *msgptr) ...@@ -4105,17 +4105,11 @@ static int ncr_prepare_nego(struct ncb *np, struct ccb *cp, u_char *msgptr)
switch (nego) { switch (nego) {
case NS_SYNC: case NS_SYNC:
msgptr[msglen++] = EXTENDED_MESSAGE; msglen += spi_populate_sync_msg(msgptr + msglen,
msgptr[msglen++] = 3; tp->maxoffs ? tp->minsync : 0, tp->maxoffs);
msgptr[msglen++] = EXTENDED_SDTR;
msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
msgptr[msglen++] = tp->maxoffs;
break; break;
case NS_WIDE: case NS_WIDE:
msgptr[msglen++] = EXTENDED_MESSAGE; msglen += spi_populate_width_msg(msgptr + msglen, tp->usrwide);
msgptr[msglen++] = 2;
msgptr[msglen++] = EXTENDED_WDTR;
msgptr[msglen++] = tp->usrwide;
break; break;
} }
...@@ -6989,12 +6983,7 @@ void ncr_int_sir (struct ncb *np) ...@@ -6989,12 +6983,7 @@ void ncr_int_sir (struct ncb *np)
spi_offset(starget) = ofs; spi_offset(starget) = ofs;
ncr_setsync(np, cp, scntl3, (fak<<5)|ofs); ncr_setsync(np, cp, scntl3, (fak<<5)|ofs);
np->msgout[0] = EXTENDED_MESSAGE; spi_populate_sync_msg(np->msgout, per, ofs);
np->msgout[1] = 3;
np->msgout[2] = EXTENDED_SDTR;
np->msgout[3] = per;
np->msgout[4] = ofs;
cp->nego_status = NS_SYNC; cp->nego_status = NS_SYNC;
if (DEBUG_FLAGS & DEBUG_NEGO) { if (DEBUG_FLAGS & DEBUG_NEGO) {
...@@ -7080,11 +7069,7 @@ void ncr_int_sir (struct ncb *np) ...@@ -7080,11 +7069,7 @@ void ncr_int_sir (struct ncb *np)
spi_width(starget) = wide; spi_width(starget) = wide;
ncr_setwide(np, cp, wide, 1); ncr_setwide(np, cp, wide, 1);
spi_populate_width_msg(np->msgout, wide);
np->msgout[0] = EXTENDED_MESSAGE;
np->msgout[1] = 2;
np->msgout[2] = EXTENDED_WDTR;
np->msgout[3] = wide;
np->msgin [0] = NOP; np->msgin [0] = NOP;
......
...@@ -1051,6 +1051,39 @@ void spi_display_xfer_agreement(struct scsi_target *starget) ...@@ -1051,6 +1051,39 @@ void spi_display_xfer_agreement(struct scsi_target *starget)
} }
EXPORT_SYMBOL(spi_display_xfer_agreement); EXPORT_SYMBOL(spi_display_xfer_agreement);
int spi_populate_width_msg(unsigned char *msg, int width)
{
msg[0] = EXTENDED_MESSAGE;
msg[1] = 2;
msg[2] = EXTENDED_WDTR;
msg[3] = width;
return 4;
}
int spi_populate_sync_msg(unsigned char *msg, int period, int offset)
{
msg[0] = EXTENDED_MESSAGE;
msg[1] = 3;
msg[2] = EXTENDED_SDTR;
msg[3] = period;
msg[4] = offset;
return 5;
}
int spi_populate_ppr_msg(unsigned char *msg, int period, int offset,
int width, int options)
{
msg[0] = EXTENDED_MESSAGE;
msg[1] = 6;
msg[2] = EXTENDED_PPR;
msg[3] = period;
msg[4] = 0;
msg[5] = offset;
msg[6] = width;
msg[7] = options;
return 8;
}
#ifdef CONFIG_SCSI_CONSTANTS #ifdef CONFIG_SCSI_CONSTANTS
static const char * const one_byte_msgs[] = { static const char * const one_byte_msgs[] = {
/* 0x00 */ "Command Complete", NULL, "Save Pointers", /* 0x00 */ "Command Complete", NULL, "Save Pointers",
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/param.h> /* for timeouts in units of HZ */ #include <asm/param.h> /* for timeouts in units of HZ */
#include <scsi/scsi_dbg.h>
#include "sym_glue.h" #include "sym_glue.h"
#include "sym_nvram.h" #include "sym_nvram.h"
...@@ -1430,29 +1429,18 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp ...@@ -1430,29 +1429,18 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
switch (nego) { switch (nego) {
case NS_SYNC: case NS_SYNC:
msgptr[msglen++] = M_EXTENDED; msglen += spi_populate_sync_msg(msgptr + msglen, goal->period,
msgptr[msglen++] = 3; goal->offset);
msgptr[msglen++] = M_X_SYNC_REQ;
msgptr[msglen++] = goal->period;
msgptr[msglen++] = goal->offset;
break; break;
case NS_WIDE: case NS_WIDE:
msgptr[msglen++] = M_EXTENDED; msglen += spi_populate_width_msg(msgptr + msglen, goal->width);
msgptr[msglen++] = 2;
msgptr[msglen++] = M_X_WIDE_REQ;
msgptr[msglen++] = goal->width;
break; break;
case NS_PPR: case NS_PPR:
msgptr[msglen++] = M_EXTENDED; msglen += spi_populate_ppr_msg(msgptr + msglen, goal->period,
msgptr[msglen++] = 6; goal->offset, goal->width,
msgptr[msglen++] = M_X_PPR_REQ; (goal->iu ? PPR_OPT_IU : 0) |
msgptr[msglen++] = goal->period;
msgptr[msglen++] = 0;
msgptr[msglen++] = goal->offset;
msgptr[msglen++] = goal->width;
msgptr[msglen++] = (goal->iu ? PPR_OPT_IU : 0) |
(goal->dt ? PPR_OPT_DT : 0) | (goal->dt ? PPR_OPT_DT : 0) |
(goal->qas ? PPR_OPT_QAS : 0); (goal->qas ? PPR_OPT_QAS : 0));
break; break;
} }
...@@ -3948,11 +3936,7 @@ sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) ...@@ -3948,11 +3936,7 @@ sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
/* /*
* It was a request. Prepare an answer message. * It was a request. Prepare an answer message.
*/ */
np->msgout[0] = M_EXTENDED; spi_populate_sync_msg(np->msgout, per, ofs);
np->msgout[1] = 3;
np->msgout[2] = M_X_SYNC_REQ;
np->msgout[3] = per;
np->msgout[4] = ofs;
if (DEBUG_FLAGS & DEBUG_NEGO) { if (DEBUG_FLAGS & DEBUG_NEGO) {
sym_print_nego_msg(np, target, "sync msgout", np->msgout); sym_print_nego_msg(np, target, "sync msgout", np->msgout);
...@@ -4078,14 +4062,7 @@ sym_ppr_nego_check(struct sym_hcb *np, int req, int target) ...@@ -4078,14 +4062,7 @@ sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
/* /*
* It was a request. Prepare an answer message. * It was a request. Prepare an answer message.
*/ */
np->msgout[0] = M_EXTENDED; spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts);
np->msgout[1] = 6;
np->msgout[2] = M_X_PPR_REQ;
np->msgout[3] = per;
np->msgout[4] = 0;
np->msgout[5] = ofs;
np->msgout[6] = wide;
np->msgout[7] = opts;
if (DEBUG_FLAGS & DEBUG_NEGO) { if (DEBUG_FLAGS & DEBUG_NEGO) {
sym_print_nego_msg(np, target, "ppr msgout", np->msgout); sym_print_nego_msg(np, target, "ppr msgout", np->msgout);
...@@ -4197,10 +4174,7 @@ sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) ...@@ -4197,10 +4174,7 @@ sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
/* /*
* It was a request. Prepare an answer message. * It was a request. Prepare an answer message.
*/ */
np->msgout[0] = M_EXTENDED; spi_populate_width_msg(np->msgout, wide);
np->msgout[1] = 2;
np->msgout[2] = M_X_WIDE_REQ;
np->msgout[3] = wide;
np->msgin [0] = M_NOOP; np->msgin [0] = M_NOOP;
...@@ -4245,11 +4219,8 @@ static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb ...@@ -4245,11 +4219,8 @@ static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb
* a single SCSI command (Suggested by Justin Gibbs). * a single SCSI command (Suggested by Justin Gibbs).
*/ */
if (tp->tgoal.offset) { if (tp->tgoal.offset) {
np->msgout[0] = M_EXTENDED; spi_populate_sync_msg(np->msgout, tp->tgoal.period,
np->msgout[1] = 3; tp->tgoal.offset);
np->msgout[2] = M_X_SYNC_REQ;
np->msgout[3] = tp->tgoal.period;
np->msgout[4] = tp->tgoal.offset;
if (DEBUG_FLAGS & DEBUG_NEGO) { if (DEBUG_FLAGS & DEBUG_NEGO) {
sym_print_nego_msg(np, cp->target, sym_print_nego_msg(np, cp->target,
......
...@@ -148,5 +148,9 @@ void spi_schedule_dv_device(struct scsi_device *); ...@@ -148,5 +148,9 @@ void spi_schedule_dv_device(struct scsi_device *);
void spi_dv_device(struct scsi_device *); void spi_dv_device(struct scsi_device *);
void spi_display_xfer_agreement(struct scsi_target *); void spi_display_xfer_agreement(struct scsi_target *);
int spi_print_msg(const unsigned char *); int spi_print_msg(const unsigned char *);
int spi_populate_width_msg(unsigned char *msg, int width);
int spi_populate_sync_msg(unsigned char *msg, int period, int offset);
int spi_populate_ppr_msg(unsigned char *msg, int period, int offset, int width,
int options);
#endif /* SCSI_TRANSPORT_SPI_H */ #endif /* SCSI_TRANSPORT_SPI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment