public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3
@ 2008-10-02  7:58 Andi Kleen
  2008-10-02  7:58 ` [PATCH] [1/21] SCSI-ISA-DMA: Add the alloc/get_pages_mask calls Andi Kleen
                   ` (21 more replies)
  0 siblings, 22 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


This reposts the patchkit to remove unchecked_isa_dma which was already
discussed some time ago. Instead it replaces it with interfaces
that declare the mask. Right now those interfaces map back to GFP_DMA
eventually, but it is a preparation for using the DMA mask allocator
eventually.

The previous time there were some disagreement on where to handle
the sense buffer bouncing which was done in low level drivers 
in Boaz' version of the patchkit. I went back to the original
code which keeps sense buffer bouncing in the mid layer, which
should be non controversal.

I also removed blk_kmalloc and went back to the blk_q_mask() interfaces.

I believe there were no other controversies, so this should be ready
for merging now.

Other main changes was to forward port it to 2.6.27rc8 and doing some 
retesting.

The changes are also available for pulling from

  git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc-2.6 scsi-dma

Andi Kleen (21):
      SCSI-ISA-DMA: Add the alloc/get_pages_mask calls
      SCSI-ISA-DMA: Add blk_q_mask
      SCSI-ISA-DMA: Pass gfp to scsi_allocate_command
      SCSI-ISA-DMA: Add sense_buffer_isa to host template
      SCSI-ISA-DMA: Remove unchecked_isa in BusLogic
      SCSI-ISA-DMA: Remove unchecked_isa_dma in advansys.c
      SCSI-ISA-DMA: Remove unchecked_isa_dma in gdth
      SCSI-ISA-DMA: Remove unchecked_isa_dma in eata.c
      SCSI-ISA-DMA: Remove unchecked_isa_dma in aha1542
      SCSI-ISA-DMA: Remove unchecked_isa_dma in aha152x/wd7000/sym53c416/u14-34f/NCR53c406a
      SCSI-ISA-DMA: Remove GFP_DMA uses in st/osst
      SCSI-ISA-DMA: Remove unchecked_isa_dma support for hostdata
      SCSI-ISA-DMA: Use blk_q_mask/get_pages_mask in sg driver
      SCSI-ISA-DMA: Rely on block layer bouncing for ISA DMA devices scanning
      SCSI-ISA-DMA: Don't disable direct_io for unchecked_isa_dma in st.c
      SCSI-ISA-DMA: Remove automatic block layer bouncing for unchecked_isa_dma
      SCSI-ISA-DMA: Remove GFP_DMA use in sr.c
      SCSI-ISA-DMA: Remove unchecked_isa_dma from sysfs
      SCSI-ISA-DMA: Switch to a single SCSI command pool
      SCSI-ISA-DMA: Finally kill unchecked_isa_dma
      SCSI-ISA-DMA: Convert DMA buffers in ch.c to allocate via the block layer

 Documentation/scsi/scsi_mid_low_api.txt |    4 +-
 drivers/scsi/BusLogic.c                 |   77 +++++++++++----
 drivers/scsi/NCR53c406a.c               |    8 ++-
 drivers/scsi/advansys.c                 |  162 ++++++++++++++++++++-----------
 drivers/scsi/aha152x.c                  |   29 +++++-
 drivers/scsi/aha1542.c                  |   40 ++++++--
 drivers/scsi/ch.c                       |   16 ++-
 drivers/scsi/eata.c                     |   54 ++++++++---
 drivers/scsi/gdth.c                     |   81 ++++++++++++----
 drivers/scsi/hosts.c                    |    5 +-
 drivers/scsi/osst.c                     |   24 ++---
 drivers/scsi/osst.h                     |    2 -
 drivers/scsi/scsi.c                     |   93 +++++++++++-------
 drivers/scsi/scsi_lib.c                 |    2 -
 drivers/scsi/scsi_scan.c                |    6 +-
 drivers/scsi/scsi_sysfs.c               |    2 -
 drivers/scsi/sg.c                       |   48 +++-------
 drivers/scsi/sr.c                       |    2 +-
 drivers/scsi/sr_ioctl.c                 |   13 +--
 drivers/scsi/sr_vendor.c                |    4 +-
 drivers/scsi/st.c                       |   37 +++----
 drivers/scsi/st.h                       |    2 -
 drivers/scsi/sym53c416.c                |    9 ++-
 drivers/scsi/u14-34f.c                  |   54 ++++++++---
 drivers/scsi/ultrastor.c                |   13 ++-
 drivers/scsi/wd7000.c                   |   48 ++++++---
 include/linux/blkdev.h                  |    5 +
 include/linux/gfp.h                     |   22 ++++-
 include/scsi/scsi_cmnd.h                |    5 +-
 include/scsi/scsi_host.h                |   14 ++-
 30 files changed, 569 insertions(+), 312 deletions(-)




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [1/21] SCSI-ISA-DMA: Add the alloc/get_pages_mask calls
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [2/21] SCSI-ISA-DMA: Add blk_q_mask Andi Kleen
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


[Merge note: this patch will be in a SCSI patchkit and in the core
mask allocator patchkit. They are equivalent. If one of them 
is merged first simply drop it in the other]

Add the compat version of the *_pages_* calls. These just check
if the mask is inside the DMA range and if yes set __GFP_DMA.

This is needed so that some code can start using the _mask calls
early.

Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 include/linux/gfp.h |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

Index: linux/include/linux/gfp.h
===================================================================
--- linux.orig/include/linux/gfp.h
+++ linux/include/linux/gfp.h
@@ -4,6 +4,7 @@
 #include <linux/mmzone.h>
 #include <linux/stddef.h>
 #include <linux/linkage.h>
+#include <asm/dma.h>  /* For TRAD_DMA_MASK/MAX_DMA_ADDRESS */
 
 struct vm_area_struct;
 
