Re: SCSI breakage on non-cache coherent architectures
On Tue, Nov 20, 2007 at 06:51:14AM +1100, Benjamin Herrenschmidt wrote: > > On Mon, 2007-11-19 at 00:38 -0800, David Miller wrote: > > From: Benjamin Herrenschmidt <[EMAIL PROTECTED]> > > Date: Mon, 19 Nov 2007 16:35:23 +1100 > > > > > I'm not sure what is the best way to fix that. Internally, I've done > > > some test whacking some cacheline_aligned in the scsi_cmnd data > > > structure to verify I no longer get random SLAB corruption when using my > > > USB but that significantly bloats the size of the structure on archs > > > such as ppc64 that don't need it and have a large cache line size. > > > > > > Unfortunately, I don't think there's any existing Kconfig symbol or arch > > > provided #define to tell us that we are on a non-coherent arch afaik > > > that could be used to make that conditional. > > > > > > Another option would be to kmalloc the buffer (wasn't it the case before > > > btw ?) but I suppose some people will scream at the idea due to how the > > > command pools are done... > > > > You could make a dma_cacheline_aligned and use that. > > It seems pretty reasonable. > > I was thinking about that. What archs would need it ? arm, mips, what > else ? older parisc Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] SGIWD93: use cached memory access to make driver work on IP28
Following patch is 2.6.25 material needed to get SGI IP28 machines supported. Thomas. SGI IP28 machines would need special treatment (enable adding addtional wait states) when accessing memory uncached. To avoid this pain I changed the driver to use only cached access to memory. Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- drivers/scsi/sgiwd93.c | 68 ++- 1 files changed, 43 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index eef8275..d4e6468 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -33,19 +33,27 @@ struct ip22_hostdata { struct WD33C93_hostdata wh; - struct hpc_data { - dma_addr_t dma; - void*cpu; - } hd; + dma_addr_t dma; + void *cpu; + void *dev; }; #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) struct hpc_chunk { struct hpc_dma_desc desc; - u32 _padding; /* align to quadword boundary */ + u32 _padding[128/4 - 3];/* align to biggest cache line size */ }; +/* space for hpc dma descriptors */ +#define HPC_DMA_SIZE (4 * PAGE_SIZE) + +/* we only need to sync the dma descriptor */ +#define DMA_HPC_SYNC(dev, hcp, dir) \ + dma_cache_sync(dev, hcp, sizeof(struct hpc_dma_desc), dir) + +#define DMA_DIR(d) ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE) + static irqreturn_t sgiwd93_intr(int irq, void *dev_id) { struct Scsi_Host * host = dev_id; @@ -59,14 +67,14 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id) } static inline -void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) +void fill_hpc_entries(void *dev, struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) { unsigned long len = cmd->SCp.this_residual; void *addr = cmd->SCp.ptr; dma_addr_t physaddr; unsigned long count; - physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); + physaddr = dma_map_single(dev, addr, len, DMA_DIR(datainp)); cmd->SCp.dma_handle = physaddr; while (len) { @@ -77,6 +85,7 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) count = len > 8192 ? 8192 : len; hcp->desc.pbuf = physaddr; hcp->desc.cntinfo = count; + DMA_HPC_SYNC(dev, hcp, DMA_TO_DEVICE); hcp++; len -= count; physaddr += count; @@ -89,6 +98,7 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) */ hcp->desc.pbuf = 0; hcp->desc.cntinfo = HPCDMA_EOX; + DMA_HPC_SYNC(dev, hcp, DMA_TO_DEVICE); } static int dma_setup(struct scsi_cmnd *cmd, int datainp) @@ -96,7 +106,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->device->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; + struct hpc_chunk *hcp = (struct hpc_chunk *)hdata->cpu; pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); @@ -111,12 +121,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries(hcp, cmd, datainp); + fill_hpc_entries(hdata->dev, hcp, cmd, datainp); pr_debug(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = hdata->hd.dma; + hregs->ndptr = hdata->dma; if (datainp) hregs->ctrl = HPC3_SCTRL_ACTIVE; else @@ -134,6 +144,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, if (!SCpnt) return; + if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0) + return; + hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; pr_debug("dma_stop: status<%d> ", status); @@ -145,8 +158,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, barrier(); } hregs->ctrl = 0; - dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, -SCpnt->sc_data_direction); + dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle, +SCpnt->SCp.this_residual, +DMA_DIR(hdata->wh.dma_dir)); pr_debug("\n"); } @@ -160,22 +174,25 @@ void sgiwd93_reset(unsigned long base) hregs->ctrl = 0; } -static inline void init_hpc_chain(struct hp
Re: [PATCH] SGIWD93: use cached memory access to make driver work on IP28
On Tue, Nov 27, 2007 at 09:28:14AM +0100, Geert Uytterhoeven wrote: > > struct hpc_chunk { > > struct hpc_dma_desc desc; > > - u32 _padding; /* align to quadword boundary */ > > + u32 _padding[128/4 - 3];/* align to biggest cache line size */ > ^ > (128 - sizeof(struct hpc_dma_desc))/4? yes, that's safer. Thank you. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] SGIWD93: use cached memory access to make driver work on IP28
On Wed, Nov 28, 2007 at 12:00:39AM +0100, peter fuerst wrote: > unlike with sgiseeq.c, in sgiwd93.c there's no need to bloat the hpc_chunk > and only a single dma_cache_sync-call is necessary in fill_hpc_entries and > init_hpc_chain respectively. funny I realized that a couple of minutes ago. A kernel with this changes booted ok. I'll post an updated driver tomorrow. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[UPDATED PATCH] SGIWD93: use cached memory access to make driver work on IP28
Changes to last version: - no additional padding of hpc descriptor - one dma_cache_sync after hpc descriptors are setup is enough Thomas. SGI IP28 machines would need special treatment (enable adding addtional wait states) when accessing memory uncached. To avoid this pain I changed the driver to use only cached access to memory. Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- drivers/scsi/sgiwd93.c | 64 +-- 1 files changed, 39 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index eef8275..e64ddee 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -33,10 +33,9 @@ struct ip22_hostdata { struct WD33C93_hostdata wh; - struct hpc_data { - dma_addr_t dma; - void*cpu; - } hd; + dma_addr_t dma; + void *cpu; + void *dev; }; #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) @@ -46,6 +45,11 @@ struct hpc_chunk { u32 _padding; /* align to quadword boundary */ }; +/* space for hpc dma descriptors */ +#define HPC_DMA_SIZE PAGE_SIZE + +#define DMA_DIR(d) ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE) + static irqreturn_t sgiwd93_intr(int irq, void *dev_id) { struct Scsi_Host * host = dev_id; @@ -59,15 +63,17 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id) } static inline -void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) +void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din) { unsigned long len = cmd->SCp.this_residual; void *addr = cmd->SCp.ptr; dma_addr_t physaddr; unsigned long count; + struct hpc_chunk *hcp; - physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); + physaddr = dma_map_single(hd->dev, addr, len, DMA_DIR(din)); cmd->SCp.dma_handle = physaddr; + hcp = hd->cpu; while (len) { /* @@ -89,6 +95,9 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) */ hcp->desc.pbuf = 0; hcp->desc.cntinfo = HPCDMA_EOX; + dma_cache_sync(hd->dev, hd->cpu, + (unsigned long)(hcp + 1) - (unsigned long)hd->cpu, + DMA_TO_DEVICE); } static int dma_setup(struct scsi_cmnd *cmd, int datainp) @@ -96,9 +105,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->device->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hdata->cpu); hdata->wh.dma_dir = datainp; @@ -111,12 +119,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries(hcp, cmd, datainp); + fill_hpc_entries(hdata, cmd, datainp); pr_debug(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = hdata->hd.dma; + hregs->ndptr = hdata->dma; if (datainp) hregs->ctrl = HPC3_SCTRL_ACTIVE; else @@ -134,6 +142,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, if (!SCpnt) return; + if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0) + return; + hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; pr_debug("dma_stop: status<%d> ", status); @@ -145,8 +156,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, barrier(); } hregs->ctrl = 0; - dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, -SCpnt->sc_data_direction); + dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle, +SCpnt->SCp.this_residual, +DMA_DIR(hdata->wh.dma_dir)); pr_debug("\n"); } @@ -160,22 +172,23 @@ void sgiwd93_reset(unsigned long base) hregs->ctrl = 0; } -static inline void init_hpc_chain(struct hpc_data *hd) +static inline void init_hpc_chain(void *dev, struct ip22_hostdata *hdata) { - struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu; - struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma; + struct hpc_chunk *hcp = (struct hpc_chunk *)hdata->cpu; + dma_addr_t dma = hdata->dma; unsigned long
[UPDATED PATCH] SGIWD93: use cached memory access to make driver work on IP28
SGI IP28 machines would need special treatment (enable adding addtional wait states) when accessing memory uncached. To avoid this pain I changed the driver to use only cached access to memory. Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- Changes to last version: - added Kconfig change to make selection for similair SGI boxes easier drivers/scsi/Kconfig |2 +- drivers/scsi/sgiwd93.c | 64 +-- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a6676be..2a071b0 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -345,7 +345,7 @@ config ISCSI_TCP config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" - depends on SGI_IP22 && SCSI + depends on SGI_HAS_WD93 && SCSI help If you have a Western Digital WD93 SCSI controller on an SGI MIPS system, say Y. Otherwise, say N. diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index eef8275..e64ddee 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -33,10 +33,9 @@ struct ip22_hostdata { struct WD33C93_hostdata wh; - struct hpc_data { - dma_addr_t dma; - void*cpu; - } hd; + dma_addr_t dma; + void *cpu; + void *dev; }; #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) @@ -46,6 +45,11 @@ struct hpc_chunk { u32 _padding; /* align to quadword boundary */ }; +/* space for hpc dma descriptors */ +#define HPC_DMA_SIZE PAGE_SIZE + +#define DMA_DIR(d) ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE) + static irqreturn_t sgiwd93_intr(int irq, void *dev_id) { struct Scsi_Host * host = dev_id; @@ -59,15 +63,17 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id) } static inline -void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) +void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din) { unsigned long len = cmd->SCp.this_residual; void *addr = cmd->SCp.ptr; dma_addr_t physaddr; unsigned long count; + struct hpc_chunk *hcp; - physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); + physaddr = dma_map_single(hd->dev, addr, len, DMA_DIR(din)); cmd->SCp.dma_handle = physaddr; + hcp = hd->cpu; while (len) { /* @@ -89,6 +95,9 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) */ hcp->desc.pbuf = 0; hcp->desc.cntinfo = HPCDMA_EOX; + dma_cache_sync(hd->dev, hd->cpu, + (unsigned long)(hcp + 1) - (unsigned long)hd->cpu, + DMA_TO_DEVICE); } static int dma_setup(struct scsi_cmnd *cmd, int datainp) @@ -96,9 +105,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->device->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hdata->cpu); hdata->wh.dma_dir = datainp; @@ -111,12 +119,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries(hcp, cmd, datainp); + fill_hpc_entries(hdata, cmd, datainp); pr_debug(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = hdata->hd.dma; + hregs->ndptr = hdata->dma; if (datainp) hregs->ctrl = HPC3_SCTRL_ACTIVE; else @@ -134,6 +142,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, if (!SCpnt) return; + if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0) + return; + hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; pr_debug("dma_stop: status<%d> ", status); @@ -145,8 +156,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, barrier(); } hregs->ctrl = 0; - dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, -SCpnt->sc_data_direction); + dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle, +SCpnt->SCp.this_residual, +DMA_DIR(hdata->wh.dma_dir)); pr_debug("\n"); } @@ -160,22 +172,2
Re: [PATCH 2/2] scsi: Use new __dma_buffer to align sense buffer in scsi_cmnd
On Fri, Dec 21, 2007 at 06:16:41AM -0700, Matthew Wilcox wrote: > On Fri, Dec 21, 2007 at 10:33:26AM +, Alan Cox wrote: > > On Fri, 21 Dec 2007 13:30:08 +1100 > > Benjamin Herrenschmidt <[EMAIL PROTECTED]> wrote: > > > > > The sense buffer ins scsi_cmnd can nowadays be DMA'ed into directly > > > by some low level drivers (that typically happens with USB mass > > > storage). > > > > Should that not be fixed in USB storage by using pci_alloc_coherent on the > > PCI device of the hub not peeing directly into kernel space ? > > That's what I said, but Ben seems fixated on this particular fix. there are SCSI host drivers, which also DMA to the sense buffer like sgiwd93.c for example. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] scsi: Use new __dma_buffer to align sense buffer in scsi_cmnd
On Fri, Dec 21, 2007 at 07:00:25AM -0700, Matthew Wilcox wrote: > On Fri, Dec 21, 2007 at 02:30:28PM +0100, Thomas Bogendoerfer wrote: > > there are SCSI host drivers, which also DMA to the sense buffer like > > sgiwd93.c for example. > > Yes ... and there are others which don't, for example qla2xxx and > sym53c8xx. well I don't care which way to go. I'd prefer a pointer to an allocated sense buffer, but maybe that's just me. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[UPDATED PATCH] SGIWD93: use cached memory access to make driver work on IP28
SGI IP28 machines would need special treatment (enable adding addtional wait states) when accessing memory uncached. To avoid this pain I changed the driver to use only cached access to memory. Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- Changes to last version: - added Kconfig change to make selection for similair SGI boxes easier drivers/scsi/Kconfig |2 +- drivers/scsi/sgiwd93.c | 64 +-- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a6676be..2a071b0 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -345,7 +345,7 @@ config ISCSI_TCP config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" - depends on SGI_IP22 && SCSI + depends on SGI_HAS_WD93 && SCSI help If you have a Western Digital WD93 SCSI controller on an SGI MIPS system, say Y. Otherwise, say N. diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index eef8275..e64ddee 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -33,10 +33,9 @@ struct ip22_hostdata { struct WD33C93_hostdata wh; - struct hpc_data { - dma_addr_t dma; - void*cpu; - } hd; + dma_addr_t dma; + void *cpu; + void *dev; }; #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) @@ -46,6 +45,11 @@ struct hpc_chunk { u32 _padding; /* align to quadword boundary */ }; +/* space for hpc dma descriptors */ +#define HPC_DMA_SIZE PAGE_SIZE + +#define DMA_DIR(d) ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE) + static irqreturn_t sgiwd93_intr(int irq, void *dev_id) { struct Scsi_Host * host = dev_id; @@ -59,15 +63,17 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id) } static inline -void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) +void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din) { unsigned long len = cmd->SCp.this_residual; void *addr = cmd->SCp.ptr; dma_addr_t physaddr; unsigned long count; + struct hpc_chunk *hcp; - physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); + physaddr = dma_map_single(hd->dev, addr, len, DMA_DIR(din)); cmd->SCp.dma_handle = physaddr; + hcp = hd->cpu; while (len) { /* @@ -89,6 +95,9 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) */ hcp->desc.pbuf = 0; hcp->desc.cntinfo = HPCDMA_EOX; + dma_cache_sync(hd->dev, hd->cpu, + (unsigned long)(hcp + 1) - (unsigned long)hd->cpu, + DMA_TO_DEVICE); } static int dma_setup(struct scsi_cmnd *cmd, int datainp) @@ -96,9 +105,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->device->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hdata->cpu); hdata->wh.dma_dir = datainp; @@ -111,12 +119,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries(hcp, cmd, datainp); + fill_hpc_entries(hdata, cmd, datainp); pr_debug(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = hdata->hd.dma; + hregs->ndptr = hdata->dma; if (datainp) hregs->ctrl = HPC3_SCTRL_ACTIVE; else @@ -134,6 +142,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, if (!SCpnt) return; + if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0) + return; + hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; pr_debug("dma_stop: status<%d> ", status); @@ -145,8 +156,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, barrier(); } hregs->ctrl = 0; - dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, -SCpnt->sc_data_direction); + dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle, +SCpnt->SCp.this_residual, +DMA_DIR(hdata->wh.dma_dir)); pr_debug("\n"); } @@ -160,22 +172,2
Re: [UPDATED PATCH] SGIWD93: use cached memory access to make driver work on IP28
On Fri, Jan 25, 2008 at 10:44:40AM -0600, James Bottomley wrote: > > + void *cpu; > > + void *dev; > > This should be struct device *dev; shouldn't it (that seems to be how > it's always used)? of course, no need for the void *. > And that should be dma_free_noncoherent(&pdev->dev, ...) shouldn't it? yes it should. I'm sending an updated patch in a couple of seconds. Thanks for the review. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[UPDATED PATCH] SGIWD93: use cached memory access to make driver work on IP28
SGI IP28 machines would need special treatment (enable adding addtional wait states) when accessing memory uncached. To avoid this pain I changed the driver to use only cached access to memory. Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- Changes to last version: - struct device * instead of void * in hostdata struct - get rid of not used dev argument in init_hpc_chain - fix device argument in dma_free_noncoherent call drivers/scsi/Kconfig |2 +- drivers/scsi/sgiwd93.c | 64 +-- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a6676be..2a071b0 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -345,7 +345,7 @@ config ISCSI_TCP config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" - depends on SGI_IP22 && SCSI + depends on SGI_HAS_WD93 && SCSI help If you have a Western Digital WD93 SCSI controller on an SGI MIPS system, say Y. Otherwise, say N. diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index eef8275..2c43047 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -33,10 +33,9 @@ struct ip22_hostdata { struct WD33C93_hostdata wh; - struct hpc_data { - dma_addr_t dma; - void*cpu; - } hd; + dma_addr_t dma; + void *cpu; + struct device *dev; }; #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) @@ -46,6 +45,11 @@ struct hpc_chunk { u32 _padding; /* align to quadword boundary */ }; +/* space for hpc dma descriptors */ +#define HPC_DMA_SIZE PAGE_SIZE + +#define DMA_DIR(d) ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE) + static irqreturn_t sgiwd93_intr(int irq, void *dev_id) { struct Scsi_Host * host = dev_id; @@ -59,15 +63,17 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id) } static inline -void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) +void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din) { unsigned long len = cmd->SCp.this_residual; void *addr = cmd->SCp.ptr; dma_addr_t physaddr; unsigned long count; + struct hpc_chunk *hcp; - physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); + physaddr = dma_map_single(hd->dev, addr, len, DMA_DIR(din)); cmd->SCp.dma_handle = physaddr; + hcp = hd->cpu; while (len) { /* @@ -89,6 +95,9 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) */ hcp->desc.pbuf = 0; hcp->desc.cntinfo = HPCDMA_EOX; + dma_cache_sync(hd->dev, hd->cpu, + (unsigned long)(hcp + 1) - (unsigned long)hd->cpu, + DMA_TO_DEVICE); } static int dma_setup(struct scsi_cmnd *cmd, int datainp) @@ -96,9 +105,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->device->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hdata->cpu); hdata->wh.dma_dir = datainp; @@ -111,12 +119,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries(hcp, cmd, datainp); + fill_hpc_entries(hdata, cmd, datainp); pr_debug(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = hdata->hd.dma; + hregs->ndptr = hdata->dma; if (datainp) hregs->ctrl = HPC3_SCTRL_ACTIVE; else @@ -134,6 +142,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, if (!SCpnt) return; + if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0) + return; + hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; pr_debug("dma_stop: status<%d> ", status); @@ -145,8 +156,9 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, barrier(); } hregs->ctrl = 0; - dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, -SCpnt->sc_data_direction); + dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle, +SCpnt->SCp.this_residual, +
[PATCH] SUN3X_ESP: converted to esp_scsi.c
Converted sun3x_esp driver to use esp_scsi.c Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- drivers/scsi/Kconfig |1 + drivers/scsi/Makefile|2 +- drivers/scsi/sun3x_esp.c | 546 -- 3 files changed, 237 insertions(+), 312 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 14fc7f3..fa86f34 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1779,6 +1779,7 @@ config SUN3_SCSI config SUN3X_ESP bool "Sun3x ESP SCSI" depends on SUN3X && SCSI=y + select SCSI_SPI_ATTRS help The ESP was an on-board SCSI controller used on Sun 3/80 machines. Say Y here to compile in support for it. diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 93e1428..999327d 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -118,7 +118,7 @@ obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o obj-$(CONFIG_SCSI_PPA) += ppa.o obj-$(CONFIG_SCSI_IMM) += imm.o obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o -obj-$(CONFIG_SUN3X_ESP)+= NCR53C9x.o sun3x_esp.o +obj-$(CONFIG_SUN3X_ESP)+= esp_scsi.o sun3x_esp.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 1bc4190..06152c7 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -1,392 +1,316 @@ -/* sun3x_esp.c: EnhancedScsiProcessor Sun3x SCSI driver code. +/* sun3x_esp.c: ESP front-end for Sun3x systems. * - * (C) 1999 Thomas Bogendoerfer ([EMAIL PROTECTED]) - * - * Based on David S. Miller's esp driver + * Copyright (C) 2007,2008 Thomas Bogendoerfer ([EMAIL PROTECTED]) */ #include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include -#include "scsi.h" -#include -#include "NCR53C9x.h" - #include +#include +#include #include -#include - -static void dma_barrier(struct NCR_ESP *esp); -static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); -static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp); -static void dma_drain(struct NCR_ESP *esp); -static void dma_invalidate(struct NCR_ESP *esp); -static void dma_dump_state(struct NCR_ESP *esp); -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_ints_off(struct NCR_ESP *esp); -static void dma_ints_on(struct NCR_ESP *esp); -static int dma_irq_p(struct NCR_ESP *esp); -static void dma_poll(struct NCR_ESP *esp, unsigned char *vaddr); -static int dma_ports_p(struct NCR_ESP *esp); -static void dma_reset(struct NCR_ESP *esp); -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); -static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp); -static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp); -static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp); -static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp); -static void dma_advance_sg (Scsi_Cmnd *sp); - -/* Detecting ESP chips on the machine. This is the simple and easy - * version. - */ -int sun3x_esp_detect(struct scsi_host_template *tpnt) -{ - struct NCR_ESP *esp; - struct ConfigDev *esp_dev; - - esp_dev = 0; - esp = esp_allocate(tpnt, esp_dev, 0); - - /* Do command transfer with DMA */ - esp->do_pio_cmds = 0; - - /* Required functions */ - esp->dma_bytes_sent = &dma_bytes_sent; - esp->dma_can_transfer = &dma_can_transfer; - esp->dma_dump_state = &dma_dump_state; - esp->dma_init_read = &dma_init_read; - esp->dma_init_write = &dma_init_write; - esp->dma_ints_off = &dma_ints_off; - esp->dma_ints_on = &dma_ints_on; - esp->dma_irq_p = &dma_irq_p; - esp->dma_ports_p = &dma_ports_p; - esp->dma_setup = &dma_setup; - - /* Optional functions */ - esp->dma_barrier = &dma_barrier; - esp->dma_invalidate = &dma_invalidate; - esp->dma_drain = &dma_drain; - esp->dma_irq_entry = 0; - esp->dma_irq_exit = 0; - esp->dma_led_on = 0; - esp->dma_led_off = 0; - esp->dma_poll = &dma_poll; - esp->dma_reset = &dma_reset; - -/* virtual DMA functions */ -esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; -esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; -esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; -esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; -
Re: [SCSI] sun3x_esp: convert to esp_scsi
On Sun, Feb 10, 2008 at 10:38:15AM +0100, Kars de Jong wrote: > Thomas, can't you use ioreadxx() and friends instead of rolling your own > memory mapped I/O handlers? well, at least ioread32be/iowrite32be are looking promising, but a quick grep didn't show them for m68k. > readxx() and friends are only to be used on PCI-like buses. hmm, afaik readxx/writexx is not directly related to PCI. It's like ioread/iowrite to access iomapped address space. The difference to ioread/iowrite is that it doesn't support PCI IO space. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Cleanup sni_53c710
- base address is now a physical address; no need to convert it - remove not needed error printk in module init function Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index a7dfb65..0a6b45b 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c @@ -84,7 +84,7 @@ static int __init snirm710_probe(struct platform_device *dev) hostdata->dev = &dev->dev; dma_set_mask(&dev->dev, DMA_32BIT_MASK); - hostdata->base = ioremap_nocache(CPHYSADDR(base), 0x100); + hostdata->base = ioremap_nocache(base, 0x100); hostdata->differential = 0; hostdata->clock = SNIRM710_CLOCK; @@ -141,13 +141,7 @@ static struct platform_driver snirm710_driver = { static int __init snirm710_init(void) { - int err; - - if ((err = platform_driver_register(&snirm710_driver))) { - printk(KERN_ERR "Driver registration failed\n"); - return err; - } - return 0; + return platform_driver_register(&snirm710_driver); } static void __exit snirm710_exit(void) -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Remove printk, which triggers because of low scsi clock on SNI RMs
remove printk, which triggers because of low scsi clock on SNI RMs Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index cb02656..b5ee4b3 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -267,8 +267,6 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata, offset = max_offset; } if(XFERP < min_xferp) { - printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n", - XFERP, min_xferp); XFERP = min_xferp; } return (offset & 0x0f) | (XFERP & 0x07)<<4; -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: PATCH: SNI RM 53c710 driver
On Tue, Jan 02, 2007 at 11:52:41AM +, Christoph Hellwig wrote: > On Mon, Dec 25, 2006 at 09:32:04PM +0100, Thomas Bogendoerfer wrote: > > This patch adds a SCSI driver for the onboard 53c710 chip of some > > SNI RM machines. > > Nice, this looks really clean. I haven't seen the code to declare > the platform devices in the mips queue yet, do you plan to submit it > soon? yes, it's now in Ralf queue branch and I hope it gets merged in the 2.6.21 timeframe. > Please just write this as: ok, attached is a new diff. Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- drivers/scsi/Kconfig |9 +++ drivers/scsi/Makefile |1 + drivers/scsi/sni_53c710.c | 153 + 7 files changed, 187 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 60f5827..9417042 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -973,6 +973,15 @@ config SCSI_LASI700 many PA-RISC workstations & servers. If you do not know whether you have a Lasi chip, it is safe to say "Y" here. +config SCSI_SNI_53C710 + tristate "SNI RM SCSI support for 53c710" + depends on SNI_RM && SCSI + select SCSI_SPI_ATTRS + select 53C700_LE_ON_BE + help + This is a driver for the onboard SCSI controller found in older + SNI RM workstations & servers. + config 53C700_LE_ON_BE bool depends on SCSI_LASI700 diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index bd7c988..79ecf4e 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -124,6 +124,7 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o ja obj-$(CONFIG_SUN3X_ESP)+= NCR53C9x.o sun3x_esp.o obj-$(CONFIG_SCSI_FCAL)+= fcal.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o +obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_IPR) += ipr.o obj-$(CONFIG_SCSI_SRP) += libsrp.o diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c new file mode 100644 index 000..6199ab6 --- /dev/null +++ b/drivers/scsi/sni_53c710.c @@ -0,0 +1,153 @@ +/* -*- mode: c; c-basic-offset: 8 -*- */ + +/* SNI RM driver + * + * Copyright (C) 2001 by [EMAIL PROTECTED] +**- +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +**- + */ + +/* + * Based on lasi700.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "53c700.h" + +MODULE_AUTHOR("Thomas Bogendörfer"); +MODULE_DESCRIPTION("SNI RM 53c710 SCSI Driver"); +MODULE_LICENSE("GPL"); + +#define SNIRM710_CLOCK 32 + +static struct scsi_host_template snirm710_template = { + .name = "SNI RM SCSI 53c710", + .proc_name = "snirm_53c710", + .this_id= 7, + .module = THIS_MODULE, +}; + +static int __init snirm710_probe(struct platform_device *dev) +{ + unsigned long base; + struct NCR_700_Host_Parameters *hostdata; + struct Scsi_Host *host; + struct resource *res; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + base = res->start; + hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); + if (!hostdata) { + printk(KERN_ERR "%s: Failed to allocate host data\n", + dev->dev.bus_id); + return -ENOMEM; + } + + hostdata->dev = &dev->dev; + dma_set_mask(&dev->dev, DMA_32BIT_MASK); + hostdata->base = ioremap_nocache(CPHYSADDR(base), 0x100); + hostdata->differential = 0; + + hostdata->clock = SNIRM710_CLOCK; + hostdata->force_le_on_be = 1; + hostdata->chip710 = 1; + hostdata->burst_length = 4; + +
[PATCH] jazz_esp converted to use esp_core
Hi, after chasing and fixing two jazz platform bugs and one MIPS dma mapping bug, I finally succeeded in using the Dave's new esp_core (great work, thank you Dave). Below is the patch. Thomas. Use new SCCI_ESP_CORE for JAZZ SCSS host adapter driver Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d28c14e..62d62ab 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1532,6 +1532,7 @@ source "drivers/scsi/arm/Kconfig" config JAZZ_ESP bool "MIPS JAZZ FAS216 SCSI support" depends on MACH_JAZZ && SCSI + select SCSI_ESP_CORE help This is the driver for the onboard SCSI host adapter of MIPS Magnum 4000, Acer PICA, Olivetti M700-10 and a few other identical OEM diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 51e884f..b348600 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -121,7 +121,7 @@ obj-$(CONFIG_BLK_DEV_3W__RAID) += 3w-.o obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o obj-$(CONFIG_SCSI_PPA) += ppa.o obj-$(CONFIG_SCSI_IMM) += imm.o -obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o +obj-$(CONFIG_JAZZ_ESP) += jazz_esp.o obj-$(CONFIG_SUN3X_ESP)+= NCR53C9x.o sun3x_esp.o obj-$(CONFIG_SCSI_FCAL)+= fcal.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 19dd4b9..18f7d4e 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -1,307 +1,277 @@ -/* - * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture) +/* jazz_esp.c: ESP front-end for MIPS JAZZ systems. * - * Copyright (C) 1997 Thomas Bogendoerfer ([EMAIL PROTECTED]) - * - * jazz_esp is based on David S. Miller's ESP driver and cyber_esp + * Copyright (C) 2007 Thomas Bogendörfer ([EMAIL PROTECTED]) */ -#include #include -#include #include -#include -#include -#include -#include -#include - -#include "scsi.h" -#include -#include "NCR53C9x.h" +#include +#include +#include +#include +#include #include +#include +#include + #include #include -#include -#include - -static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); -static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_dump_state(struct NCR_ESP *esp); -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_ints_off(struct NCR_ESP *esp); -static void dma_ints_on(struct NCR_ESP *esp); -static int dma_irq_p(struct NCR_ESP *esp); -static int dma_ports_p(struct NCR_ESP *esp); -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); -static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_advance_sg (struct scsi_cmnd *sp); -static void dma_led_off(struct NCR_ESP *); -static void dma_led_on(struct NCR_ESP *); - - -static volatile unsigned char cmd_buffer[16]; - /* This is where all commands are put -* before they are trasfered to the ESP chip -* via PIO. -*/ - -static int jazz_esp_release(struct Scsi_Host *shost) -{ - if (shost->irq) - free_irq(shost->irq, NULL); - if (shost->dma_channel != 0xff) - free_dma(shost->dma_channel); - if (shost->io_port && shost->n_io_port) - release_region(shost->io_port, shost->n_io_port); - scsi_unregister(shost); - return 0; -} +#include -/* Detection */ -static int jazz_esp_detect(struct scsi_host_template *tpnt) -{ -struct NCR_ESP *esp; -struct ConfigDev *esp_dev; - -/* - * first assumption it is there:-) - */ -if (1) { - esp_dev = NULL; - esp = esp_allocate(tpnt, esp_dev, 0); - - /* Do command transfer with programmed I/O */ - esp->do_pio_cmds = 1; - - /* Required functions */ - esp->dma_bytes_sent = &dma_bytes_sent; - esp->dma_can_transfer = &dma_can_transfer; - esp->dma_dump_state = &dma_dump_state; - esp->dma_init_read = &dma_init_read; - esp->dma_init_write = &dma_init_write; - esp->dma_ints_off = &dma_ints_off; - esp->dma_ints_on = &dma_ints_on; - esp->dma_irq_p = &dma_irq_p; - esp->dma_
Re: [PATCH] jazz_esp converted to use esp_core
On Tue, May 22, 2007 at 12:00:41AM +0100, Christoph Hellwig wrote: > On Mon, May 21, 2007 at 11:02:24PM +0200, Thomas Bogendoerfer wrote: > > after chasing and fixing two jazz platform bugs and one MIPS dma mapping > > bug, I finally succeeded in using the Dave's new esp_core (great work, > > thank you Dave). Below is the patch. > > Very nice driver. The only thing that confused me a little are > the various helper functions split out of esp_jazz_probe that > make the code a bit odd to read. Are these intentional or a carry > over from the previous driver? the sparc frontend used them, because most of these helper are checking for prom properties, which the jazz doesn't have. I've changed that and folded those little helpers into the probe function. I'll send a new patch a couple of minutes. > > --- a/drivers/scsi/Makefile > > +++ b/drivers/scsi/Makefile > > @@ -121,7 +121,7 @@ obj-$(CONFIG_BLK_DEV_3W__RAID) += 3w-.o > > obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o > > obj-$(CONFIG_SCSI_PPA) += ppa.o > > obj-$(CONFIG_SCSI_IMM) += imm.o > > -obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o > > +obj-$(CONFIG_JAZZ_ESP) += jazz_esp.o > > Note to Dave: it probably would be nice to just build esp_scsi.o > from the makefile like the old NCR53C9x drivers did instead of the > Kconfig hackery, what do you think? after seeing no objection to using esp_scsi.o like NCR53C9x.o, I also changed that. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[UPDATED PATCH] jazz_esp converted to use esp_core
Here is an updated patch for converting jazz_esp to use esp_scsi. Thomas. Use new esp_scsi for JAZZ SCSI host adapter driver Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]> --- diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 51e884f..fc05d90 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -121,7 +121,7 @@ obj-$(CONFIG_BLK_DEV_3W__RAID) += 3w-.o obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o obj-$(CONFIG_SCSI_PPA) += ppa.o obj-$(CONFIG_SCSI_IMM) += imm.o -obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o +obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o obj-$(CONFIG_SUN3X_ESP)+= NCR53C9x.o sun3x_esp.o obj-$(CONFIG_SCSI_FCAL)+= fcal.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 19dd4b9..10ceda1 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -1,307 +1,244 @@ -/* - * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture) +/* jazz_esp.c: ESP front-end for MIPS JAZZ systems. * - * Copyright (C) 1997 Thomas Bogendoerfer ([EMAIL PROTECTED]) - * - * jazz_esp is based on David S. Miller's ESP driver and cyber_esp + * Copyright (C) 2007 Thomas Bogendörfer ([EMAIL PROTECTED]) */ -#include #include -#include #include -#include -#include -#include -#include -#include - -#include "scsi.h" -#include -#include "NCR53C9x.h" +#include +#include +#include +#include +#include #include -#include -#include +#include #include -#include - -static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); -static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_dump_state(struct NCR_ESP *esp); -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_ints_off(struct NCR_ESP *esp); -static void dma_ints_on(struct NCR_ESP *esp); -static int dma_irq_p(struct NCR_ESP *esp); -static int dma_ports_p(struct NCR_ESP *esp); -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); -static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); -static void dma_advance_sg (struct scsi_cmnd *sp); -static void dma_led_off(struct NCR_ESP *); -static void dma_led_on(struct NCR_ESP *); - - -static volatile unsigned char cmd_buffer[16]; - /* This is where all commands are put -* before they are trasfered to the ESP chip -* via PIO. -*/ - -static int jazz_esp_release(struct Scsi_Host *shost) -{ - if (shost->irq) - free_irq(shost->irq, NULL); - if (shost->dma_channel != 0xff) - free_dma(shost->dma_channel); - if (shost->io_port && shost->n_io_port) - release_region(shost->io_port, shost->n_io_port); - scsi_unregister(shost); - return 0; -} - -/* Detection */ -static int jazz_esp_detect(struct scsi_host_template *tpnt) -{ -struct NCR_ESP *esp; -struct ConfigDev *esp_dev; - -/* - * first assumption it is there:-) - */ -if (1) { - esp_dev = NULL; - esp = esp_allocate(tpnt, esp_dev, 0); - - /* Do command transfer with programmed I/O */ - esp->do_pio_cmds = 1; - - /* Required functions */ - esp->dma_bytes_sent = &dma_bytes_sent; - esp->dma_can_transfer = &dma_can_transfer; - esp->dma_dump_state = &dma_dump_state; - esp->dma_init_read = &dma_init_read; - esp->dma_init_write = &dma_init_write; - esp->dma_ints_off = &dma_ints_off; - esp->dma_ints_on = &dma_ints_on; - esp->dma_irq_p = &dma_irq_p; - esp->dma_ports_p = &dma_ports_p; - esp->dma_setup = &dma_setup; - - /* Optional functions */ - esp->dma_barrier = NULL; - esp->dma_drain = NULL; - esp->dma_invalidate = NULL; - esp->dma_irq_entry = NULL; - esp->dma_irq_exit = NULL; - esp->dma_poll = NULL; - esp->dma_reset = NULL; - esp->dma_led_off = &dma_led_off; - esp->dma_led_on = &dma_led_on; - - /* virtual DMA functions */ - esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; - esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; - esp->dma_mmu_re
[PATCH] scsi: qla1280: set 64bit coherent mask
After Commit 54aed4dd3526 ("MIPS: IP27: use dma_direct_ops") qla1280 driver failed on SGI IP27 machines with qla1280: QLA1040 found on PCI bus 0, dev 0 qla1280 :00:00.0: enabling device (0006 -> 0007) qla1280: Failed to get request memory qla1280: probe of :00:00.0 failed with error -12 Reason is that SGI IP27 always generates 64bit DMA addresses and has no fallback mode for 32bit DMA addresses implemented. QLA1280 supports 64bit addressing for all DMA accesses so setting coherent mask to 64bit fixes the issue. Signed-off-by: Thomas Bogendoerfer --- drivers/scsi/qla1280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index a414f51302b7..6856dfdfa473 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -4248,7 +4248,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->devnum = devnum;/* specifies microcode load address */ #ifdef QLA_64BIT_PTR - if (dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) { + if (dma_set_mask_and_coherent(&ha->pdev->dev, DMA_BIT_MASK(64))) { if (dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(32))) { printk(KERN_WARNING "scsi(%li): Unable to set a " "suitable DMA mask - aborting\n", ha->host_no); -- 2.13.7
Re: [PATCH 10/12] scsi: remove the mvme147 driver
On Wed, 14 Mar 2018 11:58:25 -0400 "Martin K. Petersen" wrote: > I'm happy to keep things in the tree if they are: > > 1) maintained and tested > 2) actively used > 3) not blocking removal of legacy interfaces I own a MVME147, so if needed I could get it out of the closet and fix the driver for it. Thomas. -- SUSE Linux GmbH GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg)
[PATCH] scsi: qedf: Limit number of CQs
From: Thomas Bogendoerfer FCOE offloading on qedf devices fails with: [qed_sp_fcoe_func_start:150(sp-0-3b:00.02)]Cannot satisfy CQ amount. CQs requested 8, CQs available 6. Aborting function start [qed_fcoe_start:821()]Failed to start fcoe [__qedf_probe:3041]:6: Cannot start FCoE function. The reason is a newly introduced check in the qed main part. This change also provides the information about how many CQs are available, so we simply limit the number of requested CQs. Fixes: 3c5da9427802 qed: Share additional information with qedf Signed-off-by: Thomas Bogendoerfer --- drivers/scsi/qedf/qedf_main.c | 16 +--- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index b58bba4604e8..5778218734fa 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -2765,6 +2765,8 @@ static int qedf_set_fcoe_pf_param(struct qedf_ctx *qedf) */ qedf->num_queues = min((unsigned int)QEDF_MAX_NUM_CQS, num_online_cpus()); + /* limit to acutal available CQs */ + qedf->num_queues = min(qedf->num_queues, qedf->dev_info.num_cqs); QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Number of CQs is %d.\n", qedf->num_queues); @@ -2962,6 +2964,13 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) goto err1; } + /* Learn information crucial for qedf to progress */ + rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info); + if (rc) { + QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n"); + goto err1; + } + /* queue allocation code should come here * order should be * slowpath_start @@ -2977,13 +2986,6 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) } qed_ops->common->update_pf_params(qedf->cdev, &qedf->pf_params); - /* Learn information crucial for qedf to progress */ - rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info); - if (rc) { - QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n"); - goto err1; - } - /* Record BDQ producer doorbell addresses */ qedf->bdq_primary_prod = qedf->dev_info.primary_dbq_rq_addr; qedf->bdq_secondary_prod = qedf->dev_info.secondary_bdq_rq_addr; -- 2.12.3
[PATCH v2] scsi: qedf: Limit number of CQs
From: Thomas Bogendoerfer FCOE offloading failed with: [qed_sp_fcoe_func_start:150(sp-0-3b:00.02)]Cannot satisfy CQ amount. CQs requested 8, CQs available 6. Aborting function start [qed_fcoe_start:821()]Failed to start fcoe [__qedf_probe:3041]:6: Cannot start FCoE function. The reason is a newly introduced check in the qed main part. This change also provides the information about how many CQs are available, so we simply limit the number of requested CQs.. Fixes: 3c5da9427802 ("qed: Share additional information with qedf") Signed-off-by: Thomas Bogendoerfer --- Changes in v2: - integrated suggested change from Chad Dupuis drivers/scsi/qedf/qedf.h | 3 ++- drivers/scsi/qedf/qedf_main.c | 20 +--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index 4d038926a455..351f06dfc5a0 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -528,7 +528,8 @@ struct fip_vlan { #define QEDF_WRITE(1 << 0) #define MAX_FIBRE_LUNS 0x -#define QEDF_MAX_NUM_CQS 8 +#define MIN_NUM_CPUS_MSIX(x) min_t(u32, x->dev_info.num_cqs, \ + num_online_cpus()) /* * PCI function probe defines diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 7786c97e033f..1d13c9ca517d 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -2760,11 +2760,9 @@ static int qedf_set_fcoe_pf_param(struct qedf_ctx *qedf) * we allocation is the minimum off: * * Number of CPUs -* Number of MSI-X vectors -* Max number allocated in hardware (QEDF_MAX_NUM_CQS) +* Number allocated by qed for our PCI function */ - qedf->num_queues = min((unsigned int)QEDF_MAX_NUM_CQS, - num_online_cpus()); + qedf->num_queues = MIN_NUM_CPUS_MSIX(qedf); QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Number of CQs is %d.\n", qedf->num_queues); @@ -2962,6 +2960,13 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) goto err1; } + /* Learn information crucial for qedf to progress */ + rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info); + if (rc) { + QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n"); + goto err1; + } + /* queue allocation code should come here * order should be * slowpath_start @@ -2977,13 +2982,6 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) } qed_ops->common->update_pf_params(qedf->cdev, &qedf->pf_params); - /* Learn information crucial for qedf to progress */ - rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info); - if (rc) { - QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n"); - goto err1; - } - /* Record BDQ producer doorbell addresses */ qedf->bdq_primary_prod = qedf->dev_info.primary_dbq_rq_addr; qedf->bdq_secondary_prod = qedf->dev_info.secondary_bdq_rq_addr; -- 2.12.3
PATCH: Allow setting burst length for 53C700
This is a patch, which allows not only disabling bursting but to specify different burst lenghts. This feature is needed to get the 53c700 driver working for the onboard SCSI controller of SNI RM machines, which only work reliable with a 4 word burst length. Thomas. >From eb46a70296fd0615ac7d8ee036d0554e8d30c1f2 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer <[EMAIL PROTECTED]> Date: Mon, 25 Dec 2006 20:48:34 +0100 Subject: [PATCH] change burst_disable to burst_length to allow setting of different burst lengths --- drivers/scsi/53c700.c | 24 +--- drivers/scsi/53c700.h |2 +- drivers/scsi/lasi700.c |1 + drivers/scsi/sim710.c |1 + 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 68103e5..92030fa 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -667,12 +667,30 @@ NCR_700_chip_setup(struct Scsi_Host *hos __u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); if(hostdata->chip710) { - __u8 burst_disable = hostdata->burst_disable - ? BURST_DISABLE : 0; + __u8 burst_disable = 0; + __u8 burst_length = 0; + + switch (hostdata->burst_length) { + case 1: + burst_length = BURST_LENGTH_1; + break; + case 2: + burst_length = BURST_LENGTH_2; + break; + case 4: + burst_length = BURST_LENGTH_4; + break; + case 8: + burst_length = BURST_LENGTH_8; + break; + default: + burst_disable = BURST_DISABLE; + break; + } dcntl_extra = COMPAT_700_MODE; NCR_700_writeb(dcntl_extra, host, DCNTL_REG); - NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra, + NCR_700_writeb(burst_length | hostdata->dmode_extra, host, DMODE_710_REG); NCR_700_writeb(burst_disable | (hostdata->differential ? DIFF : 0), host, CTEST7_REG); diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index f38822d..0292410 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h @@ -203,7 +203,7 @@ #ifdef CONFIG_53C700_LE_ON_BE __u32 force_le_on_be:1; #endif __u32 chip710:1; /* set if really a 710 not 700 */ - __u32 burst_disable:1;/* set to 1 to disable 710 bursting */ + __u32 burst_length:4; /* set to 0 to disable 710 bursting */ /* NOTHING BELOW HERE NEEDS ALTERING */ __u32 fast:1; /* if we can alter the SCSI bus clock diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index f0871c3..2aae1b0 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -123,6 +123,7 @@ lasi700_probe(struct parisc_device *dev) hostdata->force_le_on_be = 0; hostdata->chip710 = 1; hostdata->dmode_extra = DMODE_FC2; + hostdata->burst_length = 8; } host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev); diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 551bacc..018c65f 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -123,6 +123,7 @@ sim710_probe_common(struct device *dev, hostdata->differential = differential; hostdata->clock = clock; hostdata->chip710 = 1; + hostdata->burst_length = 8; /* and register the chip */ if((host = NCR_700_detect(&sim710_driver_template, hostdata, dev)) -- 1.4.3.2 -- Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea.[ RFC1925, 2.3 ] - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH: SNI RM 53c710 driver
This patch adds a SCSI driver for the onboard 53c710 chip of some SNI RM machines. Thomas. >From ec2d61072027892d67a34d261bd39b32bacd1e64 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer <[EMAIL PROTECTED]> Date: Mon, 25 Dec 2006 21:04:17 +0100 Subject: [PATCH] Support for onboard SCSI controller on older SNI RM machines --- drivers/scsi/Kconfig |9 +++ drivers/scsi/Makefile |1 + drivers/scsi/sni_53c710.c | 159 + 3 files changed, 169 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 60f5827..9417042 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -973,6 +973,15 @@ config SCSI_LASI700 many PA-RISC workstations & servers. If you do not know whether you have a Lasi chip, it is safe to say "Y" here. +config SCSI_SNI_53C710 + tristate "SNI RM SCSI support for 53c710" + depends on SNI_RM && SCSI + select SCSI_SPI_ATTRS + select 53C700_LE_ON_BE + help + This is a driver for the onboard SCSI controller found in older + SNI RM workstations & servers. + config 53C700_LE_ON_BE bool depends on SCSI_LASI700 diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index bd7c988..79ecf4e 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -124,6 +124,7 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o ja obj-$(CONFIG_SUN3X_ESP)+= NCR53C9x.o sun3x_esp.o obj-$(CONFIG_SCSI_FCAL)+= fcal.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o +obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_IPR) += ipr.o obj-$(CONFIG_SCSI_SRP) += libsrp.o diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c new file mode 100644 index 000..163fd44 --- /dev/null +++ b/drivers/scsi/sni_53c710.c @@ -0,0 +1,159 @@ +/* -*- mode: c; c-basic-offset: 8 -*- */ + +/* SNI RM driver + * + * Copyright (C) 2001 by [EMAIL PROTECTED] +**- +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +**- + */ + +/* + * Based on lasi700.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "53c700.h" + +MODULE_AUTHOR("Thomas Bogendörfer"); +MODULE_DESCRIPTION("SNI RM 53c710 SCSI Driver"); +MODULE_LICENSE("GPL"); + +#define SNIRM710_CLOCK 32 + +static struct scsi_host_template snirm710_template = { + .name = "SNI RM SCSI 53c710", + .proc_name = "snirm_53c710", + .this_id= 7, + .module = THIS_MODULE, +}; + +static int __init snirm710_probe(struct platform_device *dev) +{ + unsigned long base; + struct NCR_700_Host_Parameters *hostdata; + struct Scsi_Host *host; + struct resource *res; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + base = res->start; + hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); + if (!hostdata) { + printk(KERN_ERR "%s: Failed to allocate host data\n", + dev->dev.bus_id); + return -ENOMEM; + } + + hostdata->dev = &dev->dev; + dma_set_mask(&dev->dev, DMA_32BIT_MASK); + hostdata->base = ioremap_nocache(CPHYSADDR(base), 0x100); + hostdata->differential = 0; + + hostdata->clock = SNIRM710_CLOCK; + hostdata->force_le_on_be = 1; + hostdata->chip710 = 1; + hostdata->burst_length = 4; + + host = NCR_700_detect(&snirm710_template, hostdata, &dev->dev); + if (!host) + goto out_kfree; + host->this_id = 7; + host->base = base; + host->irq = platform_get_irq(dev, 0); + if(request_irq(host->irq, NCR_700_i