tree f0adedf975fab838ec7d485731cb0bccd24e0e57
parent 7aaef27bafdfa10351726a1d383bdde33422072c
author <[EMAIL PROTECTED]> Mon, 18 Apr 2005 02:59:33 -0500
committer James Bottomley <[EMAIL PROTECTED]> Mon, 18 Apr 2005 23:52:02 -0500
aic7xxx: add support for the SPI transport class
This is just a simplistic patch to export all of the
aic7xxx internal transport parameters via the SPI
transport class. It doesn't actually alter the way the
driver works at all.
Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
scsi/aic7xxx/Kconfig.aic7xxx | 1
scsi/aic7xxx/aic7xxx_osm.c | 261 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 262 insertions(+)
Index: drivers/scsi/aic7xxx/Kconfig.aic7xxx
===================================================================
---
3c6247d74ea748285ad58d1a299dcacbdca5bd7c/drivers/scsi/aic7xxx/Kconfig.aic7xxx
(mode:100644 sha1:8398e0dd48100357fd80fedc371e88d1dcdcb1b7)
+++
f0adedf975fab838ec7d485731cb0bccd24e0e57/drivers/scsi/aic7xxx/Kconfig.aic7xxx
(mode:100644 sha1:ac8de03c9fa2b6f4b0e99f6708c0772743145410)
@@ -5,6 +5,7 @@
config SCSI_AIC7XXX
tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
depends on (PCI || EISA) && SCSI
+ select SCSI_SPI_ATTRS
---help---
This driver supports all of Adaptec's Fast through Ultra 160 PCI
based SCSI controllers as well as the aic7770 based EISA and VLB
Index: drivers/scsi/aic7xxx/aic7xxx_osm.c
===================================================================
--- 3c6247d74ea748285ad58d1a299dcacbdca5bd7c/drivers/scsi/aic7xxx/aic7xxx_osm.c
(mode:100644 sha1:35d6de5a4c9da99a8d33a3f0ddea9c9852948410)
+++ f0adedf975fab838ec7d485731cb0bccd24e0e57/drivers/scsi/aic7xxx/aic7xxx_osm.c
(mode:100644 sha1:6b6ee0a52a4689815f51941ffc0abb06fdac2fce)
@@ -122,6 +122,10 @@
#include "aic7xxx_osm.h"
#include "aic7xxx_inline.h"
#include <scsi/scsicam.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
+
+static struct scsi_transport_template *ahc_linux_transport_template = NULL;
/*
* Include aiclib.c as part of our
@@ -1728,6 +1732,8 @@
ahc_linux_start_dv(ahc);
ahc_unlock(ahc, &s);
+ host->transportt = ahc_linux_transport_template;
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /*
XXX handle failure */
scsi_scan_host(host);
@@ -4990,13 +4996,267 @@
static void ahc_linux_exit(void);
+static void ahc_linux_get_period(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ spi_period(starget) = tinfo->curr.period;
+}
+
+static void ahc_linux_set_period(struct scsi_target *starget, int period)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ struct ahc_devinfo devinfo;
+ unsigned int ppr_options = tinfo->curr.ppr_options;
+ unsigned long flags;
+ unsigned long offset = tinfo->curr.offset;
+ struct ahc_syncrate *syncrate;
+
+ if (offset == 0)
+ offset = MAX_OFFSET;
+
+ ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+ starget->channel + 'A', ROLE_INITIATOR);
+ syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
AHC_SYNCRATE_DT);
+ ahc_lock(ahc, &flags);
+ ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
+ ppr_options, AHC_TRANS_GOAL, FALSE);
+ ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_offset(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ spi_offset(starget) = tinfo->curr.offset;
+}
+
+static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ struct ahc_devinfo devinfo;
+ unsigned int ppr_options = 0;
+ unsigned int period = 0;
+ unsigned long flags;
+ struct ahc_syncrate *syncrate = NULL;
+
+ ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+ starget->channel + 'A', ROLE_INITIATOR);
+ if (offset != 0) {
+ syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
AHC_SYNCRATE_DT);
+ period = tinfo->curr.period;
+ ppr_options = tinfo->curr.ppr_options;
+ }
+ ahc_lock(ahc, &flags);
+ ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
+ ppr_options, AHC_TRANS_GOAL, FALSE);
+ ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_width(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ spi_width(starget) = tinfo->curr.width;
+}
+
+static void ahc_linux_set_width(struct scsi_target *starget, int width)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_devinfo devinfo;
+ unsigned long flags;
+
+ ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+ starget->channel + 'A', ROLE_INITIATOR);
+ ahc_lock(ahc, &flags);
+ ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
+ ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_dt(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
+}
+
+static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ struct ahc_devinfo devinfo;
+ unsigned int ppr_options = tinfo->curr.ppr_options
+ & ~MSG_EXT_PPR_DT_REQ;
+ unsigned int period = tinfo->curr.period;
+ unsigned long flags;
+ struct ahc_syncrate *syncrate;
+
+ ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+ starget->channel + 'A', ROLE_INITIATOR);
+ syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+ dt ? AHC_SYNCRATE_DT :
AHC_SYNCRATE_ULTRA2);
+ ahc_lock(ahc, &flags);
+ ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+ ppr_options, AHC_TRANS_GOAL, FALSE);
+ ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_qas(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
+}
+
+static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ struct ahc_devinfo devinfo;
+ unsigned int ppr_options = tinfo->curr.ppr_options
+ & ~MSG_EXT_PPR_QAS_REQ;
+ unsigned int period = tinfo->curr.period;
+ unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
+ unsigned long flags;
+ struct ahc_syncrate *syncrate;
+
+ if (qas)
+ ppr_options |= MSG_EXT_PPR_QAS_REQ;
+
+ ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+ starget->channel + 'A', ROLE_INITIATOR);
+ syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+ dt ? AHC_SYNCRATE_DT :
AHC_SYNCRATE_ULTRA2);
+ ahc_lock(ahc, &flags);
+ ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+ ppr_options, AHC_TRANS_GOAL, FALSE);
+ ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_iu(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
+}
+
+static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+ struct ahc_tmode_tstate *tstate;
+ struct ahc_initiator_tinfo *tinfo
+ = ahc_fetch_transinfo(ahc,
+ starget->channel + 'A',
+ shost->this_id, starget->id, &tstate);
+ struct ahc_devinfo devinfo;
+ unsigned int ppr_options = tinfo->curr.ppr_options
+ & ~MSG_EXT_PPR_IU_REQ;
+ unsigned int period = tinfo->curr.period;
+ unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
+ unsigned long flags;
+ struct ahc_syncrate *syncrate;
+
+ if (iu)
+ ppr_options |= MSG_EXT_PPR_IU_REQ;
+
+ ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+ starget->channel + 'A', ROLE_INITIATOR);
+ syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+ dt ? AHC_SYNCRATE_DT :
AHC_SYNCRATE_ULTRA2);
+ ahc_lock(ahc, &flags);
+ ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+ ppr_options, AHC_TRANS_GOAL, FALSE);
+ ahc_unlock(ahc, &flags);
+}
+
+static struct spi_function_template ahc_linux_transport_functions = {
+ .get_offset = ahc_linux_get_offset,
+ .set_offset = ahc_linux_set_offset,
+ .show_offset = 1,
+ .get_period = ahc_linux_get_period,
+ .set_period = ahc_linux_set_period,
+ .show_period = 1,
+ .get_width = ahc_linux_get_width,
+ .set_width = ahc_linux_set_width,
+ .show_width = 1,
+ .get_dt = ahc_linux_get_dt,
+ .set_dt = ahc_linux_set_dt,
+ .show_dt = 1,
+ .get_iu = ahc_linux_get_iu,
+ .set_iu = ahc_linux_set_iu,
+ .show_iu = 1,
+ .get_qas = ahc_linux_get_qas,
+ .set_qas = ahc_linux_set_qas,
+ .show_qas = 1,
+};
+
+
+
static int __init
ahc_linux_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ ahc_linux_transport_template =
spi_attach_transport(&ahc_linux_transport_functions);
+ if (!ahc_linux_transport_template)
+ return -ENODEV;
int rc = ahc_linux_detect(&aic7xxx_driver_template);
if (rc)
return rc;
+ spi_release_transport(ahc_linux_transport_template);
ahc_linux_exit();
return -ENODEV;
#else
@@ -5037,6 +5297,7 @@
#endif
ahc_linux_pci_exit();
ahc_linux_eisa_exit();
+ spi_release_transport(ahc_linux_transport_template);
}
module_init(ahc_linux_init);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html