@@ -234,14 +235,29 @@ void free_pages_exact(void *virt, size_t
 #define __get_free_page(gfp_mask) \
 		__get_free_pages((gfp_mask),0)
 
-#define __get_dma_pages(gfp_mask, order) \
-		__get_free_pages((gfp_mask) | GFP_DMA,(order))
-
 extern void __free_pages(struct page *page, unsigned int order);
 extern void free_pages(unsigned long addr, unsigned int order);
 extern void free_hot_page(struct page *page);
 extern void free_cold_page(struct page *page);
 
+#define gfp_mask(m) ((__pa(MAX_DMA_ADDRESS - 1) & (m)) ? 0 : __GFP_DMA)
+
+#define alloc_pages_mask(gfp, size, mask) \
+	alloc_pages((gfp) | gfp_mask(mask), get_order(size))
+#define get_pages_mask(gfp, size, mask) \
+	((void *)__get_free_pages((gfp) | gfp_mask(mask), get_order(size)))
+#define __free_pages_mask(p, s) __free_pages((p), get_order(s))
+#define free_pages_mask(addr, s) free_pages((unsigned long)(addr), get_order(s))
+
+#define __get_dma_pages(gfp_mask, order) \
+		__get_free_pages((gfp_mask) | GFP_DMA, (order))
+
+#define get_page_mask(gfp, mask) get_pages_mask((gfp), PAGE_SIZE, mask)
+#define alloc_page_mask(gfp, mask) alloc_pages_mask((gfp), PAGE_SIZE, mask)
+
+#define __free_page_mask(page) __free_pages_mask(page, PAGE_SIZE)
+#define free_page_mask(addr) free_pages_mask((addr), PAGE_SIZE)
+
 #define __free_page(page) __free_pages((page), 0)
 #define free_page(addr) free_pages((addr),0)
 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [2/21] SCSI-ISA-DMA: Add blk_q_mask
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
  2008-10-02  7:58 ` [PATCH] [1/21] SCSI-ISA-DMA: Add the alloc/get_pages_mask calls Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [3/21] SCSI-ISA-DMA: Pass gfp to scsi_allocate_command Andi Kleen
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


[Merge note: this patch will be in a SCSI patchkit and in the core
mask allocator patchkit. They are equivalent. If one of them 
is merged first simply drop it in the other]

Converts the queue bounce_pfn to a DMA mask suitable for the mask allocator

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 include/linux/blkdev.h |    5 +++++
 1 file changed, 5 insertions(+)

Index: linux/include/linux/blkdev.h
===================================================================
--- linux.orig/include/linux/blkdev.h
+++ linux/include/linux/blkdev.h
@@ -890,6 +890,11 @@ static inline unsigned int block_size(st
 	return bdev->bd_block_size;
 }
 
+static inline u64 blk_q_mask(struct request_queue *q)
+{
+	return ~(-1LL << (PAGE_SHIFT + fls64(q->bounce_pfn)));
+}
+
 typedef struct {struct page *v;} Sector;
 
 unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [3/21] SCSI-ISA-DMA: Pass gfp to scsi_allocate_command
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
  2008-10-02  7:58 ` [PATCH] [1/21] SCSI-ISA-DMA: Add the alloc/get_pages_mask calls Andi Kleen
  2008-10-02  7:58 ` [PATCH] [2/21] SCSI-ISA-DMA: Add blk_q_mask Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [4/21] SCSI-ISA-DMA: Add sense_buffer_isa to host template Andi Kleen
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Instead of deciding low level based on unchecked_isa_dma pass in the GFP.
This makes it easier to remove unchecked_isa_dma later and also simplifies some code.

Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/scsi.c      |   45 +++++++++++++++++++++++++++++----------------
 include/scsi/scsi_cmnd.h |    5 +++--
 2 files changed, 32 insertions(+), 18 deletions(-)

Index: linux/include/scsi/scsi_cmnd.h
===================================================================
--- linux.orig/include/scsi/scsi_cmnd.h
+++ linux/include/scsi/scsi_cmnd.h
@@ -151,8 +151,9 @@ extern void scsi_release_buffers(struct 
 extern int scsi_dma_map(struct scsi_cmnd *cmd);
 extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
 
-struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask);
-void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd);
+struct scsi_cmnd *scsi_allocate_command(struct Scsi_Host *shost,
+					gfp_t gfp_mask);
+void scsi_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd);
 
 static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
 {
Index: linux/drivers/scsi/scsi.c
===================================================================
--- linux.orig/drivers/scsi/scsi.c
+++ linux/drivers/scsi/scsi.c
@@ -353,7 +353,8 @@ void scsi_put_command(struct scsi_cmnd *
 }
 EXPORT_SYMBOL(scsi_put_command);
 
-static struct scsi_host_cmd_pool *scsi_get_host_cmd_pool(gfp_t gfp_mask)
+static struct scsi_host_cmd_pool *
+scsi_get_host_cmd_pool(struct Scsi_Host *shost, gfp_t gfp_mask)
 {
 	struct scsi_host_cmd_pool *retval = NULL, *pool;
 	/*
@@ -361,8 +362,9 @@ static struct scsi_host_cmd_pool *scsi_g
 	 * yet existent.
 	 */
 	mutex_lock(&host_cmd_pool_mutex);
-	pool = (gfp_mask & __GFP_DMA) ? &scsi_cmd_dma_pool :
-		&scsi_cmd_pool;
+	pool = &scsi_cmd_pool;
+	if (shost && shost->unchecked_isa_dma)
+		pool = &scsi_cmd_dma_pool;
 	if (!pool->users) {
 		pool->cmd_slab = kmem_cache_create(pool->cmd_name,
 						   sizeof(struct scsi_cmnd), 0,
@@ -386,12 +388,12 @@ static struct scsi_host_cmd_pool *scsi_g
 	return retval;
 }
 
-static void scsi_put_host_cmd_pool(gfp_t gfp_mask)
+static void scsi_put_host_cmd_pool(struct Scsi_Host *shost)
 {
 	struct scsi_host_cmd_pool *pool;
 
 	mutex_lock(&host_cmd_pool_mutex);
-	pool = (gfp_mask & __GFP_DMA) ? &scsi_cmd_dma_pool :
+	pool = (shost && shost->unchecked_isa_dma) ? &scsi_cmd_dma_pool :
 		&scsi_cmd_pool;
 	/*
 	 * This may happen if a driver has a mismatched get and put
@@ -409,6 +411,10 @@ static void scsi_put_host_cmd_pool(gfp_t
 
 /**
  * scsi_allocate_command - get a fully allocated SCSI command
+ * @shost:	SCSI host. Can be NULL, then we assume you have no
+ *		special DMA address requirements for command/sense buffer.
+ *		If you have special DMA requirements you must record
+ *		them in the shost before calling this.
  * @gfp_mask:	allocation mask
  *
  * This function is for use outside of the normal host based pools.
@@ -420,9 +426,16 @@ static void scsi_put_host_cmd_pool(gfp_t
  * This function should *only* be used by drivers that need a static
  * command allocation at start of day for internal functions.
  */
-struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask)
+struct scsi_cmnd *scsi_allocate_command(struct Scsi_Host *shost, gfp_t gfp_mask)
 {
-	struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask);
+	struct scsi_host_cmd_pool *pool;
+
+	/*
+	 * ISA-DMAness should be only decided by flags in shost. Only use the gfp for
+	 * sleeping vs non sleeping if at all.
+	 */
+	BUG_ON(gfp_mask & __GFP_DMA);
+	pool = scsi_get_host_cmd_pool(shost, gfp_mask);
 
 	if (!pool)
 		return NULL;
@@ -433,16 +446,16 @@ EXPORT_SYMBOL(scsi_allocate_command);
 
 /**
  * scsi_free_command - free a command allocated by scsi_allocate_command
- * @gfp_mask:	mask used in the original allocation
+ * @shost:	shost used in the original allocation or NULL
  * @cmd:	command to free
  *
- * Note: using the original allocation mask is vital because that's
+ * Note: using the original shost is vital because that's
  * what determines which command pool we use to free the command.  Any
  * mismatch will cause the system to BUG eventually.
  */
-void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd)
+void scsi_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
 {
-	struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask);
+	struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(shost, 0);
 
 	/*
 	 * this could trigger if the mask to scsi_allocate_command
@@ -458,8 +471,8 @@ void scsi_free_command(gfp_t gfp_mask, s
 	 * reference we took above, and once to release the reference
 	 * originally taken by scsi_allocate_command
 	 */
-	scsi_put_host_cmd_pool(gfp_mask);
-	scsi_put_host_cmd_pool(gfp_mask);
+	scsi_put_host_cmd_pool(shost);
+	scsi_put_host_cmd_pool(shost);
 }
 EXPORT_SYMBOL(scsi_free_command);
 
@@ -481,7 +494,7 @@ int scsi_setup_command_freelist(struct S
 	spin_lock_init(&shost->free_list_lock);
 	INIT_LIST_HEAD(&shost->free_list);
 
-	shost->cmd_pool = scsi_get_host_cmd_pool(gfp_mask);
+	shost->cmd_pool = scsi_get_host_cmd_pool(shost, 0);
 
 	if (!shost->cmd_pool)
 		return -ENOMEM;
@@ -491,7 +504,7 @@ int scsi_setup_command_freelist(struct S
 	 */
 	cmd = scsi_host_alloc_command(shost, gfp_mask);
 	if (!cmd) {
-		scsi_put_host_cmd_pool(gfp_mask);
+		scsi_put_host_cmd_pool(shost);
 		shost->cmd_pool = NULL;
 		return -ENOMEM;
 	}
@@ -520,7 +533,7 @@ void scsi_destroy_command_freelist(struc
 		scsi_pool_free_command(shost->cmd_pool, cmd);
 	}
 	shost->cmd_pool = NULL;
-	scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL);
+	scsi_put_host_cmd_pool(shost);
 }
 
 #ifdef CONFIG_SCSI_LOGGING

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [4/21] SCSI-ISA-DMA: Add sense_buffer_isa to host template
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (2 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [3/21] SCSI-ISA-DMA: Pass gfp to scsi_allocate_command Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [5/21] SCSI-ISA-DMA: Remove unchecked_isa in BusLogic Andi Kleen
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Instead of having the global "unchecked_isa_dma" bit add a single
bit that tells the mid layer that the sense buffer needs to be ISA
DMA'able.

Right now when the bit is set we still force all commands to the ISA
DMA zone too, but that can change in the future.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 Documentation/scsi/scsi_mid_low_api.txt |    1 +
 drivers/scsi/hosts.c                    |    1 +
 drivers/scsi/scsi.c                     |   10 ++++++----
 include/scsi/scsi_host.h                |    8 ++++++++
 4 files changed, 16 insertions(+), 4 deletions(-)

Index: linux/include/scsi/scsi_host.h
===================================================================
--- linux.orig/include/scsi/scsi_host.h
+++ linux/include/scsi/scsi_host.h
@@ -454,6 +454,11 @@ struct scsi_host_template {
 	unsigned ordered_tag:1;
 
 	/*
+	 * True if sense buffers need to be ISA-DMAable
+	 */
+	unsigned sense_buffer_isa:1;
+
+	/*
 	 * Countdown for host blocking with no commands outstanding.
 	 */
 	unsigned int max_host_blocked;
@@ -614,6 +619,9 @@ struct Scsi_Host {
 	 */
 	unsigned ordered_tag:1;
 
+	/* Sense buffer needs to be ISA dma'able */
+	unsigned sense_buffer_isa:1;
+
 	/* Task mgmt function in progress */
 	unsigned tmf_in_progress:1;
 
Index: linux/Documentation/scsi/scsi_mid_low_api.txt
===================================================================
--- linux.orig/Documentation/scsi/scsi_mid_low_api.txt
+++ linux/Documentation/scsi/scsi_mid_low_api.txt
@@ -1268,6 +1268,7 @@ of interest:
                    instances (currently ordered by ascending host_no)
     my_devices   - a double linked list of pointers to struct scsi_device 
                    instances that belong to this host.
+    sense_buffer_isa - bit flag; true when the sense buffer needs to be ISA DMAable
     hostdata[0]  - area reserved for LLD at end of struct Scsi_Host. Size
                    is set by the second argument (named 'xtr_bytes') to
                    scsi_host_alloc() or scsi_register().
Index: linux/drivers/scsi/hosts.c
===================================================================
--- linux.orig/drivers/scsi/hosts.c
+++ linux/drivers/scsi/hosts.c
@@ -364,6 +364,7 @@ struct Scsi_Host *scsi_host_alloc(struct
 		shost->active_mode = MODE_INITIATOR;
 	else
 		shost->active_mode = sht->supported_mode;
+	shost->sense_buffer_isa = sht->sense_buffer_isa;
 
 	if (sht->max_host_blocked)
 		shost->max_host_blocked = sht->max_host_blocked;
Index: linux/drivers/scsi/scsi.c
===================================================================
--- linux.orig/drivers/scsi/scsi.c
+++ linux/drivers/scsi/scsi.c
@@ -363,7 +363,7 @@ scsi_get_host_cmd_pool(struct Scsi_Host 
 	 */
 	mutex_lock(&host_cmd_pool_mutex);
 	pool = &scsi_cmd_pool;
-	if (shost && shost->unchecked_isa_dma)
+	if (shost && (shost->unchecked_isa_dma || shost->sense_buffer_isa))
 		pool = &scsi_cmd_dma_pool;
 	if (!pool->users) {
 		pool->cmd_slab = kmem_cache_create(pool->cmd_name,
@@ -393,8 +393,8 @@ static void scsi_put_host_cmd_pool(struc
 	struct scsi_host_cmd_pool *pool;
 
 	mutex_lock(&host_cmd_pool_mutex);
-	pool = (shost && shost->unchecked_isa_dma) ? &scsi_cmd_dma_pool :
-		&scsi_cmd_pool;
+	pool = (shost && (shost->unchecked_isa_dma || shost->sense_buffer_isa)) ?
+		&scsi_cmd_dma_pool : &scsi_cmd_pool;
 	/*
 	 * This may happen if a driver has a mismatched get and put
 	 * of the command pool; the driver should be implicated in
@@ -489,7 +489,9 @@ EXPORT_SYMBOL(scsi_free_command);
 int scsi_setup_command_freelist(struct Scsi_Host *shost)
 {
 	struct scsi_cmnd *cmd;
-	const gfp_t gfp_mask = shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL;
+	gfp_t gfp_mask = GFP_KERNEL;
+	if (shost->unchecked_isa_dma || shost->sense_buffer_isa)
+		gfp_mask = GFP_DMA;
 
 	spin_lock_init(&shost->free_list_lock);
 	INIT_LIST_HEAD(&shost->free_list);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [5/21] SCSI-ISA-DMA: Remove unchecked_isa in BusLogic
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (3 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [4/21] SCSI-ISA-DMA: Add sense_buffer_isa to host template Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [6/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in advansys.c Andi Kleen
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


- ->cmnd handling audited and does always copy
- Allocate hostdata separately
- Enable sense_buffer isa bounce buffering
- Remove unchecked_isa_dma
- Enable block layer bouncing explicitely for isa adapters

Untested due to lack of hardware

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/BusLogic.c |   77 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 59 insertions(+), 18 deletions(-)

Index: linux/drivers/scsi/BusLogic.c
===================================================================
--- linux.orig/drivers/scsi/BusLogic.c
+++ linux/drivers/scsi/BusLogic.c
@@ -62,6 +62,13 @@
 
 static struct scsi_host_template Bus_Logic_template;
 
+struct host_ptr {
+	struct BusLogic_HostAdapter *host;
+	dma_addr_t dma;
+};
+#define bl_shost_priv(shost) (((struct host_ptr *)shost_priv(shost))->host)
+#define bl_shost_dma(shost) (((struct host_ptr *)shost_priv(shost))->dma)
+
 /*
   BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
   Options specifications provided via the Linux Kernel Command Line or via
@@ -124,6 +131,12 @@ static int BusLogic_ProbeInfoCount;
 
 static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList;
 
+static int buslogic_adjust_queue(struct scsi_device *device)
+{
+	if (device->host->sense_buffer_isa)
+		blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
 
 /*
   BusLogic_CommandFailureReason holds a string identifying the reason why a
@@ -152,7 +165,7 @@ static void BusLogic_AnnounceDriver(stru
 
 static const char *BusLogic_DriverInfo(struct Scsi_Host *Host)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(Host);
 	return HostAdapter->FullModelName;
 }
 
@@ -1610,9 +1623,6 @@ static bool __init BusLogic_ReadHostAdap
 	   BIOS_Address is 0.
 	 */
 	HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
-	/*
-	   ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
-	 */
 	if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
 		HostAdapter->BounceBuffersRequired = true;
 	/*
@@ -2131,7 +2141,9 @@ static void __init BusLogic_InitializeHo
 	Host->this_id = HostAdapter->SCSI_ID;
 	Host->can_queue = HostAdapter->DriverQueueDepth;
 	Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
-	Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
+	if (HostAdapter->BounceBuffersRequired)
+		Host->sense_buffer_isa = 1;
+
 	Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
 }
 
@@ -2145,7 +2157,7 @@ static void __init BusLogic_InitializeHo
 */
 static int BusLogic_SlaveConfigure(struct scsi_device *Device)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(Device->host);
 	int TargetID = Device->id;
 	int QueueDepth = HostAdapter->QueueDepth[TargetID];
 
@@ -2170,6 +2182,35 @@ static int BusLogic_SlaveConfigure(struc
 	return 0;
 }
 
+static struct Scsi_Host *buslogic_host_alloc(gfp_t gfp)
+{
+	struct BusLogic_HostAdapter *board;
+	struct Scsi_Host *shost;
+
+
+	shost = scsi_host_alloc(&Bus_Logic_template, sizeof(struct host_ptr));
+	if (!shost)
+		return NULL;
+
+	board = dma_alloc_coherent(NULL, sizeof(struct BusLogic_HostAdapter),
+					&bl_shost_dma(shost), GFP_KERNEL);
+	if (!board) {
+		scsi_host_put(shost);
+		return NULL;
+	}
+
+	bl_shost_priv(shost) = board;
+
+	return shost;
+}
+
+static void buslogic_free_host(struct Scsi_Host *shost)
+{
+	dma_free_coherent(NULL, sizeof(struct BusLogic_HostAdapter),
+			  bl_shost_priv(shost), bl_shost_dma(shost));
+	scsi_host_put(shost);
+}
+
 /*
   BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
   I/O Addresses where they may be located, initializing, registering, and
@@ -2270,12 +2311,12 @@ static int __init BusLogic_init(void)
 		   Register the SCSI Host structure.
 		 */
 
-		Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter));
+		Host = buslogic_host_alloc(PrototypeHostAdapter->BounceBuffersRequired ? GFP_DMA : 0);
 		if (Host == NULL) {
 			release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
 			continue;
 		}
-		HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
+		HostAdapter = bl_shost_priv(Host);
 		memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
 		HostAdapter->SCSI_Host = Host;
 		HostAdapter->HostNumber = Host->host_no;
@@ -2321,7 +2362,7 @@ static int __init BusLogic_init(void)
 				BusLogic_DestroyCCBs(HostAdapter);
 				BusLogic_ReleaseResources(HostAdapter);
 				list_del(&HostAdapter->host_list);
-				scsi_host_put(Host);
+				buslogic_free_host(Host);
 				ret = -ENOMEM;
 			} else {
 				BusLogic_InitializeHostStructure(HostAdapter,
@@ -2335,7 +2376,7 @@ static int __init BusLogic_init(void)
 					BusLogic_DestroyCCBs(HostAdapter);
 					BusLogic_ReleaseResources(HostAdapter);
 					list_del(&HostAdapter->host_list);
-					scsi_host_put(Host);
+					buslogic_free_host(Host);
 					ret = -ENODEV;
 				} else {
 					scsi_scan_host(Host);
@@ -2354,7 +2395,7 @@ static int __init BusLogic_init(void)
 			BusLogic_DestroyCCBs(HostAdapter);
 			BusLogic_ReleaseResources(HostAdapter);
 			list_del(&HostAdapter->host_list);
-			scsi_host_put(Host);
+			buslogic_free_host(Host);
 			ret = -ENODEV;
 		}
 	}
@@ -2398,7 +2439,7 @@ static int __exit BusLogic_ReleaseHostAd
 	 */
 	list_del(&HostAdapter->host_list);
 
-	scsi_host_put(Host);
+	buslogic_free_host(Host);
 	return 0;
 }
 
@@ -2786,7 +2827,7 @@ static bool BusLogic_WriteOutgoingMailbo
 
 static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(SCpnt->device->host);
 
 	unsigned int id = SCpnt->device->id;
 	struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
@@ -2808,7 +2849,7 @@ static int BusLogic_host_reset(struct sc
 
 static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(Command->device->host);
 	struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
 	struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
 	unsigned char *CDB = Command->cmnd;
@@ -3001,7 +3042,7 @@ static int BusLogic_QueueCommand(struct 
 
 static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(Command->device->host);
 
 	int TargetID = Command->device->id;
 	struct BusLogic_CCB *CCB;
@@ -3131,7 +3172,7 @@ static int BusLogic_ResetHostAdapter(str
 
 static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(sdev->host);
 	struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
 	unsigned char *buf;
 	if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) {
@@ -3202,7 +3243,7 @@ static int BusLogic_BIOSDiskParameters(s
 
 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
+	struct BusLogic_HostAdapter *HostAdapter = bl_shost_priv(shost);
 	struct BusLogic_TargetStatistics *TargetStatistics;
 	int TargetID, Length;
 	char *Buffer;
@@ -3575,9 +3616,9 @@ static struct scsi_host_template Bus_Log
 #if 0
 	.eh_abort_handler = BusLogic_AbortCommand,
 #endif
-	.unchecked_isa_dma = 1,
 	.max_sectors = 128,
 	.use_clustering = ENABLE_CLUSTERING,
+	.slave_alloc = buslogic_adjust_queue,
 };
 
 /*

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [6/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in advansys.c
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (4 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [5/21] SCSI-ISA-DMA: Remove unchecked_isa in BusLogic Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [7/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in gdth Andi Kleen
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


That patch is a little more complicated than the others. advansys
was the only ISA driver who actually passed ->cmnd to the firmware.
So I implemented a simple own bounce buffer scheme for this case.
Also did sense_buffer bouncing in the driver while I was at it;
which means it doesn't require the mid layer to do this anymore.

- allocate hostdata with GFP_DMA separately for the ISA case
- Tell block layer explicitely to bounce for ISA case
- remove unchecked_isa_dma

Untested due to lack of hardware

v2: use dma api for all allocations
v3: remove cmnd buffer bouncing (thanks m.willcox), move sense bouncing
    to mid layer

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/advansys.c |  162 ++++++++++++++++++++++++++++++------------------
 1 file changed, 103 insertions(+), 59 deletions(-)

Index: linux/drivers/scsi/advansys.c
===================================================================
--- linux.orig/drivers/scsi/advansys.c
+++ linux/drivers/scsi/advansys.c
@@ -2212,7 +2212,7 @@ do { \
 #define ASC_STATS_ADD(shost, counter, count)
 #else /* ADVANSYS_STATS */
 #define ASC_STATS_ADD(shost, counter, count) \
-	(((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
+	(asc_shost_priv(shost)->asc_stats.counter += (count))
 #endif /* ADVANSYS_STATS */
 
 /* If the result wraps when calculating tenths, return 0. */
@@ -2354,10 +2354,6 @@ struct asc_stats {
 
 /*
  * Structure allocated for each board.
- *
- * This structure is allocated by scsi_host_alloc() at the end
- * of the 'Scsi_Host' structure starting at the 'hostdata'
- * field. It is guaranteed to be allocated from DMA-able memory.
  */
 struct asc_board {
 	struct device *dev;
@@ -2388,6 +2384,7 @@ struct asc_board {
 #ifdef ADVANSYS_STATS
 	struct asc_stats asc_stats;	/* Board statistics */
 #endif				/* ADVANSYS_STATS */
+
 	/*
 	 * The following fields are used only for Narrow Boards.
 	 */
@@ -2403,8 +2400,19 @@ struct asc_board {
 	ushort bios_version;	/* BIOS Version. */
 	ushort bios_codeseg;	/* BIOS Code Segment. */
 	ushort bios_codelen;	/* BIOS Code Segment Length. */
+
+};
+
+struct asc_board_ptr {
+	struct asc_board *b;
+	dma_addr_t dma;
 };
 
+
+
+#define asc_shost_priv(h) (((struct asc_board_ptr *)shost_priv(h))->b)
+#define asc_shost_dma(h) (((struct asc_board_ptr *)shost_priv(h))->dma)
+
 #define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \
 							dvc_var.asc_dvc_var)
 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
@@ -2525,7 +2533,7 @@ static void asc_prt_adv_dvc_cfg(ADV_DVC_
  */
 static void asc_prt_scsi_host(struct Scsi_Host *s)
 {
-	struct asc_board *boardp = shost_priv(s);
+	struct asc_board *boardp = asc_shost_priv(s);
 
 	printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id);
 	printk(" host_busy %u, host_no %d, last_reset %d,\n",
@@ -2537,8 +2545,8 @@ static void asc_prt_scsi_host(struct Scs
 	printk(" dma_channel %d, this_id %d, can_queue %d,\n",
 	       s->dma_channel, s->this_id, s->can_queue);
 
-	printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
-	       s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
+	printk(" cmd_per_lun %d, sg_tablesize %d\n",
+	       s->cmd_per_lun, s->sg_tablesize);
 
 	if (ASC_NARROW_BOARD(boardp)) {
 		asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var);
@@ -2803,7 +2811,7 @@ static void * advansys_srb_to_ptr(struct
 static const char *advansys_info(struct Scsi_Host *shost)
 {
 	static char info[ASC_INFO_SIZE];
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	ASC_DVC_VAR *asc_dvc_varp;
 	ADV_DVC_VAR *adv_dvc_varp;
 	char *busname;
@@ -2919,7 +2927,7 @@ static int asc_prt_line(char *buf, int b
  */
 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	int leftlen;
 	int totlen;
 	int len;
@@ -2959,7 +2967,7 @@ static int asc_prt_board_devices(struct 
  */
 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	int leftlen;
 	int totlen;
 	int len;
@@ -3124,7 +3132,7 @@ static int asc_get_eeprom_string(ushort 
  */
 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	ASC_DVC_VAR *asc_dvc_varp;
 	int leftlen;
 	int totlen;
@@ -3257,7 +3265,7 @@ static int asc_prt_asc_board_eeprom(stru
  */
 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	ADV_DVC_VAR *adv_dvc_varp;
 	int leftlen;
 	int totlen;
@@ -3543,7 +3551,7 @@ static int asc_prt_adv_board_eeprom(stru
  */
 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	int leftlen;
 	int totlen;
 	int len;
@@ -3569,9 +3577,7 @@ static int asc_prt_driver_conf(struct Sc
 			   shost->sg_tablesize, shost->cmd_per_lun);
 	ASC_PRT_NEXT();
 
-	len = asc_prt_line(cp, leftlen,
-			   " unchecked_isa_dma %d, use_clustering %d\n",
-			   shost->unchecked_isa_dma, shost->use_clustering);
+	len = asc_prt_line(cp, leftlen, " use_clustering %d\n", shost->use_clustering);
 	ASC_PRT_NEXT();
 
 	len = asc_prt_line(cp, leftlen,
@@ -3605,7 +3611,7 @@ static int asc_prt_driver_conf(struct Sc
  */
 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	int chip_scsi_id;
 	int leftlen;
 	int totlen;
@@ -3787,7 +3793,7 @@ static int asc_prt_asc_board_info(struct
  */
 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	int leftlen;
 	int totlen;
 	int len;
@@ -4065,7 +4071,7 @@ asc_proc_copy(off_t advoffset, off_t off
  */
 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	struct asc_stats *s = &boardp->asc_stats;
 
 	int leftlen = cplen;
@@ -4151,7 +4157,7 @@ static int
 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
 		   off_t offset, int length, int inout)
 {
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	char *cp;
 	int cplen;
 	int cnt;
@@ -8200,7 +8206,7 @@ static void adv_isr_callback(ADV_DVC_VAR
 	ASC_STATS(shost, callback);
 	ASC_DBG(1, "shost 0x%p\n", shost);
 
-	boardp = shost_priv(shost);
+	boardp = asc_shost_priv(shost);
 	BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
 
 	/*
@@ -9132,7 +9138,7 @@ static void asc_isr_callback(ASC_DVC_VAR
 	ASC_STATS(shost, callback);
 	ASC_DBG(1, "shost 0x%p\n", shost);
 
-	boardp = shost_priv(shost);
+	boardp = asc_shost_priv(shost);
 	BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
 
 	dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
@@ -9484,7 +9490,7 @@ static int AscISR(ASC_DVC_VAR *asc_dvc)
 static int advansys_reset(struct scsi_cmnd *scp)
 {
 	struct Scsi_Host *shost = scp->device->host;
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	unsigned long flags;
 	int status;
 	int ret = SUCCESS;
@@ -9567,7 +9573,7 @@ static int
 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 		   sector_t capacity, int ip[])
 {
-	struct asc_board *boardp = shost_priv(sdev->host);
+	struct asc_board *boardp = asc_shost_priv(sdev->host);
 
 	ASC_DBG(1, "begin\n");
 	ASC_STATS(sdev->host, biosparam);
@@ -9603,7 +9609,7 @@ advansys_biosparam(struct scsi_device *s
 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
 {
 	struct Scsi_Host *shost = dev_id;
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	irqreturn_t result = IRQ_NONE;
 
 	ASC_DBG(2, "boardp 0x%p\n", boardp);
@@ -9691,6 +9697,9 @@ advansys_narrow_slave_configure(struct s
 	ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
 	ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
 
+	if (sdev->host->sense_buffer_isa)
+		blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ISA);
+
 	if (sdev->lun == 0) {
 		ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
 		if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
@@ -9865,7 +9874,7 @@ advansys_wide_slave_configure(struct scs
  */
 static int advansys_slave_configure(struct scsi_device *sdev)
 {
-	struct asc_board *boardp = shost_priv(sdev->host);
+	struct asc_board *boardp = asc_shost_priv(sdev->host);
 
 	if (ASC_NARROW_BOARD(boardp))
 		advansys_narrow_slave_configure(sdev,
@@ -10925,7 +10934,7 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *
 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
 {
 	int ret, err_code;
-	struct asc_board *boardp = shost_priv(scp->device->host);
+	struct asc_board *boardp = asc_shost_priv(scp->device->host);
 
 	ASC_DBG(1, "scp 0x%p\n", scp);
 
@@ -11725,7 +11734,7 @@ static ushort __devinit AscInitFromEEP(A
 
 static int __devinit AscInitGetConfig(struct Scsi_Host *shost)
 {
-	struct asc_board *board = shost_priv(shost);
+	struct asc_board *board = asc_shost_priv(shost);
 	ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
 	unsigned short warn_code = 0;
 
@@ -11779,7 +11788,7 @@ static int __devinit AscInitGetConfig(st
 
 static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
 {
-	struct asc_board *board = shost_priv(shost);
+	struct asc_board *board = asc_shost_priv(shost);
 	ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
 	PortAddr iop_base = asc_dvc->iop_base;
 	unsigned short cfg_msw;
@@ -13172,7 +13181,7 @@ static int __devinit AdvInitFrom38C1600E
 static int __devinit
 AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
 {
-	struct asc_board *board = shost_priv(shost);
+	struct asc_board *board = asc_shost_priv(shost);
 	ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
 	unsigned short warn_code = 0;
 	AdvPortAddr iop_base = asc_dvc->iop_base;
@@ -13250,6 +13259,13 @@ AdvInitGetConfig(struct pci_dev *pdev, s
 }
 #endif
 
+static int advansys_adjust_queue(struct scsi_device *device)
+{
+	if (device->host->sense_buffer_isa)
+		blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 static struct scsi_host_template advansys_template = {
 	.proc_name = DRV_NAME,
 #ifdef CONFIG_PROC_FS
@@ -13261,12 +13277,7 @@ static struct scsi_host_template advansy
 	.eh_bus_reset_handler = advansys_reset,
 	.bios_param = advansys_biosparam,
 	.slave_configure = advansys_slave_configure,
-	/*
-	 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
-	 * must be set. The flag will be cleared in advansys_board_found
-	 * for non-ISA adapters.
-	 */
-	.unchecked_isa_dma = 1,
+	.slave_alloc = advansys_adjust_queue,
 	/*
 	 * All adapters controlled by this driver are capable of large
 	 * scatter-gather lists. According to the mid-level SCSI documentation
@@ -13279,7 +13290,7 @@ static struct scsi_host_template advansy
 
 static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
 {
-	struct asc_board *board = shost_priv(shost);
+	struct asc_board *board = asc_shost_priv(shost);
 	struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
 	int req_cnt = 0;
 	adv_req_t *reqp = NULL;
@@ -13394,7 +13405,7 @@ static int __devinit advansys_board_foun
 					  unsigned int iop, int bus_type)
 {
 	struct pci_dev *pdev;
-	struct asc_board *boardp = shost_priv(shost);
+	struct asc_board *boardp = asc_shost_priv(shost);
 	ASC_DVC_VAR *asc_dvc_varp = NULL;
 	ADV_DVC_VAR *adv_dvc_varp = NULL;
 	int share_irq, warn_code, ret;
@@ -13464,6 +13475,8 @@ static int __devinit advansys_board_foun
 	}
 #endif /* CONFIG_PROC_FS */
 
+	ret = 0;
+
 	if (ASC_NARROW_BOARD(boardp)) {
 		/*
 		 * Set the board bus type and PCI IRQ before
@@ -13472,28 +13485,23 @@ static int __devinit advansys_board_foun
 		switch (asc_dvc_varp->bus_type) {
 #ifdef CONFIG_ISA
 		case ASC_IS_ISA:
-			shost->unchecked_isa_dma = TRUE;
 			share_irq = 0;
 			break;
 		case ASC_IS_VL:
-			shost->unchecked_isa_dma = FALSE;
 			share_irq = 0;
 			break;
 		case ASC_IS_EISA:
-			shost->unchecked_isa_dma = FALSE;
 			share_irq = IRQF_SHARED;
 			break;
 #endif /* CONFIG_ISA */
 #ifdef CONFIG_PCI
 		case ASC_IS_PCI:
-			shost->unchecked_isa_dma = FALSE;
 			share_irq = IRQF_SHARED;
 			break;
 #endif /* CONFIG_PCI */
 		default:
 			shost_printk(KERN_ERR, shost, "unknown adapter type: "
 					"%d\n", asc_dvc_varp->bus_type);
-			shost->unchecked_isa_dma = TRUE;
 			share_irq = 0;
 			break;
 		}
@@ -13505,14 +13513,14 @@ static int __devinit advansys_board_foun
 		 * referenced only use the bit-wise AND operator "&".
 		 */
 		ASC_DBG(2, "AscInitGetConfig()\n");
-		ret = AscInitGetConfig(shost) ? -ENODEV : 0;
+		if (!ret)
+			ret = AscInitGetConfig(shost) ? -ENODEV : 0;
 	} else {
 #ifdef CONFIG_PCI
 		/*
 		 * For Wide boards set PCI information before calling
 		 * AdvInitGetConfig().
 		 */
-		shost->unchecked_isa_dma = FALSE;
 		share_irq = IRQF_SHARED;
 		ASC_DBG(2, "AdvInitGetConfig()\n");
 
@@ -13883,6 +13891,16 @@ static int __devinit advansys_board_foun
 	return ret;
 }
 
+static void adv_free_host(struct Scsi_Host *shost)
+{
+	struct asc_board *board = asc_shost_priv(shost);
+	struct device *device = board->dev;
+	dma_free_coherent(device, sizeof(struct asc_board),
+				  asc_shost_priv(shost),
+				  asc_shost_dma(shost));
+	scsi_host_put(shost);
+}
+
 /*
  * advansys_release()
  *
@@ -13890,7 +13908,7 @@ static int __devinit advansys_board_foun
  */
 static int advansys_release(struct Scsi_Host *shost)
 {
-	struct asc_board *board = shost_priv(shost);
+	struct asc_board *board = asc_shost_priv(shost);
 	ASC_DBG(1, "begin\n");
 	scsi_remove_host(shost);
 	free_irq(board->irq, shost);
@@ -13908,11 +13926,32 @@ static int advansys_release(struct Scsi_
 		advansys_wide_free_mem(board);
 	}
 	kfree(board->prtbuf);
-	scsi_host_put(shost);
+	adv_free_host(shost);
 	ASC_DBG(1, "end\n");
 	return 0;
 }
 
+static struct Scsi_Host *adv_host_alloc(struct device *dev)
+{
+	struct asc_board *board;
+	struct Scsi_Host *shost;
+	shost = scsi_host_alloc(&advansys_template,
+				sizeof(struct asc_board_ptr));
+	if (!shost)
+		return NULL;
+
+	board = dma_alloc_coherent(dev,
+				   sizeof(struct asc_board),
+				   &asc_shost_dma(shost),
+				   GFP_KERNEL);
+	if (!board) {
+		scsi_host_put(shost);
+		return NULL;
+	}
+	asc_shost_priv(shost) = board;
+	return shost;
+}
+
 #define ASC_IOADR_TABLE_MAX_IX  11
 
 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
@@ -13954,11 +13993,13 @@ static int __devinit advansys_isa_probe(
 		goto release_region;
 
 	err = -ENOMEM;
-	shost = scsi_host_alloc(&advansys_template, sizeof(*board));
+	shost = adv_host_alloc(NULL);
 	if (!shost)
 		goto release_region;
+	shost->sense_buffer_isa = 1;
+
+	board = asc_shost_priv(shost);
 
-	board = shost_priv(shost);
 	board->irq = advansys_isa_irq_no(iop_base);
 	board->dev = dev;
 
@@ -13970,7 +14011,7 @@ static int __devinit advansys_isa_probe(
 	return 0;
 
  free_host:
-	scsi_host_put(shost);
+	adv_free_host(shost);
  release_region:
 	release_region(iop_base, ASC_IOADR_GAP);
 	return err;
@@ -14036,11 +14077,12 @@ static int __devinit advansys_vlb_probe(
 		goto release_region;
 
 	err = -ENOMEM;
-	shost = scsi_host_alloc(&advansys_template, sizeof(*board));
+	shost = adv_host_alloc(NULL);
 	if (!shost)
 		goto release_region;
+	shost->sense_buffer_isa = 1;
 
-	board = shost_priv(shost);
+	board = asc_shost_priv(shost);
 	board->irq = advansys_vlb_irq_no(iop_base);
 	board->dev = dev;
 
@@ -14052,7 +14094,7 @@ static int __devinit advansys_vlb_probe(
 	return 0;
 
  free_host:
-	scsi_host_put(shost);
+	adv_free_host(shost);
  release_region:
 	release_region(iop_base, ASC_IOADR_GAP);
 	return -ENODEV;
@@ -14143,11 +14185,13 @@ static int __devinit advansys_eisa_probe
 			irq = advansys_eisa_irq_no(edev);
 
 		err = -ENOMEM;
-		shost = scsi_host_alloc(&advansys_template, sizeof(*board));
+		/* RED-PEN does use GFP_DMA unnecessarily since EISA is 32bit */
+		shost = adv_host_alloc(NULL);
+
 		if (!shost)
 			goto release_region;
 
-		board = shost_priv(shost);
+		board = asc_shost_priv(shost);
 		board->irq = irq;
 		board->dev = dev;
 
@@ -14259,11 +14303,11 @@ advansys_pci_probe(struct pci_dev *pdev,
 	ioport = pci_resource_start(pdev, 0);
 
 	err = -ENOMEM;
-	shost = scsi_host_alloc(&advansys_template, sizeof(*board));
+	shost = adv_host_alloc(&pdev->dev);
 	if (!shost)
 		goto release_region;
 
-	board = shost_priv(shost);
+	board = asc_shost_priv(shost);
 	board->irq = pdev->irq;
 	board->dev = &pdev->dev;
 
@@ -14281,7 +14325,7 @@ advansys_pci_probe(struct pci_dev *pdev,
 	return 0;
 
  free_host:
-	scsi_host_put(shost);
+	adv_free_host(shost);
  release_region:
 	pci_release_regions(pdev);
  disable_device:

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [7/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in gdth
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (5 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [6/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in advansys.c Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [8/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in eata.c Andi Kleen
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


- Audited ->cmnd use and it always copies
- Allocate hostdata separately with GFP_DMA for the ISA case
- Tell scsi layer to bounce sense_buffer for ISA case
- Tell block layer to bounce for isa case
- Remove unchecked_isa_dma

Untested due to lack of hardware

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/gdth.c |   81 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 62 insertions(+), 19 deletions(-)

Index: linux/drivers/scsi/gdth.c
===================================================================
--- linux.orig/drivers/scsi/gdth.c
+++ linux/drivers/scsi/gdth.c
@@ -139,6 +139,15 @@
 #include <scsi/scsi_host.h>
 #include "gdth.h"
 
+
+struct host_ptr {
+	gdth_ha_str *host_ptr;
+	dma_addr_t dma;
+};
+
+#define gdth_shost_priv(host) (((struct host_ptr *)shost_priv(host))->host_ptr)
+#define gdth_shost_dma(host) (((struct host_ptr *)shost_priv(host))->dma)
+
 static void gdth_delay(int milliseconds);
 static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs);
 static irqreturn_t gdth_interrupt(int irq, void *dev_id);
@@ -443,7 +452,7 @@ static void gdth_scsi_done(struct scsi_c
 int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
                    int timeout, u32 *info)
 {
-    gdth_ha_str *ha = shost_priv(sdev->host);
+    gdth_ha_str *ha = gdth_shost_priv(sdev->host);
     Scsi_Cmnd *scp;
     struct gdth_cmndinfo cmndinfo;
     DECLARE_COMPLETION_ONSTACK(wait);
@@ -3893,7 +3902,7 @@ static const char *gdth_ctr_name(gdth_ha
 
 static const char *gdth_info(struct Scsi_Host *shp)
 {
-    gdth_ha_str *ha = shost_priv(shp);
+    gdth_ha_str *ha = gdth_shost_priv(shp);
 
     TRACE2(("gdth_info()\n"));
     return ((const char *)ha->binfo.type_string);
@@ -3901,7 +3910,7 @@ static const char *gdth_info(struct Scsi
 
 static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
 {
-    gdth_ha_str *ha = shost_priv(scp->device->host);
+    gdth_ha_str *ha = gdth_shost_priv(scp->device->host);
     int i;
     ulong flags;
     Scsi_Cmnd *cmnd;
@@ -3954,7 +3963,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *
 static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip)
 {
     unchar b, t;
-    gdth_ha_str *ha = shost_priv(sdev->host);
+    gdth_ha_str *ha = gdth_shost_priv(sdev->host);
     struct scsi_device *sd;
     unsigned capacity;
 
@@ -3983,7 +3992,7 @@ static int gdth_bios_param(struct scsi_d
 static int gdth_queuecommand(struct scsi_cmnd *scp,
 				void (*done)(struct scsi_cmnd *))
 {
-    gdth_ha_str *ha = shost_priv(scp->device->host);
+    gdth_ha_str *ha = gdth_shost_priv(scp->device->host);
     struct gdth_cmndinfo *cmndinfo;
 
     TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0]));
@@ -4636,6 +4645,13 @@ static int gdth_slave_configure(struct s
     return 0;
 }
 
+static int gdth_adjust_queue(struct scsi_device *device)
+{
+	if (device->host->sense_buffer_isa)
+		blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 static struct scsi_host_template gdth_template = {
         .name                   = "GDT SCSI Disk Array Controller",
         .info                   = gdth_info, 
@@ -4649,10 +4665,38 @@ static struct scsi_host_template gdth_te
         .this_id                = -1,
         .sg_tablesize           = GDTH_MAXSG,
         .cmd_per_lun            = GDTH_MAXC_P_L,
-        .unchecked_isa_dma      = 1,
         .use_clustering         = ENABLE_CLUSTERING,
+	.slave_alloc		= gdth_adjust_queue,
 };
 
+static struct Scsi_Host *gdth_host_alloc(struct device *dev)
+{
+	struct Scsi_Host *shost;
+	gdth_ha_str *board;
+	shost = scsi_host_alloc(&gdth_template, sizeof(struct host_ptr));
+	if (!shost)
+		return NULL;
+
+	board = dma_alloc_coherent(dev, sizeof(gdth_ha_str),
+				&gdth_shost_dma(shost), GFP_KERNEL);
+	if (!board) {
+		scsi_host_put(shost);
+		return NULL;
+	}
+
+	gdth_shost_priv(shost) = board;
+
+	return shost;
+}
+
+static void gdth_free_host(struct Scsi_Host *shost)
+{
+	gdth_ha_str *h = gdth_shost_priv(shost);
+	dma_free_coherent(h->pdev ? &h->pdev->dev : NULL, sizeof(gdth_ha_str),
+			  h, gdth_shost_dma(shost));
+	scsi_host_put(shost);
+}
+
 #ifdef CONFIG_ISA
 static int __init gdth_isa_probe_one(ulong32 isa_bios)
 {
@@ -4664,10 +4708,10 @@ static int __init gdth_isa_probe_one(ulo
 	if (!gdth_search_isa(isa_bios))
 		return -ENXIO;
 
-	shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
+	shp = gdth_host_alloc(NULL);
 	if (!shp)
 		return -ENOMEM;
-	ha = shost_priv(shp);
+	ha = gdth_shost_priv(shp);
 
 	error = -ENODEV;
 	if (!gdth_init_isa(isa_bios,ha))
@@ -4691,7 +4735,7 @@ static int __init gdth_isa_probe_one(ulo
 
 	set_dma_mode(ha->drq,DMA_MODE_CASCADE);
 	enable_dma(ha->drq);
-	shp->unchecked_isa_dma = 1;
+	shp->sense_buffer_isa = 1;
 	shp->irq = ha->irq;
 	shp->dma_channel = ha->drq;
 
@@ -4780,7 +4824,7 @@ static int __init gdth_isa_probe_one(ulo
  out_free_irq:
 	free_irq(ha->irq, ha);
  out_host_put:
-	scsi_host_put(shp);
+	gdth_free_host(shp);
 	return error;
 }
 #endif /* CONFIG_ISA */
@@ -4796,10 +4840,11 @@ static int __init gdth_eisa_probe_one(us
 	if (!gdth_search_eisa(eisa_slot))
 		return -ENXIO;
 
-	shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
+	/* RED-PEN NULL device ISA mask is 24bit, but EISA 32bit */
+	shp = gdth_host_alloc(NULL);
 	if (!shp)
 		return -ENOMEM;
-	ha = shost_priv(shp);
+	ha = gdth_shost_priv(shp);
 
 	error = -ENODEV;
 	if (!gdth_init_eisa(eisa_slot,ha))
@@ -4815,7 +4860,6 @@ static int __init gdth_eisa_probe_one(us
 		goto out_host_put;
 	}
 
-	shp->unchecked_isa_dma = 0;
 	shp->irq = ha->irq;
 	shp->dma_channel = 0xff;
 
@@ -4913,7 +4957,7 @@ static int __init gdth_eisa_probe_one(us
 	free_irq(ha->irq, ha);
 	gdth_ctr_count--;
  out_host_put:
-	scsi_host_put(shp);
+	gdth_free_host(shp);
 	return error;
 }
 #endif /* CONFIG_EISA */
@@ -4930,10 +4974,10 @@ static int gdth_pci_probe_one(gdth_pci_s
 
 	*ha_out = NULL;
 
-	shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
+	shp = gdth_host_alloc(&pcistr->pdev->dev);
 	if (!shp)
 		return -ENOMEM;
-	ha = shost_priv(shp);
+	ha = gdth_shost_priv(shp);
 
 	error = -ENODEV;
 	if (!gdth_init_pci(pdev, pcistr, ha))
@@ -4952,7 +4996,6 @@ static int gdth_pci_probe_one(gdth_pci_s
 		goto out_host_put;
 	}
 
-	shp->unchecked_isa_dma = 0;
 	shp->irq = ha->irq;
 	shp->dma_channel = 0xff;
 
@@ -5059,7 +5102,7 @@ static int gdth_pci_probe_one(gdth_pci_s
 	free_irq(ha->irq, ha);
 	gdth_ctr_count--;
  out_host_put:
-	scsi_host_put(shp);
+	gdth_free_host(shp);
 	return error;
 }
 #endif /* CONFIG_PCI */
@@ -5101,7 +5144,7 @@ static void gdth_remove_one(gdth_ha_str 
 		pci_unmap_single(ha->pdev,ha->ccb_phys,
 			sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
 
-	scsi_host_put(shp);
+	gdth_free_host(shp);
 }
 
 static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [8/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in eata.c
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (6 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [7/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in gdth Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [9/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha1542 Andi Kleen
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


- Allocate hostdata with DMA separately in the driver
- Audited ->cmnd uses and it only ever copies them
- Enable sense_buffer bouncing using new sense_buffer_isa flag
- Enable block layer bouncing explicitely
- Remove unchecked_isa_dma

Untested due to lack of hardware

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/eata.c |   54 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 15 deletions(-)

Index: linux/drivers/scsi/eata.c
===================================================================
--- linux.orig/drivers/scsi/eata.c
+++ linux/drivers/scsi/eata.c
@@ -512,6 +512,13 @@ static int eata2x_bios_param(struct scsi
 			     sector_t, int *);
 static int eata2x_slave_configure(struct scsi_device *);
 
+static int eata_adjust_queue(struct scsi_device *device)
+{
+	if (device->host->sense_buffer_isa)
+		blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 static struct scsi_host_template driver_template = {
 	.name = "EATA/DMA 2.0x rev. 8.10.00 ",
 	.detect = eata2x_detect,
@@ -522,8 +529,8 @@ static struct scsi_host_template driver_
 	.bios_param = eata2x_bios_param,
 	.slave_configure = eata2x_slave_configure,
 	.this_id = 7,
-	.unchecked_isa_dma = 1,
 	.use_clustering = ENABLE_CLUSTERING,
+	.slave_alloc = eata_adjust_queue,
 };
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
@@ -834,6 +841,16 @@ struct hostdata {
 	struct mssp sp;		/* Local copy of sp buffer */
 };
 
+struct hostdata_ptr {
+	struct hostdata *host;
+	dma_addr_t dma;
+};
+
+#define eata_shost_priv(shost) \
+	(((struct hostdata_ptr *)shost_priv(shost))->host)
+#define eata_shost_dma(shost) \
+	(((struct hostdata_ptr *)shost_priv(shost))->dma)
+
 static struct Scsi_Host *sh[MAX_BOARDS];
 static const char *driver_name = "EATA";
 static char sha[MAX_BOARDS];
@@ -1266,14 +1283,23 @@ static int port_detect(unsigned long por
 #endif
 
 	spin_unlock_irq(&driver_lock);
-	sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata));
+	sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata_ptr));
+	ha = dma_alloc_coherent(pdev ? &pdev->dev : NULL,
+				sizeof(struct hostdata),
+				&eata_shost_dma(shost), GFP_KERNEL);
 	spin_lock_irq(&driver_lock);
 
-	if (shost == NULL) {
+	if (shost == NULL || ha == NULL) {
+		if (ha)
+			dma_free_coherent(pdev ? &pdev->dev : NULL,
+					  sizeof(struct hostdata),
+					  ha, eata_shost_dma(shost));
 		printk("%s: unable to register host, detaching.\n", name);
 		goto freedma;
 	}
 
+	eata_shost_priv(shost) = ha;
+
 	shost->io_port = port_base;
 	shost->unique_id = port_base;
 	shost->n_io_port = REGION_SIZE;
@@ -1283,8 +1309,6 @@ static int port_detect(unsigned long por
 	shost->this_id = (ushort) info.host_addr[3];
 	shost->can_queue = (ushort) info.queue_size;
 	shost->cmd_per_lun = MAX_CMD_PER_LUN;
-
-	ha = (struct hostdata *)shost->hostdata;
 	
 	memset(ha, 0, sizeof(struct hostdata));
 	ha->subversion = subversion;
@@ -1293,11 +1317,9 @@ static int port_detect(unsigned long por
 	ha->pdev = pdev;
 	ha->board_number = j;
 
-	if (ha->subversion == ESA)
-		shost->unchecked_isa_dma = 0;
-	else {
+	if (ha->subversion != ESA) {
 		unsigned long flags;
-		shost->unchecked_isa_dma = 1;
+		shost->sense_buffer_isa = 1;
 
 		flags = claim_dma_lock();
 		disable_dma(dma_channel);
@@ -1355,7 +1377,7 @@ static int port_detect(unsigned long por
 
 	for (i = 0; i < shost->can_queue; i++) {
 		size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
-		gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
+		gfp_t gfp_mask = (shost->sense_buffer_isa ? GFP_DMA : 0) | GFP_ATOMIC;
 		ha->cp[i].sglist = kmalloc(sz, gfp_mask);
 		if (!ha->cp[i].sglist) {
 			printk
@@ -1752,7 +1774,7 @@ static int eata2x_queuecommand(struct sc
 			       void (*done) (struct scsi_cmnd *))
 {
 	struct Scsi_Host *shost = SCpnt->device->host;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	struct hostdata *ha = eata_shost_priv(shost);
 	unsigned int i, k;
 	struct mscp *cpp;
 
@@ -1836,7 +1858,7 @@ static int eata2x_queuecommand(struct sc
 static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
 {
 	struct Scsi_Host *shost = SCarg->device->host;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	struct hostdata *ha = eata_shost_priv(shost);
 	unsigned int i;
 
 	if (SCarg->host_scribble == NULL) {
@@ -1906,7 +1928,7 @@ static int eata2x_eh_host_reset(struct s
 	int arg_done = 0;
 	struct scsi_cmnd *SCpnt;
 	struct Scsi_Host *shost = SCarg->device->host;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	struct hostdata *ha = eata_shost_priv(shost);
 
 	scmd_printk(KERN_INFO, SCarg,
 		"reset, enter, pid %ld.\n", SCarg->serial_number);
@@ -2292,7 +2314,7 @@ static irqreturn_t ihdlr(struct Scsi_Hos
 	unsigned int i, k, c, status, tstatus, reg;
 	struct mssp *spp;
 	struct mscp *cpp;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	struct hostdata *ha = eata_shost_priv(shost);
 	int irq = shost->irq;
 
 	/* Check if this board need to be serviced */
@@ -2552,7 +2574,7 @@ static irqreturn_t do_interrupt_handler(
 
 static int eata2x_release(struct Scsi_Host *shost)
 {
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	struct hostdata *ha = eata_shost_priv(shost);
 	unsigned int i;
 
 	for (i = 0; i < shost->can_queue; i++)
@@ -2572,6 +2594,8 @@ static int eata2x_release(struct Scsi_Ho
 		free_dma(shost->dma_channel);
 
 	release_region(shost->io_port, shost->n_io_port);
+	dma_free_coherent(ha->pdev ? &ha->pdev->dev : NULL,
+			  sizeof(*ha), ha, eata_shost_dma(shost));
 	scsi_unregister(shost);
 	return 0;
 }

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [9/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha1542
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (7 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [8/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in eata.c Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [10/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha152x/wd7000/sym53c416/u14-34f/NCR53c406a Andi Kleen
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


- Audited ->cmnd use and it always copies
- Allocate DMAable hostdata separately 
- Tell block layer explicitely to bounce
- Audited sense_buffer use and it always copies
- Remove unchecked_isa_dma finally

Untested due to lack of hardware

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/aha1542.c |   40 ++++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 10 deletions(-)

Index: linux/drivers/scsi/aha1542.c
===================================================================
--- linux.orig/drivers/scsi/aha1542.c
+++ linux/drivers/scsi/aha1542.c
@@ -151,7 +151,13 @@ struct aha1542_hostdata {
 	struct ccb ccb[AHA1542_MAILBOXES];
 };
 
-#define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
+struct hd_ptr {
+	struct aha1542_hostdata *hostptr;
+	dma_addr_t dma;
+};
+
+#define HOSTDATA(host) (((struct hd_ptr *)shost_priv(host))->hostptr)
+#define HOSTDMA(host) (((struct hd_ptr *)shost_priv(host))->dma)
 
 static DEFINE_SPINLOCK(aha1542_lock);
 
@@ -1125,23 +1131,28 @@ static int __init aha1542_detect(struct 
 	}
 	for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
 		if (bases[indx] != 0 && request_region(bases[indx], 4, "aha1542")) {
-			shpnt = scsi_register(tpnt,
-					sizeof(struct aha1542_hostdata));
+			struct aha1542_hostdata *host;
+
+			shpnt = scsi_register(tpnt, sizeof(struct hd_ptr));
 
 			if(shpnt==NULL) {
 				release_region(bases[indx], 4);
 				continue;
 			}
-			/* For now we do this - until kmalloc is more intelligent
-			   we are resigned to stupid hacks like this */
-			if (SCSI_BUF_PA(shpnt) >= ISA_DMA_THRESHOLD) {
-				printk(KERN_ERR "Invalid address for shpnt with 1542.\n");
-				goto unregister;
+
+			host = dma_alloc_coherent(NULL, sizeof(*host),
+						  &HOSTDMA(shpnt), GFP_KERNEL);
+			if (!host) {
+				scsi_unregister(shpnt);
+				release_region(bases[indx], 4);
+				continue;
 			}
+
+			HOSTDATA(shpnt) = host;
+
 			if (!aha1542_test_port(bases[indx], shpnt))
 				goto unregister;
 
-
 			base_io = bases[indx];
 
 			/* Set the Bus on/off-times as not to ruin floppy performance */
@@ -1259,6 +1270,8 @@ fail:
 			continue;
 unregister:
 			release_region(bases[indx], 4);
+			dma_free_coherent(NULL, sizeof(struct aha1542_hostdata),
+					  HOSTDATA(shpnt), HOSTDMA(shpnt));
 			scsi_unregister(shpnt);
 			continue;
 
@@ -1275,6 +1288,8 @@ static int aha1542_release(struct Scsi_H
 		free_dma(shost->dma_channel);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
+	dma_free_coherent(NULL, sizeof(struct aha1542_hostdata),
+			  HOSTDATA(shost), HOSTDMA(shost));
 	scsi_unregister(shost);
 	return 0;
 }
@@ -1746,6 +1761,11 @@ static int aha1542_biosparam(struct scsi
 }
 MODULE_LICENSE("GPL");
 
+static int aha154x_adjust_queue(struct scsi_device *device)
+{
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
 
 static struct scsi_host_template driver_template = {
 	.proc_name		= "aha1542",
@@ -1761,7 +1781,7 @@ static struct scsi_host_template driver_
 	.this_id		= 7,
 	.sg_tablesize		= AHA1542_SCATTER,
 	.cmd_per_lun		= AHA1542_CMDLUN,
-	.unchecked_isa_dma	= 1, 
 	.use_clustering		= ENABLE_CLUSTERING,
+	.slave_alloc		= aha154x_adjust_queue,
 };
 #include "scsi_module.c"

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [10/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha152x/wd7000/sym53c416/u14-34f/NCR53c406a
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (8 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [9/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha1542 Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [11/21] SCSI-ISA-DMA: Remove GFP_DMA uses in st/osst Andi Kleen
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


I lumped these all together because these old ISA only drivers all look 
very unmaintained and the changes were relatively simple.

I audited them for possible use of unchecked_isa_dma and fixed the cases
who needed them:
- Allocate separate dma'able hostdata when needed
- Checked that they all always copy ->cmnd
- Checked if they need sense_buffer bouncing and enable when needed
(i'm not 100% sure what it means if a driver does not reference
sense_buffer, but all except ultrastor and u14-34f do not) 
- Add a explicit slave_alloc callback to enable block layer bouncing

Untested due to lack of hardware.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/NCR53c406a.c |    8 +++++-
 drivers/scsi/aha152x.c    |   29 +++++++++++++++++++++---
 drivers/scsi/sym53c416.c  |    9 ++++++-
 drivers/scsi/u14-34f.c    |   54 +++++++++++++++++++++++++++++++++++-----------
 drivers/scsi/ultrastor.c  |   13 ++++++++---
 drivers/scsi/wd7000.c     |   48 +++++++++++++++++++++++++++-------------
 6 files changed, 124 insertions(+), 37 deletions(-)

Index: linux/drivers/scsi/aha152x.c
===================================================================
--- linux.orig/drivers/scsi/aha152x.c
+++ linux/drivers/scsi/aha152x.c
@@ -551,6 +551,10 @@ struct aha152x_hostdata {
 	struct list_head host_list;
 };
 
+struct aha152x_hostdata_ptr {
+	struct aha152x_hostdata *host;
+	dma_addr_t dma;
+};
 
 /*
  * host specific command extension
@@ -564,7 +568,10 @@ struct aha152x_scdata {
 
 /* access macros for hostdata */
 
-#define HOSTDATA(shpnt)		((struct aha152x_hostdata *) &shpnt->hostdata)
+#define HOSTDATA(shpnt) \
+	(((struct aha152x_hostdata_ptr *) shost_priv(shpnt))->host)
+#define HOSTDMA(shpnt) \
+	(((struct aha152x_hostdata_ptr *) shost_priv(shpnt))->dma)
 
 #define HOSTNO			((shpnt)->host_no)
 
@@ -771,14 +778,24 @@ static irqreturn_t swintr(int irqno, voi
 struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)
 {
 	struct Scsi_Host *shpnt;
+	struct aha152x_hostdata *host;
 
-	shpnt = scsi_host_alloc(&aha152x_driver_template, sizeof(struct aha152x_hostdata));
+	shpnt = scsi_host_alloc(&aha152x_driver_template,
+				sizeof(struct aha152x_hostdata_ptr));
 	if (!shpnt) {
 		printk(KERN_ERR "aha152x: scsi_host_alloc failed\n");
 		return NULL;
 	}
 
-	memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt));
+	host = dma_alloc_coherent(NULL, sizeof(struct aha152x_hostdata),
+				  &HOSTDMA(shpnt), GFP_KERNEL);
+	HOSTDATA(shpnt) = host;
+	if (!host) {
+		scsi_host_put(shpnt);
+		printk(KERN_ERR "aha152x: dma alloc of hostdata failed\n");
+		return NULL;
+	}
+
 	INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list);
 
 	/* need to have host registered before triggering any interrupt */
@@ -899,6 +916,8 @@ struct Scsi_Host *aha152x_probe_one(stru
 
 out_host_put:
 	list_del(&HOSTDATA(shpnt)->host_list);
+	dma_free_coherent(NULL, sizeof(struct aha152x_hostdata),
+			  HOSTDATA(shpnt), HOSTDMA(shpnt));
 	scsi_host_put(shpnt);
 
 	return NULL;
@@ -924,6 +943,8 @@ void aha152x_release(struct Scsi_Host *s
 #endif
 
 	list_del(&HOSTDATA(shpnt)->host_list);
+	dma_free_coherent(NULL, sizeof(struct aha152x_hostdata),
+			  HOSTDATA(shpnt), HOSTDMA(shpnt));
 	scsi_host_put(shpnt);
 }
 
@@ -3451,7 +3472,7 @@ static int aha152x_proc_info(struct Scsi
 
 static int aha152x_adjust_queue(struct scsi_device *device)
 {
-	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
 	return 0;
 }
 
Index: linux/drivers/scsi/wd7000.c
===================================================================
--- linux.orig/drivers/scsi/wd7000.c
+++ linux/drivers/scsi/wd7000.c
@@ -189,7 +189,6 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsicam.h>
 
-
 #undef  WD7000_DEBUG		/* general debug                */
 #ifdef WD7000_DEBUG
 #define dprintk printk
@@ -260,6 +259,14 @@ typedef struct adapter {
 	unchar rev1, rev2;	/* filled in by wd7000_revision      */
 } Adapter;
 
+struct adapter_ptr {
+	Adapter *host;
+	dma_addr_t dma;
+};
+
+#define wd_host(shost) (((struct adapter_ptr *)shost_priv(shost))->host)
+#define wd_host_dma(shost) (((struct adapter_ptr *)shost_priv(shost))->dma)
+
 /*
  * (linear) base address for ROM BIOS
  */
@@ -1092,7 +1099,7 @@ static int wd7000_queuecommand(struct sc
 	unchar idlun;
 	short cdblen;
 	int nseg;
-	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
+	Adapter *host = wd_host(SCpnt->device->host);
 
 	cdblen = SCpnt->cmd_len;
 	idlun = ((SCpnt->device->id << 5) & 0xe0) | (SCpnt->device->lun & 7);
@@ -1312,7 +1319,7 @@ static int wd7000_set_info(char *buffer,
 
 static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,  int inout)
 {
-	Adapter *adapter = (Adapter *)host->hostdata;
+	Adapter *adapter = wd_host(host);
 	unsigned long flags;
 	char *pos = buffer;
 #ifdef WD7000_DEBUG
@@ -1485,18 +1492,17 @@ static __init int wd7000_detect(struct s
 				dprintk("ok!\n");
 
 			if (inb(iobase + ASC_INTR_STAT) == 1) {
-				/*
-				 *  We register here, to get a pointer to the extra space,
-				 *  which we'll use as the Adapter structure (host) for
-				 *  this adapter.  It is located just after the registered
-				 *  Scsi_Host structure (sh), and is located by the empty
-				 *  array hostdata.
-				 */
-				sh = scsi_register(tpnt, sizeof(Adapter));
+				sh = scsi_register(tpnt, sizeof(struct adapter_ptr));
 				if (sh == NULL)
 					goto err_release;
 
-				host = (Adapter *) sh->hostdata;
+				host = dma_alloc_coherent(NULL, sizeof(Adapter),
+							  &wd_host_dma(sh),
+							  GFP_KERNEL);
+				if (!host)
+					goto err_unregister;
+
+				wd_host(sh) = host;
 
 				dprintk("wd7000_detect: adapter allocated at 0x%x\n", (int) host);
 				memset(host, 0, sizeof(Adapter));
@@ -1513,7 +1519,7 @@ static __init int wd7000_detect(struct s
 				dprintk("wd7000_detect: Trying init WD-7000 card at IO " "0x%x, IRQ %d, DMA %d...\n", host->iobase, host->irq, host->dma);
 
 				if (!wd7000_init(host))	/* Initialization failed */
-					goto err_unregister;
+					goto err_free_host;
 
 				/*
 				 *  OK from here - we'll use this adapter/configuration.
@@ -1540,6 +1546,8 @@ static __init int wd7000_detect(struct s
 
 		continue;
 
+	      err_free_host:
+		dma_free_coherent(NULL, sizeof(Adapter), host,wd_host_dma(sh));
 	      err_unregister:
 		scsi_unregister(sh);
 	      err_release:
@@ -1559,6 +1567,8 @@ static int wd7000_release(struct Scsi_Ho
 		free_irq(shost->irq, NULL);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
+	dma_free_coherent(NULL, sizeof(Adapter), wd_host(shost),
+			  wd_host_dma(shost));
 	scsi_unregister(shost);
 	return 0;
 }
@@ -1569,7 +1579,7 @@ static int wd7000_release(struct Scsi_Ho
  */
 static int wd7000_abort(Scsi_Cmnd * SCpnt)
 {
-	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
+	Adapter *host = wd_host(SCpnt->device->host);
 
 	if (inb(host->iobase + ASC_STAT) & INT_IM) {
 		printk("wd7000_abort: lost interrupt\n");
@@ -1586,7 +1596,7 @@ static int wd7000_abort(Scsi_Cmnd * SCpn
 
 static int wd7000_host_reset(struct scsi_cmnd *SCpnt)
 {
-	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
+	Adapter *host = wd_host(SCpnt->device->host);
 
 	spin_unlock_irq(SCpnt->device->host->host_lock);
 
@@ -1652,6 +1662,12 @@ static int wd7000_biosparam(struct scsi_
 	return (0);
 }
 
+static int wd7000_adjust_queue(struct scsi_device *device)
+{
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 MODULE_AUTHOR("Thomas Wuensche, John Boyd, Miroslav Zagorac");
 MODULE_DESCRIPTION("Driver for the WD7000 series ISA controllers");
 MODULE_LICENSE("GPL");
@@ -1669,7 +1685,7 @@ static struct scsi_host_template driver_
 	.this_id		= 7,
 	.sg_tablesize		= WD7000_SG,
 	.cmd_per_lun		= 1,
-	.unchecked_isa_dma	= 1,
+	.slave_alloc		= wd7000_adjust_queue,
 	.use_clustering		= ENABLE_CLUSTERING,
 };
 
Index: linux/drivers/scsi/NCR53c406a.c
===================================================================
--- linux.orig/drivers/scsi/NCR53c406a.c
+++ linux/drivers/scsi/NCR53c406a.c
@@ -1045,6 +1045,12 @@ static void __init calc_port_addr(void)
 
 MODULE_LICENSE("GPL");
 
+static int NCR53c406a_adjust_queue(struct scsi_device *device)
+{
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 /* NOTE:  scatter-gather support only works in PIO mode.
  * Use SG_NONE if DMA mode is enabled!
  */
@@ -1063,8 +1069,8 @@ static struct scsi_host_template driver_
      .this_id           	= 7			/* SCSI ID of the chip */,
      .sg_tablesize      	= 32			/*SG_ALL*/ /*SG_NONE*/, 
      .cmd_per_lun       	= 1			/* commands per lun */, 
-     .unchecked_isa_dma 	= 1			/* unchecked_isa_dma */,
      .use_clustering    	= ENABLE_CLUSTERING,
+     .slave_alloc		= NCR53c406a_adjust_queue,
 };
 
 #include "scsi_module.c"
Index: linux/drivers/scsi/u14-34f.c
===================================================================
--- linux.orig/drivers/scsi/u14-34f.c
+++ linux/drivers/scsi/u14-34f.c
@@ -439,6 +439,12 @@ static int u14_34f_bios_param(struct scs
                               sector_t, int *);
 static int u14_34f_slave_configure(struct scsi_device *);
 
+static int u14_34f_adjust_queue(struct scsi_device *device)
+{
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 static struct scsi_host_template driver_template = {
                 .name                    = "UltraStor 14F/34F rev. 8.10.00 ",
                 .detect                  = u14_34f_detect,
@@ -449,8 +455,9 @@ static struct scsi_host_template driver_
                 .bios_param              = u14_34f_bios_param,
                 .slave_configure         = u14_34f_slave_configure,
                 .this_id                 = 7,
-                .unchecked_isa_dma       = 1,
                 .use_clustering          = ENABLE_CLUSTERING,
+		.sense_buffer_isa	 = 1,
+		.slave_alloc		 = u14_34f_adjust_queue,
                 };
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
@@ -606,6 +613,11 @@ struct hostdata {
    char board_id[256];                  /* data from INQUIRY on this board */
    };
 
+struct hostdata_ptr {
+	struct hostdata *host;
+	dma_addr_t dma;
+};
+
 static struct Scsi_Host *sh[MAX_BOARDS + 1];
 static const char *driver_name = "Ux4F";
 static char sha[MAX_BOARDS];
@@ -627,7 +639,9 @@ static unsigned long io_port[] = {
    0x0
    };
 
-#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
+#define HOSTDATA(shost) (((struct hostdata_ptr *)shost_priv(shost))->host)
+#define HOSTDMA(shost) (((struct hostdata_ptr *)shost_priv(shost))->dma)
+#define HD(board) HOSTDATA(sh[board])
 #define BN(board) (HD(board)->board_name)
 
 /* Device is Little Endian */
@@ -688,7 +702,7 @@ static int u14_34f_slave_configure(struc
    char *tag_suffix, *link_suffix;
    struct Scsi_Host *host = dev->host;
 
-   j = ((struct hostdata *) host->hostdata)->board_number;
+   j = HOSTDATA(host)->board_number;
 
    utqd = MAX_CMD_PER_LUN;
    tqd = max_queue_depth;
@@ -799,6 +813,8 @@ static int port_detect \
    unsigned char irq, dma_channel, subversion, i;
    unsigned char in_byte;
    char *bus_type, dma_name[16];
+   struct hostdata *host;
+   dma_addr_t dma;
 
    /* Allowed BIOS base addresses (NULL indicates reserved) */
    unsigned long bios_segment_table[8] = {
@@ -888,13 +904,26 @@ static int port_detect \
    if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING;
 
    spin_unlock_irq(&driver_lock);
-   sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
+
+   host = dma_alloc_coherent(NULL, sizeof(struct hostdata), &dma, GFP_KERNEL);
+   if (!host) {
+	   printk("%s: unable to allocate dma data\n", name);
+	   spin_lock_irq(&driver_lock);
+	   goto freedma;
+   }
+
+   sh[j] = scsi_register(tpnt, sizeof(struct hostdata_ptr));
+   if (sh[j])
+     HOSTDMA(sh[j]) = dma;
+
    spin_lock_irq(&driver_lock);
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
-      goto freedma;
-      }
+      goto freebounce;
+   }
+   HOSTDATA(sh[j]) = host;
+   memset(host, 0, sizeof(struct hostdata));
 
    sh[j]->io_port = port_base;
    sh[j]->unique_id = port_base;
@@ -932,14 +961,12 @@ static int port_detect \
    if (have_old_firmware) sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
 
    if (HD(j)->subversion == ESA) {
-      sh[j]->unchecked_isa_dma = FALSE;
       sh[j]->dma_channel = NO_DMA;
       sprintf(BN(j), "U34F%d", j);
       bus_type = "VESA";
       }
    else {
       unsigned long flags;
-      sh[j]->unchecked_isa_dma = TRUE;
 
       flags=claim_dma_lock();
       disable_dma(dma_channel);
@@ -981,7 +1008,7 @@ static int port_detect \
    for (i = 0; i < sh[j]->can_queue; i++)
       if (! ((&HD(j)->cp[i])->sglist = kmalloc(
             sh[j]->sg_tablesize * sizeof(struct sg_list),
-            (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
+	    ((HD(j)->subversion != ESA) ? __GFP_DMA : 0) | GFP_ATOMIC))) {
          printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
          goto release;
          }
@@ -1015,6 +1042,8 @@ static int port_detect \
 
    return TRUE;
 
+freebounce:
+   dma_free_coherent(NULL, sizeof(struct hostdata), host, HOSTDMA(sh[j]));
 freedma:
    if (subversion == ISA) free_dma(dma_channel);
 freeirq:
@@ -1251,7 +1280,7 @@ static int u14_34f_queuecommand(struct s
    struct mscp *cpp;
 
    /* j is the board number */
-   j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
+   j = HOSTDATA(SCpnt->device->host)->board_number;
 
    if (SCpnt->host_scribble)
       panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
@@ -1330,7 +1359,7 @@ static int u14_34f_queuecommand(struct s
 static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
    unsigned int i, j;
 
-   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
+   j = HOSTDATA(SCarg->device->host)->board_number;
 
    if (SCarg->host_scribble == NULL) {
       scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n",
@@ -1398,7 +1427,7 @@ static int u14_34f_eh_host_reset(struct 
    int arg_done = FALSE;
    struct scsi_cmnd *SCpnt;
 
-   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
+   j = HOSTDATA(SCarg->device->host)->board_number;
    scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->serial_number);
 
    spin_lock_irq(sh[j]->host_lock);
@@ -1962,6 +1991,7 @@ static int u14_34f_release(struct Scsi_H
       free_dma(sh[j]->dma_channel);
 
    release_region(sh[j]->io_port, sh[j]->n_io_port);
+   dma_free_coherent(NULL, sizeof(struct hostdata), sh[j], HOSTDMA(sh[j]));
    scsi_unregister(sh[j]);
    return FALSE;
 }
Index: linux/drivers/scsi/sym53c416.c
===================================================================
--- linux.orig/drivers/scsi/sym53c416.c
+++ linux/drivers/scsi/sym53c416.c
@@ -825,6 +825,12 @@ module_param_array(sym53c416_3, uint, NU
 
 #endif
 
+static int sym53c416_adjust_queue(struct scsi_device *device)
+{
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 static struct scsi_host_template driver_template = {
 	.proc_name =		"sym53c416",
 	.name =			"Symbios Logic 53c416",
@@ -838,7 +844,8 @@ static struct scsi_host_template driver_
 	.this_id =		SYM53C416_SCSI_ID,
 	.sg_tablesize =		32,
 	.cmd_per_lun =		1,
-	.unchecked_isa_dma =	1,
 	.use_clustering =	ENABLE_CLUSTERING,
+	.slave_alloc =		sym53c416_adjust_queue,
+
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/ultrastor.c
===================================================================
--- linux.orig/drivers/scsi/ultrastor.c
+++ linux/drivers/scsi/ultrastor.c
@@ -350,6 +350,12 @@ static void log_ultrastor_abort(struct u
 }
 #endif
 
+static int ultrastor_adjust_queue(struct scsi_device *device)
+{
+	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_ISA);
+	return 0;
+}
+
 static int ultrastor_14f_detect(struct scsi_host_template * tpnt)
 {
     size_t i;
@@ -501,7 +507,10 @@ static int ultrastor_14f_detect(struct s
 	   config.dma_channel, config.ha_scsi_id, config.subversion);
 #endif
     tpnt->this_id = config.ha_scsi_id;
-    tpnt->unchecked_isa_dma = (config.subversion != U34F);
+    if (config.subversion != U34F) {
+	tpnt->sense_buffer_isa = 1;
+	tpnt->slave_alloc = ultrastor_adjust_queue;
+    }
 
 #if ULTRASTOR_MAX_CMDS > 1
     config.mscp_free = ~0;
@@ -605,7 +614,6 @@ static int ultrastor_24f_detect(struct s
 	     config.interrupt, config.ha_scsi_id);
 #endif
       tpnt->this_id = config.ha_scsi_id;
-      tpnt->unchecked_isa_dma = 0;
       tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
 
       shpnt = scsi_register(tpnt, 0);
@@ -1202,7 +1210,6 @@ static struct scsi_host_template driver_
 	.can_queue         = ULTRASTOR_MAX_CMDS,
 	.sg_tablesize      = ULTRASTOR_14F_MAX_SG,
 	.cmd_per_lun       = ULTRASTOR_MAX_CMDS_PER_LUN,
-	.unchecked_isa_dma = 1,
 	.use_clustering    = ENABLE_CLUSTERING,
 };
 #include "scsi_module.c"

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [11/21] SCSI-ISA-DMA: Remove GFP_DMA uses in st/osst
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (9 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [10/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha152x/wd7000/sym53c416/u14-34f/NCR53c406a Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [12/21] SCSI-ISA-DMA: Remove unchecked_isa_dma support for hostdata Andi Kleen
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Parts of it were already dead code: the ->dma member was only set, but not read.

Then also remove the code to allocate buffers with GFP_DMA, because this
goes all through the block layer which bounces anyways.

Also remove code to disable direct sg for unchecked_isa_dma

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/osst.c |   24 ++++++++++--------------
 drivers/scsi/osst.h |    2 --
 drivers/scsi/st.c   |   35 ++++++++++++++++-------------------
 drivers/scsi/st.h   |    2 --
 4 files changed, 26 insertions(+), 37 deletions(-)

Index: linux/drivers/scsi/osst.c
===================================================================
--- linux.orig/drivers/scsi/osst.c
+++ linux/drivers/scsi/osst.c
@@ -158,8 +158,8 @@ static DEFINE_RWLOCK(os_scsi_tapes_lock)
 
 static int modes_defined = 0;
 
-static struct osst_buffer *new_tape_buffer(int, int, int);
-static int enlarge_buffer(struct osst_buffer *, int);
+static struct osst_buffer *new_tape_buffer(int, int);
+static int enlarge_buffer(struct osst_buffer *);
 static void normalize_buffer(struct osst_buffer *);
 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
 static int from_buffer(struct osst_buffer *, char __user *, int);
@@ -4431,7 +4431,7 @@ static int __os_scsi_tape_open(struct in
 		STp->header_ok = 0;
 
 	/* Allocate data segments for this device's tape buffer */
-	if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
+	if (!enlarge_buffer(STp->buffer)) {
 		printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
 		retval = (-EOVERFLOW);
 		goto err_out;
@@ -5210,7 +5210,7 @@ static long osst_compat_ioctl(struct fil
 /* Memory handling routines */
 
 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
-static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
+static struct osst_buffer * new_tape_buffer( int from_initialization, int max_sg )
 {
 	int i;
 	gfp_t priority;
@@ -5231,19 +5231,18 @@ static struct osst_buffer * new_tape_buf
 	tb->sg_segs = tb->orig_sg_segs = 0;
 	tb->use_sg = max_sg;
 	tb->in_use = 1;
-	tb->dma = need_dma;
 	tb->buffer_size = 0;
 #if DEBUG
 	if (debugging) 
 		printk(OSST_DEB_MSG
-			"osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
-			   i, max_sg, need_dma);
+			"osst :D: Allocated tape buffer skeleton (%d bytes, %d segments).\n",
+			   i, max_sg);
 #endif
 	return tb;
 }
 
 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
-static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
+static int enlarge_buffer(struct osst_buffer *STbuffer)
 {
 	int segs, nbr, max_segs, b_size, order, got;
 	gfp_t priority;
@@ -5261,8 +5260,6 @@ static int enlarge_buffer(struct osst_bu
 		return 0;
 
 	priority = GFP_KERNEL /* | __GFP_NOWARN */;
-	if (need_dma)
-		priority |= GFP_DMA;
 
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
@@ -5307,8 +5304,8 @@ static int enlarge_buffer(struct osst_bu
 #if DEBUG
 	if (debugging) {
 		printk(OSST_DEB_MSG
-			   "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
-			   got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
+			   "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, at: %p).\n",
+			   got, STbuffer->orig_sg_segs, STbuffer->sg_segs, STbuffer->b_data);
 		printk(OSST_DEB_MSG
 			   "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
 			   STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
@@ -5805,7 +5802,7 @@ static int osst_probe(struct device *dev
 	i = SDp->host->sg_tablesize;
 	if (osst_max_sg_segs < i)
 		i = osst_max_sg_segs;
-	buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
+	buffer = new_tape_buffer(1, i);
 	if (buffer == NULL) {
 		write_unlock(&os_scsi_tapes_lock);
 		printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
@@ -5823,7 +5820,6 @@ static int osst_probe(struct device *dev
 	tpnt->capacity = 0xfffff;
 	tpnt->dirty = 0;
 	tpnt->drv_buffer = 1;  /* Try buffering if no mode sense */
-	tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
 	tpnt->density = 0;
 	tpnt->do_auto_lock = OSST_AUTO_LOCK;
 	tpnt->can_bsr = OSST_IN_FILE_POS;
Index: linux/drivers/scsi/osst.h
===================================================================
--- linux.orig/drivers/scsi/osst.h
+++ linux/drivers/scsi/osst.h
@@ -510,7 +510,6 @@ typedef struct os_header_s {
 /* The OnStream tape buffer descriptor. */
 struct osst_buffer {
   unsigned char in_use;
-  unsigned char dma;	/* DMA-able buffer */
   int buffer_size;
   int buffer_blocks;
   int buffer_bytes;
@@ -544,7 +543,6 @@ struct osst_tape {
   unsigned char can_partitions;
   unsigned char two_fm;
   unsigned char fast_mteom;
-  unsigned char restr_dma;
   unsigned char scsi2_logical;
   unsigned char default_drvbuffer;  /* 0xff = don't touch, value 3 bits */
   unsigned char pos_unknown;        /* after reset position unknown */
Index: linux/drivers/scsi/st.c
===================================================================
--- linux.orig/drivers/scsi/st.c
+++ linux/drivers/scsi/st.c
@@ -182,8 +182,8 @@ static struct scsi_tape **scsi_tapes = N
 
 static int modes_defined;
 
-static struct st_buffer *new_tape_buffer(int, int, int);
-static int enlarge_buffer(struct st_buffer *, int, int);
+static struct st_buffer *new_tape_buffer(int, int);
+static int enlarge_buffer(struct scsi_tape *t, struct st_buffer *, int);
 static void clear_buffer(struct st_buffer *);
 static void normalize_buffer(struct st_buffer *);
 static int append_to_buffer(const char __user *, struct st_buffer *, int);
@@ -1155,7 +1155,7 @@ static int st_open(struct inode *inode, 
 	}
 
 	/* See that we have at least a one page buffer available */
-	if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
+	if (!enlarge_buffer(STp, STp->buffer, PAGE_SIZE)) {
 		printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
 		       name);
 		retval = (-EOVERFLOW);
@@ -1447,7 +1447,7 @@ static int setup_buffering(struct scsi_t
 		}
 
 		if (bufsize > STbp->buffer_size &&
-		    !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
+		    !enlarge_buffer(STp, STbp, bufsize)) {
 			printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
 			       tape_name(STp), bufsize);
 			retval = (-EOVERFLOW);
@@ -3605,7 +3605,7 @@ static long st_compat_ioctl(struct file 
 /* Try to allocate a new tape buffer. Calling function must not hold
    dev_arr_lock. */
 static struct st_buffer *
- new_tape_buffer(int from_initialization, int need_dma, int max_sg)
+ new_tape_buffer(int from_initialization, int max_sg)
 {
 	int i, got = 0;
 	gfp_t priority;
@@ -3627,7 +3627,6 @@ static struct st_buffer *
 	tb->use_sg = max_sg;
 	tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
 
-	tb->dma = need_dma;
 	tb->buffer_size = got;
 	sg_init_table(tb->sg, max_sg);
 
@@ -3636,9 +3635,11 @@ static struct st_buffer *
 
 
 /* Try to allocate enough space in the tape buffer */
-static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
+static int enlarge_buffer(struct scsi_tape *t, struct st_buffer * STbuffer,
+			  int new_size)
 {
-	int segs, nbr, max_segs, b_size, order, got;
+	struct request_queue *q = t->device->request_queue;
+	int segs, nbr, max_segs, b_size, got;
 	gfp_t priority;
 
 	if (new_size <= STbuffer->buffer_size)
@@ -3653,20 +3654,18 @@ static int enlarge_buffer(struct st_buff
 		return 0;
 
 	priority = GFP_KERNEL | __GFP_NOWARN;
-	if (need_dma)
-		priority |= GFP_DMA;
-	for (b_size = PAGE_SIZE, order=0; order <= 6 &&
+	for (b_size = PAGE_SIZE; b_size <= (PAGE_SIZE << 6) &&
 	     b_size < new_size - STbuffer->buffer_size;
-	     order++, b_size *= 2)
+	     b_size *= 2)
 		;  /* empty */
 
 	for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
 	     segs < max_segs && got < new_size;) {
-		STbuffer->frp[segs].page = alloc_pages(priority, order);
+		STbuffer->frp[segs].page = alloc_pages_mask(priority,
+					b_size, blk_q_mask(q));
 		if (STbuffer->frp[segs].page == NULL) {
 			if (new_size - got <= (max_segs - segs) * b_size / 2) {
 				b_size /= 2; /* Large enough for the rest of the buffers */
-				order--;
 				continue;
 			}
 			DEB(STbuffer->buffer_size = got);
@@ -3701,11 +3700,10 @@ static void clear_buffer(struct st_buffe
 /* Release the extra buffer */
 static void normalize_buffer(struct st_buffer * STbuffer)
 {
-	int i, order;
+	int i;
 
 	for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
-		order = get_order(STbuffer->frp[i].length);
-		__free_pages(STbuffer->frp[i].page, order);
+		__free_pages_mask(STbuffer->frp[i].page, STbuffer->frp[i].length);
 		STbuffer->buffer_size -= STbuffer->frp[i].length;
 	}
 	STbuffer->frp_segs = STbuffer->orig_frp_segs;
@@ -3934,7 +3932,7 @@ static int st_probe(struct device *dev)
 		SDp->request_queue->max_phys_segments);
 	if (st_max_sg_segs < i)
 		i = st_max_sg_segs;
-	buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
+	buffer = new_tape_buffer(1, i);
 	if (buffer == NULL) {
 		printk(KERN_ERR
 		       "st: Can't allocate new tape buffer. Device not attached.\n");
@@ -4013,7 +4011,6 @@ static int st_probe(struct device *dev)
 	tpnt->dirty = 0;
 	tpnt->in_use = 0;
 	tpnt->drv_buffer = 1;	/* Try buffering if no mode sense */
-	tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
 	tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
 	tpnt->density = 0;
 	tpnt->do_auto_lock = ST_AUTO_LOCK;
Index: linux/drivers/scsi/st.h
===================================================================
--- linux.orig/drivers/scsi/st.h
+++ linux/drivers/scsi/st.h
@@ -33,7 +33,6 @@ struct st_request {
 
 /* The tape buffer descriptor. */
 struct st_buffer {
-	unsigned char dma;	/* DMA-able buffer */
 	unsigned char do_dio;   /* direct i/o set up? */
 	unsigned char cleared;  /* internal buffer cleared after open? */
 	int buffer_size;
@@ -113,7 +112,6 @@ struct scsi_tape {
 	unsigned char two_fm;
 	unsigned char fast_mteom;
 	unsigned char immediate;
-	unsigned char restr_dma;
 	unsigned char scsi2_logical;
 	unsigned char default_drvbuffer;	/* 0xff = don't touch, value 3 bits */
 	unsigned char cln_mode;			/* 0 = none, otherwise sense byte nbr */

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [12/21] SCSI-ISA-DMA: Remove unchecked_isa_dma support for hostdata
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (10 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [11/21] SCSI-ISA-DMA: Remove GFP_DMA uses in st/osst Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [13/21] SCSI-ISA-DMA: Use blk_q_mask/get_pages_mask in sg driver Andi Kleen
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


All ISA drivers who relied on dma able hostdata have been converted
to allocate it separately. So remove the unchecked_isa_dma hostdata
support in the mid layer

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/hosts.c |    3 ---
 1 file changed, 3 deletions(-)

Index: linux/drivers/scsi/hosts.c
===================================================================
--- linux.orig/drivers/scsi/hosts.c
+++ linux/drivers/scsi/hosts.c
@@ -314,9 +314,6 @@ struct Scsi_Host *scsi_host_alloc(struct
 	gfp_t gfp_mask = GFP_KERNEL;
 	int rval;
 
-	if (sht->unchecked_isa_dma && privsize)
-		gfp_mask |= __GFP_DMA;
-
 	shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
 	if (!shost)
 		return NULL;

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [13/21] SCSI-ISA-DMA: Use blk_q_mask/get_pages_mask in sg driver
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (11 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [12/21] SCSI-ISA-DMA: Remove unchecked_isa_dma support for hostdata Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [14/21] SCSI-ISA-DMA: Rely on block layer bouncing for ISA DMA devices scanning Andi Kleen
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Instead of using GFP_DMA directly.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/sg.c |   48 +++++++++++++-----------------------------------
 1 file changed, 13 insertions(+), 35 deletions(-)

Index: linux/drivers/scsi/sg.c
===================================================================
--- linux.orig/drivers/scsi/sg.c
+++ linux/drivers/scsi/sg.c
@@ -50,6 +50,7 @@ static int sg_version_num = 30534;	/* 2 
 #include <linux/scatterlist.h>
 #include <linux/blktrace_api.h>
 #include <linux/smp_lock.h>
+#include <linux/gfp.h>
 
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
@@ -151,7 +152,6 @@ typedef struct sg_fd {		/* holds the sta
 	Sg_request *headrp;	/* head of request slist, NULL->empty */
 	struct fasync_struct *async_qp;	/* used by asynchronous notification */
 	Sg_request req_arr[SG_MAX_QUEUE];	/* used as singly-linked list */
-	char low_dma;		/* as in parent but possibly overridden to 1 */
 	char force_packid;	/* 1 -> pack_id input to read(), 0 -> ignored */
 	volatile char closed;	/* 1 -> fd closed but request(s) outstanding */
 	char cmd_q;		/* 1 -> allow command queuing, 0 -> don't */
@@ -197,7 +197,7 @@ static void sg_remove_scat(Sg_scatter_ho
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
-static struct page *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
+static struct page *sg_page_malloc(struct scsi_device *dev, int rqSz, int *retSzp);
 static void sg_page_free(struct page *page, int size);
 static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
 static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
@@ -867,8 +867,7 @@ sg_ioctl(struct inode *inode, struct fil
 		if (result)
 			return result;
 		if (val) {
-			sfp->low_dma = 1;
-			if ((0 == sfp->low_dma) && (0 == sg_res_in_use(sfp))) {
+			if (0 == sg_res_in_use(sfp)) {
 				val = (int) sfp->reserve.bufflen;
 				sg_remove_scat(&sfp->reserve);
 				sg_build_reserve(sfp, val);
@@ -876,11 +875,10 @@ sg_ioctl(struct inode *inode, struct fil
 		} else {
 			if (sdp->detached)
 				return -ENODEV;
-			sfp->low_dma = sdp->device->host->unchecked_isa_dma;
 		}
 		return 0;
 	case SG_GET_LOW_DMA:
-		return put_user((int) sfp->low_dma, ip);
+		return put_user(0, ip);
 	case SG_GET_SCSI_ID:
 		if (!access_ok(VERIFY_WRITE, p, sizeof (sg_scsi_id_t)))
 			return -EFAULT;
@@ -1649,8 +1647,7 @@ sg_start_req(Sg_request * srp)
 	if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
 		return 0;
 	if (sg_allow_dio && (hp->flags & SG_FLAG_DIRECT_IO) &&
-	    (dxfer_dir != SG_DXFER_UNKNOWN) && (0 == hp->iovec_count) &&
-	    (!sfp->parentdp->device->host->unchecked_isa_dma)) {
+	    (dxfer_dir != SG_DXFER_UNKNOWN) && (0 == hp->iovec_count)) {
 		res = sg_build_direct(srp, sfp, dxfer_len);
 		if (res <= 0)	/* -ve -> error, 0 -> done, 1 -> try indirect */
 			return res;
@@ -1687,14 +1684,6 @@ sg_build_sgat(Sg_scatter_hold * schp, co
 	int sg_bufflen = tablesize * sizeof(struct scatterlist);
 	gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
-	/*
-	 * TODO: test without low_dma, we should not need it since
-	 * the block layer will bounce the buffer for us
-	 *
-	 * XXX(hch): we shouldn't need GFP_DMA for the actual S/G list.
-	 */
-	if (sfp->low_dma)
-		 gfp_flags |= GFP_DMA;
 	schp->buffer = kzalloc(sg_bufflen, gfp_flags);
 	if (!schp->buffer)
 		return -ENOMEM;
@@ -1887,7 +1876,7 @@ sg_build_indirect(Sg_scatter_hold * schp
 		
 		num = (rem_sz > scatter_elem_sz_prev) ?
 		      scatter_elem_sz_prev : rem_sz;
-		p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
+		p = sg_page_malloc(sfp->parentdp->device, num, &ret_sz);
 		if (!p)
 			return -ENOMEM;
 
@@ -2372,8 +2361,6 @@ sg_add_sfp(Sg_device * sdp, int dev)
 	sfp->timeout = SG_DEFAULT_TIMEOUT;
 	sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER;
 	sfp->force_packid = SG_DEF_FORCE_PACK_ID;
-	sfp->low_dma = (SG_DEF_FORCE_LOW_DMA == 0) ?
-	    sdp->device->host->unchecked_isa_dma : 1;
 	sfp->cmd_q = SG_DEF_COMMAND_Q;
 	sfp->keep_orphan = SG_DEF_KEEP_ORPHAN;
 	sfp->parentdp = sdp;
@@ -2483,7 +2470,7 @@ sg_res_in_use(Sg_fd * sfp)
 
 /* The size fetched (value output via retSzp) set when non-NULL return */
 static struct page *
-sg_page_malloc(int rqSz, int lowDma, int *retSzp)
+sg_page_malloc(struct scsi_device *dev, int rqSz, int *retSzp)
 {
 	struct page *resp = NULL;
 	gfp_t page_mask;
@@ -2493,15 +2480,12 @@ sg_page_malloc(int rqSz, int lowDma, int
 	if ((rqSz <= 0) || (NULL == retSzp))
 		return resp;
 
-	if (lowDma)
-		page_mask = GFP_ATOMIC | GFP_DMA | __GFP_COMP | __GFP_NOWARN;
-	else
-		page_mask = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN;
+	page_mask = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN;
 
 	for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
 	     order++, a_size <<= 1) ;
 	resSz = a_size;		/* rounded up if necessary */
-	resp = alloc_pages(page_mask, order);
+	resp = get_pages_mask(page_mask, resSz, blk_q_mask(dev->request_queue));
 	while ((!resp) && order) {
 		--order;
 		a_size >>= 1;	/* divide by 2, until PAGE_SIZE */
@@ -2519,13 +2503,8 @@ sg_page_malloc(int rqSz, int lowDma, int
 static void
 sg_page_free(struct page *page, int size)
 {
-	int order, a_size;
-
-	if (!page)
-		return;
-	for (order = 0, a_size = PAGE_SIZE; a_size < size;
-	     order++, a_size <<= 1) ;
-	__free_pages(page, order);
+	if (page)
+		__free_pages_mask(page, size);
 }
 
 #ifdef CONFIG_SCSI_PROC_FS
@@ -2868,11 +2847,10 @@ static void sg_proc_debug_helper(struct 
 
 	for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) {
 		seq_printf(s, "   FD(%d): timeout=%dms bufflen=%d "
-			   "(res)sgat=%d low_dma=%d\n", k + 1,
+			   "(res)sgat=%d\n", k + 1,
 			   jiffies_to_msecs(fp->timeout),
 			   fp->reserve.bufflen,
-			   (int) fp->reserve.k_use_sg,
-			   (int) fp->low_dma);
+			   (int) fp->reserve.k_use_sg);
 		seq_printf(s, "   cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n",
 			   (int) fp->cmd_q, (int) fp->force_packid,
 			   (int) fp->keep_orphan, (int) fp->closed);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [14/21] SCSI-ISA-DMA: Rely on block layer bouncing for ISA DMA devices scanning
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (12 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [13/21] SCSI-ISA-DMA: Use blk_q_mask/get_pages_mask in sg driver Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [15/21] SCSI-ISA-DMA: Don't disable direct_io for unchecked_isa_dma in st.c Andi Kleen
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Remove unchecked_isa_dma references in scsi_scan.c Instead we rely on
the block layer bouncing here. This is safe because all ISA DMA drivers have
been converted to set a suitable bounce pfn. Also scanning is not performance
critical, so a copy more or less doesn't matter.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/scsi_scan.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/scsi_scan.c
===================================================================
--- linux.orig/drivers/scsi/scsi_scan.c
+++ linux/drivers/scsi/scsi_scan.c
@@ -1015,8 +1015,7 @@ static int scsi_probe_and_add_lun(struct
 	if (!sdev)
 		goto out;
 
-	result = kmalloc(result_len, GFP_ATOMIC |
-			((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
+	result = kmalloc(result_len, GFP_ATOMIC);
 	if (!result)
 		goto out_free_sdev;
 
@@ -1335,8 +1334,7 @@ static int scsi_report_lun_scan(struct s
 	 * prevent us from finding any LUNs on this target.
 	 */
 	length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun);
-	lun_data = kmalloc(length, GFP_ATOMIC |
-			   (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
+	lun_data = kmalloc(length, GFP_ATOMIC);
 	if (!lun_data) {
 		printk(ALLOC_FAILURE_MSG, __func__);
 		goto out;

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [15/21] SCSI-ISA-DMA: Don't disable direct_io for unchecked_isa_dma in st.c
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (13 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [14/21] SCSI-ISA-DMA: Rely on block layer bouncing for ISA DMA devices scanning Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [16/21] SCSI-ISA-DMA: Remove automatic block layer bouncing for unchecked_isa_dma Andi Kleen
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Block layer bounces anyways.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/st.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/scsi/st.c
===================================================================
--- linux.orig/drivers/scsi/st.c
+++ linux/drivers/scsi/st.c
@@ -4027,7 +4027,7 @@ static int st_probe(struct device *dev)
 	tpnt->nbr_partitions = 0;
 	tpnt->device->timeout = ST_TIMEOUT;
 	tpnt->long_timeout = ST_LONG_TIMEOUT;
-	tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
+	tpnt->try_dio = try_direct_io;
 
 	for (i = 0; i < ST_NBR_MODES; i++) {
 		STm = &(tpnt->modes[i]);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [16/21] SCSI-ISA-DMA: Remove automatic block layer bouncing for unchecked_isa_dma
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (14 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [15/21] SCSI-ISA-DMA: Don't disable direct_io for unchecked_isa_dma in st.c Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [17/21] SCSI-ISA-DMA: Remove GFP_DMA use in sr.c Andi Kleen
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


All ISA drivers explicitely tell the block layer now that it needs
to bounce for them, so SCSI mid layer doesn't need to do that automatically
for unchecked_isa_dma anymore.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/scsi_lib.c |    2 --
 1 file changed, 2 deletions(-)

Index: linux/drivers/scsi/scsi_lib.c
===================================================================
--- linux.orig/drivers/scsi/scsi_lib.c
+++ linux/drivers/scsi/scsi_lib.c
@@ -1610,8 +1610,6 @@ u64 scsi_calculate_bounce_limit(struct S
 	struct device *host_dev;
 	u64 bounce_limit = 0xffffffff;
 
-	if (shost->unchecked_isa_dma)
-		return BLK_BOUNCE_ISA;
 	/*
 	 * Platforms with virtual-DMA translation
 	 * hardware have no practical limit.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [17/21] SCSI-ISA-DMA: Remove GFP_DMA use in sr.c
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (15 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [16/21] SCSI-ISA-DMA: Remove automatic block layer bouncing for unchecked_isa_dma Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [18/21] SCSI-ISA-DMA: Remove unchecked_isa_dma from sysfs Andi Kleen
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Just remove GFP_DMA in all explicit IO calls in sr.c and friends. 

The block layer will bounce correctly now, and as far as I can see all the 
explicit IOs here are only for very small data sizes, so one copy more does not 
really matter.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/sr.c        |    2 +-
 drivers/scsi/sr_ioctl.c  |   13 ++++---------
 drivers/scsi/sr_vendor.c |    4 ++--
 3 files changed, 7 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/sr.c
===================================================================
--- linux.orig/drivers/scsi/sr.c
+++ linux/drivers/scsi/sr.c
@@ -766,7 +766,7 @@ static void get_capabilities(struct scsi
 
 
 	/* allocate transfer buffer */
-	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = kmalloc(512, GFP_KERNEL);
 	if (!buffer) {
 		printk(KERN_ERR "sr: out of memory.\n");
 		return;
Index: linux/drivers/scsi/sr_ioctl.c
===================================================================
--- linux.orig/drivers/scsi/sr_ioctl.c
+++ linux/drivers/scsi/sr_ioctl.c
@@ -30,11 +30,6 @@ static int xa_test = 0;
 
 module_param(xa_test, int, S_IRUGO | S_IWUSR);
 
-/* primitive to determine whether we need to have GFP_DMA set based on
- * the status of the unchecked_isa_dma flag in the host structure */
-#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)
-
-
 static int sr_read_tochdr(struct cdrom_device_info *cdi,
 		struct cdrom_tochdr *tochdr)
 {
@@ -43,7 +38,7 @@ static int sr_read_tochdr(struct cdrom_d
 	int result;
 	unsigned char *buffer;
 
-	buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+	buffer = kmalloc(32, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
 
@@ -73,7 +68,7 @@ static int sr_read_tocentry(struct cdrom
 	int result;
 	unsigned char *buffer;
 
-	buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+	buffer = kmalloc(32, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
 
@@ -385,7 +380,7 @@ int sr_get_mcn(struct cdrom_device_info 
 {
 	Scsi_CD *cd = cdi->handle;
 	struct packet_command cgc;
-	char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+	char *buffer = kmalloc(32, GFP_KERNEL);
 	int result;
 
 	if (!buffer)
@@ -564,7 +559,7 @@ int sr_is_xa(Scsi_CD *cd)
 	if (!xa_test)
 		return 0;
 
-	raw_sector = kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd));
+	raw_sector = kmalloc(2048, GFP_KERNEL);
 	if (!raw_sector)
 		return -ENOMEM;
 	if (0 == sr_read_sector(cd, cd->ms_offset + 16,
Index: linux/drivers/scsi/sr_vendor.c
===================================================================
--- linux.orig/drivers/scsi/sr_vendor.c
+++ linux/drivers/scsi/sr_vendor.c
@@ -117,7 +117,7 @@ int sr_set_blocklength(Scsi_CD *cd, int 
 		density = (blocklength > 2048) ? 0x81 : 0x83;
 #endif
 
-	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = kmalloc(512, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
 
@@ -164,7 +164,7 @@ int sr_cd_check(struct cdrom_device_info
 	if (cd->cdi.mask & CDC_MULTI_SESSION)
 		return 0;
 
-	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = kmalloc(512, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [18/21] SCSI-ISA-DMA: Remove unchecked_isa_dma from sysfs
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (16 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [17/21] SCSI-ISA-DMA: Remove GFP_DMA use in sr.c Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [19/21] SCSI-ISA-DMA: Switch to a single SCSI command pool Andi Kleen
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


I opted to remove it because it's unlikely that user space uses it.

An alternative would be to always make it report 0 now.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/scsi_sysfs.c |    2 --
 1 file changed, 2 deletions(-)

Index: linux/drivers/scsi/scsi_sysfs.c
===================================================================
--- linux.orig/drivers/scsi/scsi_sysfs.c
+++ linux/drivers/scsi/scsi_sysfs.c
@@ -248,7 +248,6 @@ shost_rd_attr(host_busy, "%hu\n");
 shost_rd_attr(cmd_per_lun, "%hd\n");
 shost_rd_attr(can_queue, "%hd\n");
 shost_rd_attr(sg_tablesize, "%hu\n");
-shost_rd_attr(unchecked_isa_dma, "%d\n");
 shost_rd_attr(prot_capabilities, "%u\n");
 shost_rd_attr(prot_guard_type, "%hd\n");
 shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
@@ -259,7 +258,6 @@ static struct attribute *scsi_sysfs_shos
 	&dev_attr_cmd_per_lun.attr,
 	&dev_attr_can_queue.attr,
 	&dev_attr_sg_tablesize.attr,
-	&dev_attr_unchecked_isa_dma.attr,
 	&dev_attr_proc_name.attr,
 	&dev_attr_scan.attr,
 	&dev_attr_hstate.attr,

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [19/21] SCSI-ISA-DMA: Switch to a single SCSI command pool
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (17 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [18/21] SCSI-ISA-DMA: Remove unchecked_isa_dma from sysfs Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [20/21] SCSI-ISA-DMA: Finally kill unchecked_isa_dma Andi Kleen
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Now that no low level driver relies on ISA DMAable scsi_cmnds anymore
it is safe to always use the same static slab for them.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/scsi.c |   58 +++++++++++++++++++++++++++-------------------------
 1 file changed, 31 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/scsi.c
===================================================================
--- linux.orig/drivers/scsi/scsi.c
+++ linux/drivers/scsi/scsi.c
@@ -131,24 +131,24 @@ const char * scsi_device_type(unsigned t
 
 EXPORT_SYMBOL(scsi_device_type);
 
+/* Writing of both protected by host_cmd_pool_mutex */
+static struct kmem_cache *scsi_cmd_slab;
+static int cmd_pool_users;
+
 struct scsi_host_cmd_pool {
-	struct kmem_cache	*cmd_slab;
 	struct kmem_cache	*sense_slab;
 	unsigned int		users;
-	char			*cmd_name;
 	char			*sense_name;
 	unsigned int		slab_flags;
 	gfp_t			gfp_mask;
 };
 
-static struct scsi_host_cmd_pool scsi_cmd_pool = {
-	.cmd_name	= "scsi_cmd_cache",
+static struct scsi_host_cmd_pool scsi_sense_pool = {
 	.sense_name	= "scsi_sense_cache",
 	.slab_flags	= SLAB_HWCACHE_ALIGN,
 };
 
-static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
-	.cmd_name	= "scsi_cmd_cache(DMA)",
+static struct scsi_host_cmd_pool scsi_sense_dma_pool = {
 	.sense_name	= "scsi_sense_cache(DMA)",
 	.slab_flags	= SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA,
 	.gfp_mask	= __GFP_DMA,
@@ -169,7 +169,7 @@ scsi_pool_alloc_command(struct scsi_host
 {
 	struct scsi_cmnd *cmd;
 
-	cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
+	cmd = kmem_cache_alloc(scsi_cmd_slab, gfp_mask);
 	if (!cmd)
 		return NULL;
 
@@ -178,7 +178,7 @@ scsi_pool_alloc_command(struct scsi_host
 	cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
 					     gfp_mask | pool->gfp_mask);
 	if (!cmd->sense_buffer) {
-		kmem_cache_free(pool->cmd_slab, cmd);
+		kmem_cache_free(scsi_cmd_slab, cmd);
 		return NULL;
 	}
 
@@ -201,7 +201,7 @@ scsi_pool_free_command(struct scsi_host_
 		kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
 
 	kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
-	kmem_cache_free(pool->cmd_slab, cmd);
+	kmem_cache_free(scsi_cmd_slab, cmd);
 }
 
 /**
@@ -362,21 +362,26 @@ scsi_get_host_cmd_pool(struct Scsi_Host 
 	 * yet existent.
 	 */
 	mutex_lock(&host_cmd_pool_mutex);
-	pool = &scsi_cmd_pool;
-	if (shost && (shost->unchecked_isa_dma || shost->sense_buffer_isa))
-		pool = &scsi_cmd_dma_pool;
+	if (!scsi_cmd_slab) {
+		scsi_cmd_slab = kmem_cache_create("scsi_cmd_pool",
+						  sizeof(struct scsi_cmnd), 0,
+						  0, NULL);
+	}
+	if (!scsi_cmd_slab)
+		goto fail;
+	cmd_pool_users++;
+
+	pool = &scsi_sense_pool;
+	if (shost && shost->sense_buffer_isa)
+		pool = &scsi_sense_dma_pool;
 	if (!pool->users) {
-		pool->cmd_slab = kmem_cache_create(pool->cmd_name,
-						   sizeof(struct scsi_cmnd), 0,
-						   pool->slab_flags, NULL);
-		if (!pool->cmd_slab)
-			goto fail;
-
 		pool->sense_slab = kmem_cache_create(pool->sense_name,
 						     SCSI_SENSE_BUFFERSIZE, 0,
 						     pool->slab_flags, NULL);
 		if (!pool->sense_slab) {
-			kmem_cache_destroy(pool->cmd_slab);
+			kmem_cache_destroy(scsi_cmd_slab);
+			scsi_cmd_slab = NULL;
+			cmd_pool_users--;
 			goto fail;
 		}
 	}
@@ -393,8 +398,8 @@ static void scsi_put_host_cmd_pool(struc
 	struct scsi_host_cmd_pool *pool;
 
 	mutex_lock(&host_cmd_pool_mutex);
-	pool = (shost && (shost->unchecked_isa_dma || shost->sense_buffer_isa)) ?
-		&scsi_cmd_dma_pool : &scsi_cmd_pool;
+	pool = (shost && shost->sense_buffer_isa) ?
+		&scsi_sense_dma_pool : &scsi_sense_pool;
 	/*
 	 * This may happen if a driver has a mismatched get and put
 	 * of the command pool; the driver should be implicated in
@@ -402,9 +407,11 @@ static void scsi_put_host_cmd_pool(struc
 	 */
 	BUG_ON(pool->users == 0);
 
-	if (!--pool->users) {
-		kmem_cache_destroy(pool->cmd_slab);
+	if (!--pool->users)
 		kmem_cache_destroy(pool->sense_slab);
+	if (!--cmd_pool_users) {
+		kmem_cache_destroy(scsi_cmd_slab);
+		scsi_cmd_slab = NULL;
 	}
 	mutex_unlock(&host_cmd_pool_mutex);
 }
@@ -489,9 +496,6 @@ EXPORT_SYMBOL(scsi_free_command);
 int scsi_setup_command_freelist(struct Scsi_Host *shost)
 {
 	struct scsi_cmnd *cmd;
-	gfp_t gfp_mask = GFP_KERNEL;
-	if (shost->unchecked_isa_dma || shost->sense_buffer_isa)
-		gfp_mask = GFP_DMA;
 
 	spin_lock_init(&shost->free_list_lock);
 	INIT_LIST_HEAD(&shost->free_list);
@@ -504,7 +508,7 @@ int scsi_setup_command_freelist(struct S
 	/*
 	 * Get one backup command for this host.
 	 */
-	cmd = scsi_host_alloc_command(shost, gfp_mask);
+	cmd = scsi_host_alloc_command(shost, 0);
 	if (!cmd) {
 		scsi_put_host_cmd_pool(shost);
 		shost->cmd_pool = NULL;

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [20/21] SCSI-ISA-DMA: Finally kill unchecked_isa_dma
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (18 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [19/21] SCSI-ISA-DMA: Switch to a single SCSI command pool Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-02  7:58 ` [PATCH] [21/21] SCSI-ISA-DMA: Convert DMA buffers in ch.c to allocate via the block layer Andi Kleen
  2008-10-07 23:53 ` [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Now that all users are gone it can be safely completely removed.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 Documentation/scsi/scsi_mid_low_api.txt |    3 ---
 drivers/scsi/hosts.c                    |    1 -
 include/scsi/scsi_host.h                |    6 ------
 3 files changed, 10 deletions(-)

Index: linux/Documentation/scsi/scsi_mid_low_api.txt
===================================================================
--- linux.orig/Documentation/scsi/scsi_mid_low_api.txt
+++ linux/Documentation/scsi/scsi_mid_low_api.txt
@@ -1254,9 +1254,6 @@ of interest:
     cmd_per_lun  - maximum number of commands that can be queued on devices
                    controlled by the host. Overridden by LLD calls to
                    scsi_adjust_queue_depth().
-    unchecked_isa_dma - 1=>only use bottom 16 MB of ram (ISA DMA addressing
-                   restriction), 0=>can use full 32 bit (or better) DMA
-                   address space
     use_clustering - 1=>SCSI commands in mid level's queue can be merged,
                      0=>disallow SCSI command merging
     hostt        - pointer to driver's struct scsi_host_template from which
Index: linux/drivers/scsi/hosts.c
===================================================================
--- linux.orig/drivers/scsi/hosts.c
+++ linux/drivers/scsi/hosts.c
@@ -352,7 +352,6 @@ struct Scsi_Host *scsi_host_alloc(struct
 	shost->can_queue = sht->can_queue;
 	shost->sg_tablesize = sht->sg_tablesize;
 	shost->cmd_per_lun = sht->cmd_per_lun;
-	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
 	shost->use_clustering = sht->use_clustering;
 	shost->ordered_tag = sht->ordered_tag;
 
Index: linux/include/scsi/scsi_host.h
===================================================================
--- linux.orig/include/scsi/scsi_host.h
+++ linux/include/scsi/scsi_host.h
@@ -424,11 +424,6 @@ struct scsi_host_template {
 	unsigned supported_mode:2;
 
 	/*
-	 * True if this host adapter uses unchecked DMA onto an ISA bus.
-	 */
-	unsigned unchecked_isa_dma:1;
-
-	/*
 	 * True if this host adapter can make good use of clustering.
 	 * I originally thought that if the tablesize was large that it
 	 * was a waste of CPU cycles to prepare a cluster list, but
@@ -597,7 +592,6 @@ struct Scsi_Host {
 	unsigned long cmd_serial_number;
 	
 	unsigned active_mode:2;
-	unsigned unchecked_isa_dma:1;
 	unsigned use_clustering:1;
 	unsigned use_blk_tcq:1;
 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] [21/21] SCSI-ISA-DMA: Convert DMA buffers in ch.c to allocate via the block layer
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (19 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [20/21] SCSI-ISA-DMA: Finally kill unchecked_isa_dma Andi Kleen
@ 2008-10-02  7:58 ` Andi Kleen
  2008-10-07 23:53 ` [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
  21 siblings, 0 replies; 24+ messages in thread
From: Andi Kleen @ 2008-10-02  7:58 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, axboe


Instead of specifying GFP_DMA always ask the block layer to get 
some dma'able memory

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/scsi/ch.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/ch.c
===================================================================
--- linux.orig/drivers/scsi/ch.c
+++ linux/drivers/scsi/ch.c
@@ -232,7 +232,8 @@ ch_read_element_status(scsi_changer *ch,
 	u_char  *buffer;
 	int     result;
 
-	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = get_pages_mask(GFP_KERNEL, 512,
+				blk_q_mask(ch->device->request_queue));
 	if(!buffer)
 		return -ENOMEM;
 
@@ -262,7 +263,7 @@ ch_read_element_status(scsi_changer *ch,
 		}
 		dprintk("READ ELEMENT STATUS for element 0x%x failed\n",elem);
 	}
-	kfree(buffer);
+	free_pages_mask(buffer, 512);
 	return result;
 }
 
@@ -289,9 +290,11 @@ ch_readconfig(scsi_changer *ch)
 	int     result,id,lun,i;
 	u_int   elem;
 
-	buffer = kzalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = get_pages_mask(GFP_KERNEL, 512,
+				blk_q_mask(ch->device->request_queue));
 	if (!buffer)
 		return -ENOMEM;
+	memset(buffer, 0, 512);
 
 	memset(cmd,0,sizeof(cmd));
 	cmd[0] = MODE_SENSE;
@@ -402,7 +405,7 @@ ch_readconfig(scsi_changer *ch)
 		}
 	}
 	ch->voltags = 1;
-	kfree(buffer);
+	free_pages_mask(buffer, 512);
 
 	return 0;
 }
@@ -737,7 +740,8 @@ static long ch_ioctl(struct file *file,
 			return -EINVAL;
 		elem = ch->firsts[cge.cge_type] + cge.cge_unit;
 
-		buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+		buffer = get_pages_mask(GFP_KERNEL, 512,
+					blk_q_mask(ch->device->request_queue));
 		if (!buffer)
 			return -ENOMEM;
 		mutex_lock(&ch->lock);
@@ -791,7 +795,7 @@ static long ch_ioctl(struct file *file,
 			vprintk("device has no volume tag support\n");
 			goto voltag_retry;
 		}
-		kfree(buffer);
+		free_pages_mask(buffer, 512);
 		mutex_unlock(&ch->lock);
 
 		if (copy_to_user(argp, &cge, sizeof (cge)))

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3
  2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
                   ` (20 preceding siblings ...)
  2008-10-02  7:58 ` [PATCH] [21/21] SCSI-ISA-DMA: Convert DMA buffers in ch.c to allocate via the block layer Andi Kleen
@ 2008-10-07 23:53 ` Andi Kleen
  2008-10-08 10:21   ` Jens Axboe
  21 siblings, 1 reply; 24+ messages in thread
From: Andi Kleen @ 2008-10-07 23:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: James.Bottomley, axboe

Andi Kleen <andi@firstfloor.org> writes:

> This reposts the patchkit to remove unchecked_isa_dma which was already
> discussed some time ago. Instead it replaces it with interfaces
> that declare the mask. Right now those interfaces map back to GFP_DMA
> eventually, but it is a preparation for using the DMA mask allocator
> eventually.

ping? Any comments please?

-Andi

-- 
ak@linux.intel.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3
  2008-10-07 23:53 ` [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
@ 2008-10-08 10:21   ` Jens Axboe
  0 siblings, 0 replies; 24+ messages in thread
From: Jens Axboe @ 2008-10-08 10:21 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-scsi, James.Bottomley

On Wed, Oct 08 2008, Andi Kleen wrote:
> Andi Kleen <andi@firstfloor.org> writes:
> 
> > This reposts the patchkit to remove unchecked_isa_dma which was already
> > discussed some time ago. Instead it replaces it with interfaces
> > that declare the mask. Right now those interfaces map back to GFP_DMA
> > eventually, but it is a preparation for using the DMA mask allocator
> > eventually.
> 
> ping? Any comments please?

FWIW, the patchset looks fine to me.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2008-10-08 10:22 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-02  7:58 [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
2008-10-02  7:58 ` [PATCH] [1/21] SCSI-ISA-DMA: Add the alloc/get_pages_mask calls Andi Kleen
2008-10-02  7:58 ` [PATCH] [2/21] SCSI-ISA-DMA: Add blk_q_mask Andi Kleen
2008-10-02  7:58 ` [PATCH] [3/21] SCSI-ISA-DMA: Pass gfp to scsi_allocate_command Andi Kleen
2008-10-02  7:58 ` [PATCH] [4/21] SCSI-ISA-DMA: Add sense_buffer_isa to host template Andi Kleen
2008-10-02  7:58 ` [PATCH] [5/21] SCSI-ISA-DMA: Remove unchecked_isa in BusLogic Andi Kleen
2008-10-02  7:58 ` [PATCH] [6/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in advansys.c Andi Kleen
2008-10-02  7:58 ` [PATCH] [7/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in gdth Andi Kleen
2008-10-02  7:58 ` [PATCH] [8/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in eata.c Andi Kleen
2008-10-02  7:58 ` [PATCH] [9/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha1542 Andi Kleen
2008-10-02  7:58 ` [PATCH] [10/21] SCSI-ISA-DMA: Remove unchecked_isa_dma in aha152x/wd7000/sym53c416/u14-34f/NCR53c406a Andi Kleen
2008-10-02  7:58 ` [PATCH] [11/21] SCSI-ISA-DMA: Remove GFP_DMA uses in st/osst Andi Kleen
2008-10-02  7:58 ` [PATCH] [12/21] SCSI-ISA-DMA: Remove unchecked_isa_dma support for hostdata Andi Kleen
2008-10-02  7:58 ` [PATCH] [13/21] SCSI-ISA-DMA: Use blk_q_mask/get_pages_mask in sg driver Andi Kleen
2008-10-02  7:58 ` [PATCH] [14/21] SCSI-ISA-DMA: Rely on block layer bouncing for ISA DMA devices scanning Andi Kleen
2008-10-02  7:58 ` [PATCH] [15/21] SCSI-ISA-DMA: Don't disable direct_io for unchecked_isa_dma in st.c Andi Kleen
2008-10-02  7:58 ` [PATCH] [16/21] SCSI-ISA-DMA: Remove automatic block layer bouncing for unchecked_isa_dma Andi Kleen
2008-10-02  7:58 ` [PATCH] [17/21] SCSI-ISA-DMA: Remove GFP_DMA use in sr.c Andi Kleen
2008-10-02  7:58 ` [PATCH] [18/21] SCSI-ISA-DMA: Remove unchecked_isa_dma from sysfs Andi Kleen
2008-10-02  7:58 ` [PATCH] [19/21] SCSI-ISA-DMA: Switch to a single SCSI command pool Andi Kleen
2008-10-02  7:58 ` [PATCH] [20/21] SCSI-ISA-DMA: Finally kill unchecked_isa_dma Andi Kleen
2008-10-02  7:58 ` [PATCH] [21/21] SCSI-ISA-DMA: Convert DMA buffers in ch.c to allocate via the block layer Andi Kleen
2008-10-07 23:53 ` [PATCH] [0/21] Remove SCSI unchecked_isa_dma try 3 Andi Kleen
2008-10-08 10:21   ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox