summaryrefslogtreecommitdiff
path: root/drivers/scsi/aic7xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c74
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h4
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_core.c22
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c70
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h4
5 files changed, 69 insertions, 105 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 6054881f21f1..a055a96e3ad3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -376,21 +376,10 @@ static __inline void
ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
{
struct scsi_cmnd *cmd;
- int direction;
cmd = scb->io_ctx;
- direction = cmd->sc_data_direction;
ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
- if (cmd->use_sg != 0) {
- struct scatterlist *sg;
-
- sg = (struct scatterlist *)cmd->request_buffer;
- pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction);
- } else if (cmd->request_bufflen != 0) {
- pci_unmap_single(ahd->dev_softc,
- scb->platform_data->buf_busaddr,
- cmd->request_bufflen, direction);
- }
+ scsi_dma_unmap(cmd);
}
/******************************** Macros **************************************/
@@ -1422,6 +1411,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
u_int col_idx;
uint16_t mask;
unsigned long flags;
+ int nseg;
ahd_lock(ahd, &flags);
@@ -1494,18 +1484,17 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
ahd_set_residual(scb, 0);
ahd_set_sense_residual(scb, 0);
scb->sg_count = 0;
- if (cmd->use_sg != 0) {
- void *sg;
- struct scatterlist *cur_seg;
- u_int nseg;
- int dir;
-
- cur_seg = (struct scatterlist *)cmd->request_buffer;
- dir = cmd->sc_data_direction;
- nseg = pci_map_sg(ahd->dev_softc, cur_seg,
- cmd->use_sg, dir);
+
+ nseg = scsi_dma_map(cmd);
+ BUG_ON(nseg < 0);
+ if (nseg > 0) {
+ void *sg = scb->sg_list;
+ struct scatterlist *cur_seg;
+ int i;
+
scb->platform_data->xfer_len = 0;
- for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) {
+
+ scsi_for_each_sg(cmd, cur_seg, nseg, i) {
dma_addr_t addr;
bus_size_t len;
@@ -1513,22 +1502,8 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
len = sg_dma_len(cur_seg);
scb->platform_data->xfer_len += len;
sg = ahd_sg_setup(ahd, scb, sg, addr, len,
- /*last*/nseg == 1);
+ i == (nseg - 1));
}
- } else if (cmd->request_bufflen != 0) {
- void *sg;
- dma_addr_t addr;
- int dir;
-
- sg = scb->sg_list;
- dir = cmd->sc_data_direction;
- addr = pci_map_single(ahd->dev_softc,
- cmd->request_buffer,
- cmd->request_bufflen, dir);
- scb->platform_data->xfer_len = cmd->request_bufflen;
- scb->platform_data->buf_busaddr = addr;
- sg = ahd_sg_setup(ahd, scb, sg, addr,
- cmd->request_bufflen, /*last*/TRUE);
}
LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
@@ -2309,9 +2284,12 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
if (period < 8)
period = 8;
if (period < 10) {
- ppr_options |= MSG_EXT_PPR_DT_REQ;
- if (period == 8)
- ppr_options |= MSG_EXT_PPR_IU_REQ;
+ if (spi_max_width(starget)) {
+ ppr_options |= MSG_EXT_PPR_DT_REQ;
+ if (period == 8)
+ ppr_options |= MSG_EXT_PPR_IU_REQ;
+ } else
+ period = 10;
}
dt = ppr_options & MSG_EXT_PPR_DT_REQ;
@@ -2390,7 +2368,7 @@ static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
printf("%s: %s DT\n", ahd_name(ahd),
dt ? "enabling" : "disabling");
#endif
- if (dt) {
+ if (dt && spi_max_width(starget)) {
ppr_options |= MSG_EXT_PPR_DT_REQ;
if (!width)
ahd_linux_set_width(starget, 1);
@@ -2472,7 +2450,7 @@ static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
iu ? "enabling" : "disabling");
#endif
- if (iu) {
+ if (iu && spi_max_width(starget)) {
ppr_options |= MSG_EXT_PPR_IU_REQ;
ppr_options |= MSG_EXT_PPR_DT_REQ; /* IU requires DT */
}
@@ -2512,7 +2490,7 @@ static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
rdstrm ? "enabling" : "disabling");
#endif
- if (rdstrm)
+ if (rdstrm && spi_max_width(starget))
ppr_options |= MSG_EXT_PPR_RD_STRM;
ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
@@ -2548,7 +2526,7 @@ static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
wrflow ? "enabling" : "disabling");
#endif
- if (wrflow)
+ if (wrflow && spi_max_width(starget))
ppr_options |= MSG_EXT_PPR_WR_FLOW;
ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
@@ -2592,7 +2570,7 @@ static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
rti ? "enabling" : "disabling");
#endif
- if (rti)
+ if (rti && spi_max_width(starget))
ppr_options |= MSG_EXT_PPR_RTI;
ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
@@ -2628,7 +2606,7 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
pcomp ? "Enable" : "Disable");
#endif
- if (pcomp) {
+ if (pcomp && spi_max_width(starget)) {
uint8_t precomp;
if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
@@ -2672,7 +2650,7 @@ static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold)
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
unsigned long flags;
- if (hold)
+ if (hold && spi_max_width(starget))
ppr_options |= MSG_EXT_PPR_HOLD_MCS;
ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index ad9761b237dc..853998be1474 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -781,7 +781,7 @@ int ahd_get_transfer_dir(struct scb *scb)
static __inline
void ahd_set_residual(struct scb *scb, u_long resid)
{
- scb->io_ctx->resid = resid;
+ scsi_set_resid(scb->io_ctx, resid);
}
static __inline
@@ -793,7 +793,7 @@ void ahd_set_sense_residual(struct scb *scb, u_long resid)
static __inline
u_long ahd_get_residual(struct scb *scb)
{
- return (scb->io_ctx->resid);
+ return scsi_get_resid(scb->io_ctx);
}
static __inline
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 75733b09f27a..f350b5e89e76 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -1701,7 +1701,16 @@ ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
&& maxsync < AHC_SYNCRATE_ULTRA2)
maxsync = AHC_SYNCRATE_ULTRA2;
-
+
+ /* Now set the maxsync based on the card capabilities
+ * DT is already done above */
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
+ && maxsync < AHC_SYNCRATE_ULTRA)
+ maxsync = AHC_SYNCRATE_ULTRA;
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
+ && maxsync < AHC_SYNCRATE_FAST)
+ maxsync = AHC_SYNCRATE_FAST;
+
for (syncrate = &ahc_syncrates[maxsync];
syncrate->rate != NULL;
syncrate++) {
@@ -1765,6 +1774,17 @@ ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
else
scsirate &= SXFR;
+ /* now set maxsync based on card capabilities */
+ if ((ahc->features & AHC_DT) == 0 && maxsync < AHC_SYNCRATE_ULTRA2)
+ maxsync = AHC_SYNCRATE_ULTRA2;
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
+ && maxsync < AHC_SYNCRATE_ULTRA)
+ maxsync = AHC_SYNCRATE_ULTRA;
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
+ && maxsync < AHC_SYNCRATE_FAST)
+ maxsync = AHC_SYNCRATE_FAST;
+
+
syncrate = &ahc_syncrates[maxsync];
while (syncrate->rate != NULL) {
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 660f26e23a38..2e9c38f2e8a6 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -402,18 +402,8 @@ ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
cmd = scb->io_ctx;
ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
- if (cmd->use_sg != 0) {
- struct scatterlist *sg;
-
- sg = (struct scatterlist *)cmd->request_buffer;
- pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
- cmd->sc_data_direction);
- } else if (cmd->request_bufflen != 0) {
- pci_unmap_single(ahc->dev_softc,
- scb->platform_data->buf_busaddr,
- cmd->request_bufflen,
- cmd->sc_data_direction);
- }
+
+ scsi_dma_unmap(cmd);
}
static __inline int
@@ -1381,6 +1371,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
struct ahc_tmode_tstate *tstate;
uint16_t mask;
struct scb_tailq *untagged_q = NULL;
+ int nseg;
/*
* Schedule us to run later. The only reason we are not
@@ -1472,23 +1463,21 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
ahc_set_residual(scb, 0);
ahc_set_sense_residual(scb, 0);
scb->sg_count = 0;
- if (cmd->use_sg != 0) {
+
+ nseg = scsi_dma_map(cmd);
+ BUG_ON(nseg < 0);
+ if (nseg > 0) {
struct ahc_dma_seg *sg;
struct scatterlist *cur_seg;
- struct scatterlist *end_seg;
- int nseg;
+ int i;
- cur_seg = (struct scatterlist *)cmd->request_buffer;
- nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
- cmd->sc_data_direction);
- end_seg = cur_seg + nseg;
/* Copy the segments into the SG list. */
sg = scb->sg_list;
/*
* The sg_count may be larger than nseg if
* a transfer crosses a 32bit page.
- */
- while (cur_seg < end_seg) {
+ */
+ scsi_for_each_sg(cmd, cur_seg, nseg, i) {
dma_addr_t addr;
bus_size_t len;
int consumed;
@@ -1499,7 +1488,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
sg, addr, len);
sg += consumed;
scb->sg_count += consumed;
- cur_seg++;
}
sg--;
sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
@@ -1516,33 +1504,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
*/
scb->hscb->dataptr = scb->sg_list->addr;
scb->hscb->datacnt = scb->sg_list->len;
- } else if (cmd->request_bufflen != 0) {
- struct ahc_dma_seg *sg;
- dma_addr_t addr;
-
- sg = scb->sg_list;
- addr = pci_map_single(ahc->dev_softc,
- cmd->request_buffer,
- cmd->request_bufflen,
- cmd->sc_data_direction);
- scb->platform_data->buf_busaddr = addr;
- scb->sg_count = ahc_linux_map_seg(ahc, scb,
- sg, addr,
- cmd->request_bufflen);
- sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
- /*
- * Reset the sg list pointer.
- */
- scb->hscb->sgptr =
- ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
-
- /*
- * Copy the first SG into the "current"
- * data pointer area.
- */
- scb->hscb->dataptr = sg->addr;
- scb->hscb->datacnt = sg->len;
} else {
scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
scb->hscb->dataptr = 0;
@@ -2356,8 +2317,13 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period)
if (period < 9)
period = 9; /* 12.5ns is our minimum */
- if (period == 9)
- ppr_options |= MSG_EXT_PPR_DT_REQ;
+ if (period == 9) {
+ if (spi_max_width(starget))
+ ppr_options |= MSG_EXT_PPR_DT_REQ;
+ else
+ /* need wide for DT and need DT for 12.5 ns */
+ period = 10;
+ }
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
starget->channel + 'A', ROLE_INITIATOR);
@@ -2420,7 +2386,7 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
unsigned long flags;
struct ahc_syncrate *syncrate;
- if (dt) {
+ if (dt && spi_max_width(starget)) {
ppr_options |= MSG_EXT_PPR_DT_REQ;
if (!width)
ahc_linux_set_width(starget, 1);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 8fee7edc6eb3..b48dab447bde 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -751,7 +751,7 @@ int ahc_get_transfer_dir(struct scb *scb)
static __inline
void ahc_set_residual(struct scb *scb, u_long resid)
{
- scb->io_ctx->resid = resid;
+ scsi_set_resid(scb->io_ctx, resid);
}
static __inline
@@ -763,7 +763,7 @@ void ahc_set_sense_residual(struct scb *scb, u_long resid)
static __inline
u_long ahc_get_residual(struct scb *scb)
{
- return (scb->io_ctx->resid);
+ return scsi_get_resid(scb->io_ctx);
}
static __inline