Re: st driver doesn't seem to grok LTO partitioning

2015-12-21 Thread Kai Mäkisara (Kolumbus)

> On 21.12.2015, at 19.57, Emmanuel Florac  wrote:
> 
> Le Mon, 21 Dec 2015 19:25:27 +0200
> "Kai Mäkisara (Kolumbus)"   écrivait:
> 
>>> 
>>> I'm replying to myself: this is very obviously a limitation of the
>>> st driver. Checking st.c partition_tape() function, it looks like
>>> it only knows of hardware from past century… 
>>> 
>> True, it does support only the methods supported by the drives
>> available to the developers at that time :-) However, I am not any
>> more convinced that partitioning a tape should be done by the kernel
>> driver. A more flexible method would be a user space program using sg
>> (or bsg) driver.
> 
> Yes, that's the way the LTFS utility works. That makes the code of the
> application quite hard to read, though, as partitioning on modern
> drives is pretty complex and requires understanding ugly, unholy SCSI
> commands magic. Then Windows/Cygwin, IBM AIX and maybe others seem to
> implement partitioning at the kernel level.
> 
> Do you suggest the current mkpartition/setpartition scheme should be
> removed instead of enhanced ? :)
> 
I don’t suggest that it should be removed. I just pointed out another 
possibility
to implement the more complex formatting cases. I think that SCSI is well 
defined,
but it offers too many ways to do one thing :-) In user space one can implement
several alternatives but the kernel driver has to choose only one (or move the
complexity to the interface). On the other hand, the kernel driver can allow
anyone (who can access the st device) to partition the tape. A user space
program needs more rights.

If the current interface (MTMKPART) is acceptable, we could enhance the driver
so that it handles properly more drives. I looked at the HP Ultrium SCSI 
reference
and it may not be too complicated (for instance, it needs a separate FORMAT 
MEDIUM
command) . I have also found an IBM reference and others can probably be found.
I can look at the manuals during Christmas holidays and try to think about a 
suggestion.
All other suggestions are, of course, welcome. My view may be somewhat 
theoretical
because I don’t have access to current hardware.

>>> OTOH it seems that Cygwin does that properly... by using
>>> CreateTapePartition, a windows kernel32.dll function. Argh. We'll
>>> have to do the heavy lifting of SCSI commands by hand, then.
>>> 
>>> Where should we post an eventual patch, given that the linux-tape ML
>>> looks like a ghost town? It would also be great to be able to
>>> support more than 2 partitions (LTO-6 and 7 support 4), but that
>>> would require patching the mt utility too, but I don't where it
>>> currently lives :) Any hints welcome.
>>> 
>> This (linux-scsi) is the correct mailing list.
>> 
> 
> OK. As I mentioned, the bizarre IBM lin_tape driver (what use is it?)
> implements the complete scheme properly apparently, in a nice GPL2 code.
> Why they didn't contribute it directly to the st driver is mysterious.
> 
I will look at the driver. HP also seems to have an implementation (for LTFS) 
but
I did not find the code because their web links don’t seem to be uptodate.

>> The correct source code of your mt depends on the version you are
>> using (check the distribution). Not also that the ioctl method for
>> creating partitions available in the kernel supports only up to two
>> partitions. If you want more, you should design a new interface.
> 
> I'm using mt-st on debian, the one that seems to go hand in hand with
> the st driver. Both carry your copyright :)
> 
OK. Then the mt part will not be a problem. I have not updated it “recently”
because the kernel interface has not changed.

Kai

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt path

2015-12-21 Thread KY Srinivasan


> -Original Message-
> From: James Bottomley [mailto:james.bottom...@hansenpartnership.com]
> Sent: Monday, December 21, 2015 8:28 AM
> To: KY Srinivasan ; Hannes Reinecke ;
> gre...@linuxfoundation.org; linux-ker...@vger.kernel.org;
> de...@linuxdriverproject.org; oher...@suse.com;
> jbottom...@parallels.com; h...@infradead.org; linux-scsi@vger.kernel.org;
> a...@canonical.com; vkuzn...@redhat.com; jasow...@redhat.com;
> martin.peter...@oracle.com
> Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt path
> 
> On Sat, 2015-12-19 at 02:28 +, KY Srinivasan wrote:
> >
> > > -Original Message-
> > > From: James Bottomley
> [mailto:james.bottom...@hansenpartnership.com
> > > ]
> > > Sent: Friday, December 18, 2015 8:48 AM
> > > To: KY Srinivasan ; Hannes Reinecke <
> > > h...@suse.de>;
> > > gre...@linuxfoundation.org; linux-ker...@vger.kernel.org;
> > > de...@linuxdriverproject.org; oher...@suse.com;
> > > jbottom...@parallels.com; h...@infradead.org;
> > > linux-scsi@vger.kernel.org;
> > > a...@canonical.com; vkuzn...@redhat.com; jasow...@redhat.com;
> > > martin.peter...@oracle.com
> > > Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt
> > > path
> > >
> > > On Fri, 2015-12-18 at 16:20 +, KY Srinivasan wrote:
> > > >
> > > > > -Original Message-
> > > > > From: Hannes Reinecke [mailto:h...@suse.de]
> > > > > Sent: Friday, December 18, 2015 12:52 AM
> > > > > To: KY Srinivasan ;
> > > > > gre...@linuxfoundation.org;
> > > > > linux-
> > > > > ker...@vger.kernel.org; de...@linuxdriverproject.org;
> > > > > oher...@suse.com;
> > > > > jbottom...@parallels.com; h...@infradead.org;
> > > > > linux-scsi@vger.kernel.org;
> > > > > a...@canonical.com; vkuzn...@redhat.com; jasow...@redhat.com;
> > > > > martin.peter...@oracle.com
> > > > > Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the
> > > > > interrupt
> > > > > path
> > > > >
> > > > > On 12/13/2015 09:28 PM, K. Y. Srinivasan wrote:
> > > > > > On the interrupt path, we repeatedly establish the pointer to
> > > > > > the
> > > > > > storvsc_device. Fix this.
> > > > > >
> > > > > > Signed-off-by: K. Y. Srinivasan 
> > > > > > Reviewed-by: Long Li 
> > > > > > Reviewed-by: Johannes Thumshirn 
> > > > > > Tested-by: Alex Ng 
> > > > > > ---
> > > > > >   drivers/scsi/storvsc_drv.c |   23 ---
> > > > > >   1 files changed, 8 insertions(+), 15 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/scsi/storvsc_drv.c
> > > > > > b/drivers/scsi/storvsc_drv.c
> > > > > > index d6ca4f2..b68aebe 100644
> > > > > > --- a/drivers/scsi/storvsc_drv.c
> > > > > > +++ b/drivers/scsi/storvsc_drv.c
> > > > > > @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct
> > > > > vmscsi_request *vm_srb,
> > > > > >   }
> > > > > >
> > > > > >
> > > > > > -static void storvsc_command_completion(struct
> > > > > > storvsc_cmd_request
> > > > > *cmd_request)
> > > > > > +static void storvsc_command_completion(struct
> > > > > > storvsc_cmd_request
> > > > > *cmd_request,
> > > > > > +  struct storvsc_device
> > > > > > *stor_dev)
> > > > > >   {
> > > > > > struct scsi_cmnd *scmnd = cmd_request->cmd;
> > > > > > -   struct hv_host_device *host_dev = shost_priv(scmnd
> > > > > > ->device-
> > > > > > host);
> > > > > > struct scsi_sense_hdr sense_hdr;
> > > > > > struct vmscsi_request *vm_srb;
> > > > > > struct Scsi_Host *host;
> > > > > > -   struct storvsc_device *stor_dev;
> > > > > > -   struct hv_device *dev = host_dev->dev;
> > > > > > u32 payload_sz = cmd_request->payload_sz;
> > > > > > void *payload = cmd_request->payload;
> > > > > >
> > > > > > -   stor_dev = get_in_stor_device(dev);
> > > > > > host = stor_dev->host;
> > > > > >
> > > > > > vm_srb = _request->vstor_packet.vm_srb;
> > > > > > @@ -987,14 +984,13 @@ static void
> > > > > > storvsc_command_completion(struct
> > > > > storvsc_cmd_request *cmd_request)
> > > > > > kfree(payload);
> > > > > >   }
> > > > > >
> > > > > > -static void storvsc_on_io_completion(struct hv_device
> > > > > > *device,
> > > > > > +static void storvsc_on_io_completion(struct storvsc_device
> > > > > > *stor_device,
> > > > > >   struct vstor_packet
> > > > > > *vstor_packet,
> > > > > >   struct
> > > > > > storvsc_cmd_request
> > > > > > *request)
> > > > > >   {
> > > > > > -   struct storvsc_device *stor_device;
> > > > > > struct vstor_packet *stor_pkt;
> > > > > > +   struct hv_device *device = stor_device->device;
> > > > > >
> > > > > > -   stor_device = hv_get_drvdata(device);
> > > > > > stor_pkt = >vstor_packet;
> > > > > >
> > > > > > /*
> > > > > > @@ -1049,7 +1045,7 @@ static void
> > > > > > 

Re: [PATCH v2 3/3] hpsa: add box and bay information for enclosure devices

2015-12-21 Thread kbuild test robot
Hi Don,

[auto build test ERROR on scsi/for-next]
[also build test ERROR on v4.4-rc6 next-20151221]

url:
https://github.com/0day-ci/linux/commits/Don-Brace/hpsa-updates/20151222-012604
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: alpha-allyesconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=alpha 

All errors (new ones prefixed by >>):

   drivers/scsi/hpsa.c: In function 'hpsa_get_enclosure_info':
   drivers/scsi/hpsa.c:3201:2: error: parameter 'rc' is initialized
 int rc = -1;
 ^
   drivers/scsi/hpsa.c:3202:9: error: parameter 'c' is initialized
 struct CommandList *c = NULL;
^
   drivers/scsi/hpsa.c:3203:9: error: parameter 'ei' is initialized
 struct ErrorInfo *ei = NULL;
^
   drivers/scsi/hpsa.c:3204:9: error: parameter 'bssbp' is initialized
 struct bmic_sense_storage_box_params *bssbp = NULL;
^
   drivers/scsi/hpsa.c:3205:9: error: parameter 'id_phys' is initialized
 struct bmic_identify_physical_device *id_phys = NULL;
^
   drivers/scsi/hpsa.c:3206:9: error: parameter 'rle' is initialized
 struct ext_report_lun_entry *rle = >LUN[rle_index];
^
   drivers/scsi/hpsa.c:3206:38: error: 'rlep' undeclared (first use in this 
function)
 struct ext_report_lun_entry *rle = >LUN[rle_index];
 ^
   drivers/scsi/hpsa.c:3206:38: note: each undeclared identifier is reported 
only once for each function it appears in
   drivers/scsi/hpsa.c:3206:48: error: 'rle_index' undeclared (first use in 
this function)
 struct ext_report_lun_entry *rle = >LUN[rle_index];
   ^
   drivers/scsi/hpsa.c:3207:2: error: parameter 'bmic_device_index' is 
initialized
 u16 bmic_device_index = 0;
 ^
   drivers/scsi/hpsa.c:3209:2: error: expected declaration specifiers before 
'bmic_device_index'
 bmic_device_index = GET_BMIC_DRIVE_NUMBER(>lunid[0]);
 ^
   drivers/scsi/hpsa.c:3211:2: error: expected declaration specifiers before 
'if'
 if (bmic_device_index == 0xFF00)
 ^
   drivers/scsi/hpsa.c:3214:2: error: expected declaration specifiers before 
'bssbp'
 bssbp = kzalloc(sizeof(*bssbp), GFP_KERNEL);
 ^
   drivers/scsi/hpsa.c:3215:2: error: expected declaration specifiers before 
'if'
 if (!bssbp)
 ^
   drivers/scsi/hpsa.c:3218:2: error: expected declaration specifiers before 
'id_phys'
 id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL);
 ^
   drivers/scsi/hpsa.c:3219:2: error: expected declaration specifiers before 
'if'
 if (!id_phys)
 ^
   drivers/scsi/hpsa.c:3222:2: error: expected declaration specifiers before 
'rc'
 rc = hpsa_bmic_id_physical_device(h, scsi3addr, bmic_device_index,
 ^
   drivers/scsi/hpsa.c:3224:2: error: expected declaration specifiers before 
'if'
 if (rc) {
 ^
   drivers/scsi/hpsa.c:3230:2: error: expected declaration specifiers before 'c'
 c = cmd_alloc(h);
 ^
   drivers/scsi/hpsa.c:3232:2: error: expected declaration specifiers before 
'rc'
 rc = fill_cmd(c, BMIC_SENSE_STORAGE_BOX_PARAMS, h, bssbp,
 ^
   drivers/scsi/hpsa.c:3235:2: error: expected declaration specifiers before 
'if'
 if (rc)
 ^
   drivers/scsi/hpsa.c:3238:2: error: expected declaration specifiers before 
'if'
 if (id_phys->phys_connector[1] == 'E')
 ^
   drivers/scsi/hpsa.c:3240:2: error: expected declaration specifiers before 
'else'
 else
 ^
   drivers/scsi/hpsa.c:3243:2: error: expected declaration specifiers before 
'rc'
 rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
 ^
   drivers/scsi/hpsa.c:3245:2: error: expected declaration specifiers before 
'if'
 if (rc)
 ^
   drivers/scsi/hpsa.c:3248:2: error: expected declaration specifiers before 
'ei'
 ei = c->err_info;
 ^
   drivers/scsi/hpsa.c:3249:2: error: expected declaration specifiers before 
'if'
 if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
 ^
   drivers/scsi/hpsa.c:3254:2: error: expected declaration specifiers before 
'encl_dev'
 encl_dev->box[id_phys->active_path_number] = bssbp->phys_box_on_port;
 ^
   In file included from include/linux/string.h:17:0,
from include/linux/bitmap.h:8,
from include/linux/nodemask.h:92,
from include/linux/mmzone.h:16,
from include/linux/gfp.h:5,
from include/linux/kmod.h:22,
from include/linux/module.h:13,
from drivers/scsi/hpsa.c:19:
>> arch/alpha/include/asm/string.h:21:16: error: expected declaration 
>&

Re: [PATCH 1/1] mvsas: add SGPIO support to Marvell 94xx

2015-12-21 Thread Martin K. Petersen
> "Wilfried" == Wilfried Weissmann  writes:

Wilfried,

Wilfried> add SGPIO support to Marvell 94xx

Does not apply to current tree. Please rebase on top of:

http://git.kernel.org/cgit/linux/kernel/git/mkp/scsi.git/log/?h=4.5/scsi-queue

Thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 06/77] ncr5380: Remove NCR5380_instance_name macro

2015-12-21 Thread Finn Thain
This macro makes the code cryptic. Remove it.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |2 +-
 drivers/scsi/g_NCR5380.c |7 ---
 drivers/scsi/g_NCR5380.h |2 --
 3 files changed, 5 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:15:30.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:15:34.0 +1100
@@ -412,10 +412,11 @@ static int __init generic_NCR5380_detect
continue;
}
 
-   instance->NCR5380_instance_name = 
overrides[current_override].NCR5380_map_name;
 #ifndef SCSI_G_NCR5380_MEM
+   instance->io_port = 
overrides[current_override].NCR5380_map_name;
instance->n_io_port = region_size;
 #else
+   instance->base = overrides[current_override].NCR5380_map_name;
((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
 #endif
 
@@ -464,10 +465,10 @@ static int generic_NCR5380_release_resou
NCR5380_exit(instance);
 
 #ifndef SCSI_G_NCR5380_MEM
-   release_region(instance->NCR5380_instance_name, instance->n_io_port);
+   release_region(instance->io_port, instance->n_io_port);
 #else
iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-   release_mem_region(instance->NCR5380_instance_name, 
NCR5380_region_size);
+   release_mem_region(instance->base, NCR5380_region_size);
 #endif
 
 
Index: linux/drivers/scsi/g_NCR5380.h
===
--- linux.orig/drivers/scsi/g_NCR5380.h 2015-12-22 12:15:30.0 +1100
+++ linux/drivers/scsi/g_NCR5380.h  2015-12-22 12:15:34.0 +1100
@@ -36,7 +36,6 @@
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR5380_instance_name io_port
 #define NCR53C400_register_offset 0
 #define NCR53C400_address_adjust 8
 
@@ -58,7 +57,6 @@
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR5380_instance_name base
 #define NCR53C400_register_offset 0x108
 #define NCR53C400_address_adjust 0
 #define NCR53C400_mem_base 0x3880
Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:30.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:34.0 +1100
@@ -790,7 +790,7 @@ static int NCR5380_init(struct Scsi_Host
 
 #ifdef NCR53C400
if (flags & FLAG_NCR53C400)
-   instance->NCR5380_instance_name += NCR53C400_address_adjust;
+   instance->io_port += NCR53C400_address_adjust;
 #endif
 
hostdata->aborted = 0;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 14/77] ncr5380: Use return instead of goto in NCR5380_select()

2015-12-21 Thread Finn Thain
The "failed" label in NCR5380_select() is not helpful. Some failures
return 0, others -1. Use return instead of goto to improve clarity and
brevity, like atari_NCR5380.c does. Fix the relevant comments.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |   30 --
 drivers/scsi/atari_NCR5380.c |6 +++---
 2 files changed, 11 insertions(+), 25 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:46.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:47.0 +1100
@@ -997,16 +997,6 @@ static void NCR5380_main(struct work_str
 */
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, 
"scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", 
instance->host_no, tmp->device->id, tmp->device->lun);

-   /*
-* A successful selection is defined as 
one that 
-* leaves us with the command connected 
and 
-* in hostdata->connected, OR has 
terminated the
-* command.
-*
-* With successful commands, we fall 
through
-* and see if we can do an information 
transfer,
-* with failures we will restart.
-*/
hostdata->selecting = NULL;
/* RvC: have to preset this to indicate 
a new command is being performed */
 
@@ -1162,9 +1152,10 @@ static irqreturn_t NCR5380_intr(int dumm
  * Inputs : instance - instantiation of the 5380 driver on which this 
  *  target lives, cmd - SCSI command to execute.
  * 
- * Returns : -1 if selection could not execute for some reason,
- *  0 if selection succeeded or failed because the target 
- *  did not respond.
+ * Returns : -1 if selection failed but should be retried.
+ *  0 if selection failed and should not be retried.
+ *  0 if selection succeeded completely (hostdata->connected == cmd).
+ *  0 if selection in progress (hostdata->selecting == cmd).
  *
  * Side effects : 
  *  If bus busy, arbitration failed, etc, NCR5380_select() will exit 
@@ -1224,7 +1215,7 @@ static int NCR5380_select(struct Scsi_Ho
printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", 
__LINE__);
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   goto failed;
+   return -1;
}
 
dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", 
instance->host_no);
@@ -1242,7 +1233,7 @@ static int NCR5380_select(struct Scsi_Ho
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || 
(NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || 
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, 
deasserting MR_ARBITRATE\n", instance->host_no);
-   goto failed;
+   return -1;
}
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
 
@@ -1255,7 +1246,7 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, 
deasserting ICR_ASSERT_SEL\n", instance->host_no);
-   goto failed;
+   return -1;
}
/* 
 * Again, bus clear + bus settle time is 1.2us, however, this is 
@@ -1412,7 +1403,7 @@ part2:
if(err) {
printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", 
instance->host_no, __LINE__);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   goto failed;
+   return -1;
}
 
dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into 
MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
@@ -1433,11 +1424,6 @@ part2:
initialize_SCp(cmd);
 
return 0;
-
-   /* Selection failed */
-failed:
-   return -1;
-
 }
 
 /* 
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:46.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:47.0 +1100
@@ -1382,9 +1382,9 @@ static irqreturn_t 

[PATCH v3 10/77] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT

2015-12-21 Thread Finn Thain
The atari_NCR5380.c core driver now takes care of bus reset upon driver
initialization if required (same as NCR5380.c). Move the Toshiba CD-ROM
support into the core driver, enabled with a host flag, so that all
NCR5380 drivers can make use of it.

Drop the RESET_BOOT macros and the ATARI_SCSI_RESET_BOOT and 
ATARI_SCSI_TOSHIBA_DELAY Kconfig symbols, which are now redundant.

Remove the atari_scsi_reset_boot(), mac_scsi_reset_boot() and
sun3_scsi_reset_boot() routines. None of this duplicated code is needed
now that all drivers can use NCR5380_maybe_reset_bus().

This brings atari_scsi, mac_scsi and sun3_scsi into line with all of the
other NCR5380 drivers.

The bus reset may raise an interrupt. That would be new behaviour for
atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt
is not assigned to atari_scsi at this stage, so
CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
Regardless, do_reset() now raises and clears the interrupt within
local_irq_save/restore which should avoid problems.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---

Changed since v1:
- Fixed minor inconsistency in mac5380= usage message.

---
 drivers/scsi/Kconfig |   17 ---
 drivers/scsi/NCR5380.c   |   17 +--
 drivers/scsi/NCR5380.h   |1 
 drivers/scsi/atari_NCR5380.c |   22 +-
 drivers/scsi/atari_scsi.c|   60 +--
 drivers/scsi/mac_scsi.c  |   65 ++-
 drivers/scsi/sun3_scsi.c |   47 ---
 7 files changed, 51 insertions(+), 178 deletions(-)

Index: linux/drivers/scsi/Kconfig
===
--- linux.orig/drivers/scsi/Kconfig 2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/Kconfig  2015-12-22 12:15:41.0 +1100
@@ -1618,23 +1618,6 @@ config ATARI_SCSI
  ST-DMA, replacing ACSI).  It does NOT support other schemes, like
  in the Hades (without DMA).
 
-config ATARI_SCSI_TOSHIBA_DELAY
-   bool "Long delays for Toshiba CD-ROMs"
-   depends on ATARI_SCSI
-   help
- This option increases the delay after a SCSI arbitration to
- accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
- use a Toshiba CD-ROM drive; otherwise, the option is not needed and
- would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
-   bool "Reset SCSI-devices at boottime"
-   depends on ATARI_SCSI
-   help
- Reset the devices on your Atari whenever it boots.  This makes the
- boot process fractionally longer but may assist recovery from errors
- that leave the devices with SCSI operations partway completed.
-
 config MAC_SCSI
tristate "Macintosh NCR5380 SCSI"
depends on MAC && SCSI=y
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:39.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:41.0 +1100
@@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Hos
 "base 0x%lx, irq %d, "
 "can_queue %d, cmd_per_lun %d, "
 "sg_tablesize %d, this_id %d, "
-"flags { %s}, "
+"flags { %s%s}, "
 "options { %s} ",
 instance->hostt->name, instance->io_port, instance->n_io_port,
 instance->base, instance->irq,
 instance->can_queue, instance->cmd_per_lun,
 instance->sg_tablesize, instance->this_id,
 hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
+hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
 #ifdef DIFFERENTIAL
 "DIFFERENTIAL "
 #endif
@@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Sc
 
 static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
 {
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
int pass;
 
for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; 
++pass) {
@@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struc
case 4:
shost_printk(KERN_ERR, instance, "bus busy, attempting 
reset\n");
do_reset(instance);
+   /* Wait after a reset; the SCSI standard calls for
+* 250ms, we wait 500ms to be on the safe side.
+* But some Toshiba CD-ROMs need ten times that.
+*/
+   if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+   msleep(2500);
+   else
+   msleep(500);
break;

[PATCH v3 09/77] atari_NCR5380: Reset bus on driver initialization if required

2015-12-21 Thread Finn Thain
Merge the bus reset code from NCR5380.c into atari_NCR5380.c. This allows
for removal of a lot of duplicated code conditional on the RESET_BOOT
macro (in the next patch).

The atari_NCR5380.c fork lacks the do_reset() and NCR5380_poll_politely()
routines from NCR5380.c, so introduce them. They are indispensible. Keep
the two implementations in sync.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |   33 +++-
 drivers/scsi/atari_NCR5380.c |  113 +++
 2 files changed, 134 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:38.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:39.0 +1100
@@ -838,19 +838,20 @@ static int NCR5380_maybe_reset_bus(struc
case 1:
case 3:
case 5:
-   printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to 
five seconds\n", instance->host_no);
-   NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 
5*HZ);
+   shost_printk(KERN_ERR, instance, "SCSI bus busy, 
waiting up to five seconds\n");
+   NCR5380_poll_politely(instance,
+ STATUS_REG, SR_BSY, 0, 5 * HZ);
break;
case 2:
-   printk(KERN_WARNING "scsi%d: bus busy, attempting 
abort\n", instance->host_no);
+   shost_printk(KERN_ERR, instance, "bus busy, attempting 
abort\n");
do_abort(instance);
break;
case 4:
-   printk(KERN_WARNING "scsi%d: bus busy, attempting 
reset\n", instance->host_no);
+   shost_printk(KERN_ERR, instance, "bus busy, attempting 
reset\n");
do_reset(instance);
break;
case 6:
-   printk(KERN_ERR "scsi%d: bus locked solid or invalid 
override\n", instance->host_no);
+   shost_printk(KERN_ERR, instance, "bus locked solid\n");
return -ENXIO;
}
}
@@ -1579,21 +1580,29 @@ static int NCR5380_transfer_pio(struct S
 }
 
 /**
- * do_reset-   issue a reset command
- * @host: adapter to reset
+ * do_reset - issue a reset command
+ * @instance: adapter to reset
  *
- * Issue a reset sequence to the NCR5380 and try and get the bus
- * back into sane shape.
+ * Issue a reset sequence to the NCR5380 and try and get the bus
+ * back into sane shape.
  *
- * Locks: caller holds queue lock
+ * This clears the reset interrupt flag because there may be no handler for
+ * it. When the driver is initialized, the NCR5380_intr() handler has not yet
+ * been installed. And when in EH we may have released the ST DMA interrupt.
  */
  
 static void do_reset(struct Scsi_Host *instance)
 {
-   NCR5380_write(TARGET_COMMAND_REG, 
PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
+   unsigned long flags;
+
+   local_irq_save(flags);
+   NCR5380_write(TARGET_COMMAND_REG,
+ PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-   udelay(25);
+   udelay(50);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+   (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+   local_irq_restore(flags);
 }
 
 /*
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:14:49.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:39.0 +1100
@@ -234,6 +234,9 @@
 #defineHOSTNO  instance->host_no
 #defineH_NO(cmd)   (cmd)->device->host->host_no
 
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
+
 #ifdef SUPPORT_TAGS
 
 /*
@@ -475,6 +478,47 @@ static inline void initialize_SCp(struct
}
 }
 
+/**
+ * NCR5380_poll_politely - wait for NCR5380 status bits
+ * @instance: controller to poll
+ * @reg: 5380 register to poll
+ * @bit: Bitmask to check
+ * @val: Value required to exit
+ *
+ * Polls the NCR5380 in a reasonably efficient manner waiting for
+ * an event to occur, after a short quick poll we begin giving the
+ * CPU back in non IRQ contexts
+ *
+ * Returns the value of the register or a negative error code.
+ */
+
+static int NCR5380_poll_politely(struct Scsi_Host *instance,
+ int reg, int bit, int val, int t)
+{
+   int n = 500;
+   unsigned long end = jiffies + t;
+   int r;
+
+   while (n-- > 0) {
+   r = 

[PATCH v3 13/77] ncr5380: Remove redundant register writes

2015-12-21 Thread Finn Thain
Remove the duplicate write to the Select Enable Register that appeared
in v1.1.38.

Also remove the redundant write to Initiator Command Register prior to
calling do_abort().

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |2 --
 drivers/scsi/atari_NCR5380.c |3 ---
 2 files changed, 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:44.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:46.0 +1100
@@ -1384,7 +1384,6 @@ part2:
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond 
within 250ms\n", instance->host_no);
-   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return 0;
}
hostdata->targets_present |= (1 << scmd_id(cmd));
@@ -2076,7 +2075,6 @@ static void NCR5380_information_transfer
scmd_printk(KERN_INFO, cmd,
"switching to slow 
handshake\n");
cmd->device->borken = 1;
-   
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:44.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:46.0 +1100
@@ -1640,7 +1640,6 @@ static int NCR5380_select(struct Scsi_Ho
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond 
within 250ms\n", HOSTNO);
-   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return 0;
}
 
@@ -2192,8 +2191,6 @@ static void NCR5380_information_transfer
scmd_printk(KERN_INFO, cmd,
"switching to slow 
handshake\n");
cmd->device->borken = 1;
-   
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-   ICR_ASSERT_ATN);
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 11/77] ncr5380: Simplify bus reset handlers

2015-12-21 Thread Finn Thain
Make use of do_reset() in the bus reset handler in atari_NCR5380.c. The
version in NCR5380.c already does so. Keep them in sync.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---

Bus reset handlers in both core drivers still have serious problems for
EH purposes. Those problems are addressed later in this series.

---
 drivers/scsi/NCR5380.c   |   20 +++-
 drivers/scsi/atari_NCR5380.c |   30 --
 2 files changed, 23 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:41.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:43.0 +1100
@@ -668,7 +668,7 @@ static void prepare_info(struct Scsi_Hos
  * Locks: called functions disable irqs
  */
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
 {
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2693,24 +2693,26 @@ static int NCR5380_abort(struct scsi_cmn
 }
 
 
-/* 
- * Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd)
- * 
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
- * Locks: host lock taken by caller
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
struct Scsi_Host *instance = cmd->device->host;
 
+   spin_lock_irq(instance->host_lock);
+
+#if (NDEBUG & NDEBUG_ANY)
+   scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
NCR5380_print_status(instance);
+#endif
 
-   spin_lock_irq(instance->host_lock);
do_reset(instance);
+
spin_unlock_irq(instance->host_lock);
 
return SUCCESS;
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:41.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:43.0 +1100
@@ -719,7 +719,7 @@ static void lprint_Scsi_Cmnd(struct scsi
printk("\n");
 }
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
 {
struct NCR5380_hostdata *hostdata;
struct scsi_cmnd *ptr;
@@ -2982,13 +2982,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 }
 
 
-/*
- * Function : int NCR5380_reset (struct scsi_cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS or FAILURE
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
@@ -2998,22 +2996,19 @@ static int NCR5380_bus_reset(struct scsi
int i;
unsigned long flags;
 
+   local_irq_save(flags);
+
+#if (NDEBUG & NDEBUG_ANY)
+   scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
NCR5380_print_status(instance);
+#endif
+
+   do_reset(instance);
 
-   /* get in phase */
-   NCR5380_write(TARGET_COMMAND_REG,
- PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-   /* assert RST */
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-   udelay(40);
/* reset NCR registers */
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, 0);
-   /* ++roman: reset interrupt condition! otherwise no interrupts don't get
-* through anymore ... */
-   (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
/* After the reset, there are no more connected or disconnected commands
 * and no busy units; so clear the low-level status here to avoid
@@ -3028,7 +3023,6 @@ static int NCR5380_bus_reset(struct scsi
if (hostdata->disconnected_queue)
dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected 
command(s)\n", H_NO(cmd));
 
-   local_irq_save(flags);
hostdata->issue_queue = NULL;
hostdata->connected = NULL;
hostdata->disconnected_queue = NULL;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 07/77] ncr5380: Split NCR5380_init() into two functions

2015-12-21 Thread Finn Thain
This patch splits the NCR5380_init() function into two parts, similar
to the scheme used with atari_NCR5380.c. This avoids two problems.

Firstly, NCR5380_init() may perform a bus reset, which would cause the
chip to assert IRQ. The chip is unable to mask its bus reset interrupt.
Drivers can't call request_irq() before calling NCR5380_init(), because
initialization must happen before the interrupt handler executes. If
driver initialization causes an interrupt it may be problematic on some
platforms. To avoid that, first move the bus reset code into
NCR5380_maybe_reset_bus().

Secondly, NCR5380_init() contains some board-specific interrupt setup code
for the NCR53C400 that does not belong in the core driver. In moving this
code, better not re-order interrupt initialization and bus reset. Again,
the solution is to move the bus reset code into NCR5380_maybe_reset_bus().

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c  |   34 --
 drivers/scsi/NCR5380.h  |1 +
 drivers/scsi/arm/cumana_1.c |2 ++
 drivers/scsi/arm/oak.c  |2 ++
 drivers/scsi/dmx3191d.c |2 ++
 drivers/scsi/dtc.c  |2 ++
 drivers/scsi/g_NCR5380.c|2 ++
 drivers/scsi/pas16.c|2 ++
 drivers/scsi/t128.c |2 ++
 9 files changed, 35 insertions(+), 14 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:34.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:35.0 +1100
@@ -777,8 +777,7 @@ static void lprint_opcode(int opcode, st
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
-   int i, pass;
-   unsigned long timeout;
+   int i;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
 
if(in_interrupt())
@@ -831,18 +830,26 @@ static int NCR5380_init(struct Scsi_Host
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
}
 #endif
+   return 0;
+}
 
-   /* 
-* Detect and correct bus wedge problems.
-*
-* If the system crashed, it may have crashed in a state 
-* where a SCSI command was still executing, and the 
-* SCSI bus is not in a BUS FREE STATE.
-*
-* If this is the case, we'll try to abort the currently
-* established nexus which we know nothing about, and that
-* failing, do a hard reset of the SCSI bus 
-*/
+/**
+ * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
+ * @instance: adapter to check
+ *
+ * If the system crashed, it may have crashed with a connected target and
+ * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
+ * currently established nexus, which we know nothing about. Failing that
+ * do a bus reset.
+ *
+ * Note that a bus reset will cause the chip to assert IRQ.
+ *
+ * Returns 0 if successful, otherwise -ENXIO.
+ */
+
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
+{
+   int pass;
 
for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; 
++pass) {
switch (pass) {
@@ -850,7 +857,6 @@ static int NCR5380_init(struct Scsi_Host
case 3:
case 5:
printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to 
five seconds\n", instance->host_no);
-   timeout = jiffies + 5 * HZ;
NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 
5*HZ);
break;
case 2:
Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:15:28.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:15:35.0 +1100
@@ -318,6 +318,7 @@ static void NCR5380_print(struct Scsi_Ho
 static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
 #endif
 static int NCR5380_init(struct Scsi_Host *instance, int flags);
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
 static void NCR5380_exit(struct Scsi_Host *instance);
 static void NCR5380_information_transfer(struct Scsi_Host *instance);
 #ifndef DONT_USE_INTR
Index: linux/drivers/scsi/arm/cumana_1.c
===
--- linux.orig/drivers/scsi/arm/cumana_1.c  2015-12-22 12:15:30.0 
+1100
+++ linux/drivers/scsi/arm/cumana_1.c   2015-12-22 12:15:35.0 +1100
@@ -240,6 +240,8 @@ static int cumanascsi1_probe(struct expa
 
NCR5380_init(host, 0);
 
+   NCR5380_maybe_reset_bus(host);
+
 priv(host)->ctrl = 0;
 writeb(0, priv(host)->base + CTRL);
 
Index: linux/drivers/scsi/arm/oak.c
===
--- 

[PATCH v3 15/77] ncr5380: Always escalate bad target time-out in NCR5380_select()

2015-12-21 Thread Finn Thain
Remove the restart_select and targets_present variables introduced in
Linux v1.1.38. The former was used only for a questionable debug printk
and the latter "so we can call a select failure a retryable condition".
Well, retrying select failure in general is a different problem to a
target that doesn't assert BSY. We need to handle these two cases
differently; the latter case can be left to the SCSI ML.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |   13 -
 drivers/scsi/NCR5380.h   |6 --
 drivers/scsi/atari_NCR5380.c |   13 -
 3 files changed, 32 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:47.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:48.0 +1100
@@ -790,7 +790,6 @@ static int NCR5380_init(struct Scsi_Host
 #ifdef REAL_DMA
hostdata->dmalen = 0;
 #endif
-   hostdata->targets_present = 0;
hostdata->connected = NULL;
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;
@@ -1186,8 +1185,6 @@ static int NCR5380_select(struct Scsi_Ho
if (hostdata->selecting)
goto part2;
 
-   hostdata->restart_select = 0;
-
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", 
instance->host_no, instance->this_id);
 
@@ -1363,21 +1360,12 @@ part2:
 
if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-   if (hostdata->targets_present & (1 << scmd_id(cmd))) {
-   printk(KERN_DEBUG "scsi%d : weirdness\n", 
instance->host_no);
-   if (hostdata->restart_select)
-   printk(KERN_DEBUG "\trestart select\n");
-   NCR5380_dprint(NDEBUG_SELECTION, instance);
-   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   return -1;
-   }
cmd->result = DID_BAD_TARGET << 16;
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond 
within 250ms\n", instance->host_no);
return 0;
}
-   hostdata->targets_present |= (1 << scmd_id(cmd));
 
/*
 * Since we followed the SCSI spec, and raised ATN while SEL 
@@ -2382,7 +2370,6 @@ static void NCR5380_reselect(struct Scsi
 */
 
NCR5380_write(MODE_REG, MR_BASE);
-   hostdata->restart_select = 1;
 
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & 
~(hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:47.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:48.0 +1100
@@ -826,7 +826,6 @@ static int __init NCR5380_init(struct Sc
 #if defined (REAL_DMA)
hostdata->dma_len = 0;
 #endif
-   hostdata->targets_present = 0;
hostdata->connected = NULL;
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;
@@ -1409,7 +1408,6 @@ static int NCR5380_select(struct Scsi_Ho
unsigned long timeout;
unsigned long flags;
 
-   hostdata->restart_select = 0;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", 
HOSTNO,
   instance->this_id);
@@ -1625,14 +1623,6 @@ static int NCR5380_select(struct Scsi_Ho
 
if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-   if (hostdata->targets_present & (1 << cmd->device->id)) {
-   printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
-   if (hostdata->restart_select)
-   printk(KERN_NOTICE "\trestart select\n");
-   NCR5380_dprint(NDEBUG_ANY, instance);
-   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   return -1;
-   }
cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
@@ -1643,8 +1633,6 @@ static int NCR5380_select(struct Scsi_Ho
return 0;
}
 
-   hostdata->targets_present |= (1 << cmd->device->id);
-
/*
 * Since we followed the SCSI spec, and raised ATN while SEL
 * was true but before BSY was false during selection, the information
@@ -2605,7 +2593,6 @@ static void NCR5380_reselect(struct 

[PATCH v3 12/77] ncr5380: Remove unused hostdata->aborted flag

2015-12-21 Thread Finn Thain
The aborted flag was introduced in v1.1.38 but never used. Remove it.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |2 --
 drivers/scsi/NCR5380.h   |1 -
 drivers/scsi/atari_NCR5380.c |2 --
 3 files changed, 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:43.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:44.0 +1100
@@ -781,7 +781,6 @@ static int NCR5380_init(struct Scsi_Host
if(in_interrupt())
printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
 
-   hostdata->aborted = 0;
hostdata->id_mask = 1 << instance->this_id;
for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
if (i > hostdata->id_mask)
@@ -2574,7 +2573,6 @@ static int NCR5380_abort(struct scsi_cmn
 
if (hostdata->connected == cmd) {
dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", 
instance->host_no);
-   hostdata->aborted = 1;
 /*
  * We should perform BSY checking, and make sure we haven't slipped
  * into BUS FREE.
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:43.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:44.0 +1100
@@ -813,7 +813,6 @@ static int __init NCR5380_init(struct Sc
SETUP_HOSTDATA(instance);
 
hostdata->host = instance;
-   hostdata->aborted = 0;
hostdata->id_mask = 1 << instance->this_id;
hostdata->id_higher_mask = 0;
for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
@@ -2834,7 +2833,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 */
 
if (do_abort(instance) == 0) {
-   hostdata->aborted = 1;
hostdata->connected = NULL;
cmd->result = DID_ABORT << 16;
 #ifdef SUPPORT_TAGS
Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:15:41.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:15:44.0 +1100
@@ -271,7 +271,6 @@ struct NCR5380_hostdata {
volatile int restart_select;/* we have disconnected,
   used to restart 
   NCR5380_select() */
-   volatile unsigned aborted:1;/* flag, says aborted */
int flags;
unsigned long time_expires; /* in jiffies, set prior to 
sleeping */
int select_time;/* timer in select for target 
response */


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 17/77] ncr5380: Keep BSY asserted when entering SELECTION phase

2015-12-21 Thread Finn Thain
NCR5380.c is not compliant with the SCSI-2 standard (at least, not with
the draft revision 10L that I have to refer to). The selection algorithm
in atari_NCR5380.c is correct, so use that.

Signed-off-by: Finn Thain 

---

The NCR 5380 Family datasheet has a flow chart to support this. Please see
http://pdf.datasheetarchive.com/indexerfiles/Scans-001/Scans-0031883.pdf

This is another old bug fix that was unfortunately never applied to the
original NCR5380.c core driver.

---
 drivers/scsi/NCR5380.c   |8 +++-
 drivers/scsi/atari_NCR5380.c |7 ---
 2 files changed, 11 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:50.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:51.0 +1100
@@ -1236,7 +1236,13 @@ static int NCR5380_select(struct Scsi_Ho
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, 
deasserting MR_ARBITRATE\n", instance->host_no);
return -1;
}
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
+
+   /* After/during arbitration, BSY should be asserted.
+* IBM DPES-31080 Version S31Q works now
+* Tnx to thomas_roe...@m2.maus.de for finding this! (Roman)
+*/
+   NCR5380_write(INITIATOR_COMMAND_REG,
+ ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
if (!(hostdata->flags & FLAG_DTC3181E) &&
/* RvC: DTC3181E has some trouble with this
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:50.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:51.0 +1100
@@ -1480,9 +1480,10 @@ static int NCR5380_select(struct Scsi_Ho
return -1;
}
 
-   /* after/during arbitration, BSY should be asserted.
-  IBM DPES-31080 Version S31Q works now */
-   /* Tnx to thomas_roe...@m2.maus.de for finding this! (Roman) */
+   /* After/during arbitration, BSY should be asserted.
+* IBM DPES-31080 Version S31Q works now
+* Tnx to thomas_roe...@m2.maus.de for finding this! (Roman)
+*/
NCR5380_write(INITIATOR_COMMAND_REG,
  ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 16/77] ncr5380: Proceed with next command after NCR5380_select() calls scsi_done

2015-12-21 Thread Finn Thain
If a target disappears from the SCSI bus, NCR5380_select() may
subsequently fail with a time-out. In this situation, scsi_done is
called and NCR5380_select() returns 0. Both hostdata->connected and
hostdata->selecting are NULL and the main loop should proceed with
the next command in the issue queue. Clarify this logic.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---

Good code style would be,

if (this) {
/* do stuff */
}

rather than,

if (!this) {
} else {
/* do stuff */
}

But I've used the latter form at this point in the series for a cleaner
diff between NCR5380.c and atari_NC5380.c, making it easier to gradually
reduce discrepancies. Code style gets fixed up along the way.

---
 drivers/scsi/NCR5380.c   |8 ++--
 drivers/scsi/atari_NCR5380.c |8 
 2 files changed, 10 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:48.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:50.0 +1100
@@ -1007,14 +1007,18 @@ static void NCR5380_main(struct work_str
 */
 
if (!NCR5380_select(instance, tmp)) {
-   break;
+   /* OK or bad target */
} else {
+   /* Need to retry */
LIST(tmp, 
hostdata->issue_queue);
tmp->host_scribble = (unsigned 
char *) hostdata->issue_queue;
hostdata->issue_queue = tmp;
done = 0;

dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned 
to issue_queue\n", instance->host_no);
}
+   if (hostdata->connected ||
+   hostdata->selecting)
+   break;
/* lock held here still */
}   /* if target/lun is not busy */
}   /* for */
@@ -1024,7 +1028,7 @@ static void NCR5380_main(struct work_str
tmp = (struct scsi_cmnd *) hostdata->selecting;
/* Selection will drop and retake the lock */
if (!NCR5380_select(instance, tmp)) {
-   /* Ok ?? */
+   /* OK or bad target */
} else {
/* RvC: device failed, so we wait a long time
   this is needed for Mustek scanners, that
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:15:48.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:15:50.0 +1100
@@ -1139,13 +1139,13 @@ static void NCR5380_main(struct work_str
cmd_get_tag(tmp, tmp->cmnd[0] != 
REQUEST_SENSE);
 #endif
if (!NCR5380_select(instance, tmp)) {
+   /* OK or bad target */
local_irq_disable();
hostdata->retain_dma_intr--;
-   /* release if target did not 
response! */
maybe_release_dma_irq(instance);
local_irq_restore(flags);
-   break;
} else {
+   /* Need to retry */
local_irq_disable();
LIST(tmp, 
hostdata->issue_queue);
SET_NEXT(tmp, 
hostdata->issue_queue);
@@ -1157,9 +1157,9 @@ static void NCR5380_main(struct work_str
local_irq_restore(flags);
dprintk(NDEBUG_MAIN, "scsi%d: 
main(): select() failed, "
"returned to 
issue_queue\n", HOSTNO);
-   if (hostdata->connected)
-   break;
   

[PATCH v3 18/77] ncr5380: Eliminate USLEEP_WAITLONG delay

2015-12-21 Thread Finn Thain
Linux 2.1.105 introduced the USLEEP_WAITLONG delay, apparently "needed for
Mustek scanners". It is intended to stall the issue queue for 5 seconds.
There are a number of problems with this.

1. Only g_NCR5380 enables the delay, which implies that the other five
   drivers using the NCR5380.c core driver remain incompatible with
   Mustek scanners.

2. The delay is not implemented by atari_NCR5380.c, which is problematic
   for re-unifying the two core driver forks.

3. The delay is implemented using NCR5380_set_timer() which makes it
   unreliable. A new command queued by the mid-layer cancels the delay.

4. The delay is applied indiscriminately in several situations in which
   NCR5380_select() returns -1. These are-- reselection by the target,
   failure of the target to assert BSY, and failure of the target to
   assert REQ. It's clear from the comments that USLEEP_WAITLONG is not
   relevant to the reselection case. And reportedly, these scanners do
   not disconnect.

5. atari_NCR5380.c was forked before Linux 2.1.105, so it was spared some
   of the damage done to NCR5380.c. In this case, the atari_NCR5380.c core
   driver was more standard-compliant and may not have needed any
   workaround like the USLEEP_WAITLONG kludge. The compliance issue was
   addressed in the previous patch.

If these scanners still don't work, we need a better solution. Retrying
selection until EH aborts a command offers equivalent robustness. Bugs in
the existing driver prevent EH working correctly but this is addressed in
a subsequent patch. Remove USLEEP_WAITLONG.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   19 +--
 drivers/scsi/g_NCR5380.c |1 -
 2 files changed, 5 insertions(+), 15 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:51.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:52.0 +1100
@@ -468,10 +468,6 @@ static void NCR5380_print_phase(struct S
 #ifndef USLEEP_POLL
 #define USLEEP_POLL msecs_to_jiffies(200)
 #endif
-#ifndef USLEEP_WAITLONG
-/* RvC: (reasonable time to wait on select error) */
-#define USLEEP_WAITLONG USLEEP_SLEEP
-#endif
 
 /* 
  * Function : int should_disconnect (unsigned char cmd)
@@ -619,8 +615,8 @@ static void prepare_info(struct Scsi_Hos
 "can_queue %d, cmd_per_lun %d, "
 "sg_tablesize %d, this_id %d, "
 "flags { %s%s%s%s}, "
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-"USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
+#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
+"USLEEP_POLL %lu, USLEEP_SLEEP %lu, "
 #endif
 "options { %s} ",
 instance->hostt->name, instance->io_port, instance->n_io_port,
@@ -631,8 +627,8 @@ static void prepare_info(struct Scsi_Hos
 hostdata->flags & FLAG_DTC3181E  ? "DTC3181E "  : "",
 hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-USLEEP_POLL, USLEEP_WAITLONG,
+#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
+USLEEP_POLL, USLEEP_SLEEP,
 #endif
 #ifdef AUTOPROBE_IRQ
 "AUTOPROBE_IRQ "
@@ -1030,15 +1026,10 @@ static void NCR5380_main(struct work_str
if (!NCR5380_select(instance, tmp)) {
/* OK or bad target */
} else {
-   /* RvC: device failed, so we wait a long time
-  this is needed for Mustek scanners, that
-  do not respond to commands immediately
-  after a scan */
-   printk(KERN_DEBUG "scsi%d: device %d did not 
respond in time\n", instance->host_no, tmp->device->id);
LIST(tmp, hostdata->issue_queue);
tmp->host_scribble = (unsigned char *) 
hostdata->issue_queue;
hostdata->issue_queue = tmp;
-   NCR5380_set_timer(hostdata, USLEEP_WAITLONG);
+   done = 0;
}
}   /* if hostdata->selecting */
if (hostdata->connected
Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:15:38.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:15:52.0 +1100
@@ -59,7 +59,6 @@
 /* settings for DTC3181E card with only Mustek scanner attached */
 #define USLEEP_POLLmsecs_to_jiffies(10)
 #define USLEEP_SLEEP   msecs_to_jiffies(200)
-#define 

[PATCH v3 50/77] ncr5380: Change instance->host_lock to hostdata->lock

2015-12-21 Thread Finn Thain
NCR5380.c presently uses the instance->host_lock spin lock. Convert this
to a new spin lock that protects the NCR5380_hostdata struct.

atari_NCR5380.c previously used local_irq_save/restore() rather than a
spin lock. Convert this to hostdata->lock in irq mode. For SMP platforms,
the interrupt handler now also acquires the spin lock.

This brings all locking in the two core drivers into agreement.

Adding this locking also means that a bunch of volatile qualifiers can be
removed from the members of the NCR5380_hostdata struct. This is done in
a subsequent patch.

Proper locking will allow the abort handler to locate a command being
aborted. This is presently impossible if the abort handler is invoked when
the command has been moved from a queue to a pointer on the stack. (If
eh_abort_handler can't determine whether a command has been completed
or is still being processed then it can't decide whether to return
success or failure.)

The hostdata spin lock is now held when calling NCR5380_select() and
NCR5380_information_transfer(). Where possible, the lock is dropped for
polling and PIO transfers.

Clean up the now-redundant SELECT_ENABLE_REG writes, that used to provide
limited mutual exclusion between information_transfer() and reselect().

Accessing hostdata->connected without data races means taking the lock;
cleanup these accesses.

The new spin lock falls away for m68k and other UP builds, so this should
have little impact there. In the SMP case the new lock should be
uncontested even when the SCSI bus is contested.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   82 --
 drivers/scsi/NCR5380.h   |1 
 drivers/scsi/atari_NCR5380.c |  135 +--
 3 files changed, 109 insertions(+), 109 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:45.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:47.0 +1100
@@ -256,6 +256,7 @@ struct NCR5380_hostdata {
volatile struct scsi_cmnd *connected;   /* currently connected command 
*/
volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */
volatile struct scsi_cmnd *disconnected_queue;  /* waiting for 
reconnect */
+   spinlock_t lock;/* protects this struct */
int flags;
struct scsi_eh_save ses;
char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:45.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:47.0 +1100
@@ -546,15 +546,13 @@ static struct {
 static void NCR5380_print(struct Scsi_Host *instance)
 {
unsigned char status, data, basr, mr, icr, i;
-   unsigned long flags;
 
-   local_irq_save(flags);
data = NCR5380_read(CURRENT_SCSI_DATA_REG);
status = NCR5380_read(STATUS_REG);
mr = NCR5380_read(MODE_REG);
icr = NCR5380_read(INITIATOR_COMMAND_REG);
basr = NCR5380_read(BUS_AND_STATUS_REG);
-   local_irq_restore(flags);
+
printk("STATUS_REG: %02x ", status);
for (i = 0; signals[i].mask; ++i)
if (status & signals[i].mask)
@@ -684,14 +682,12 @@ static void __maybe_unused NCR5380_print
 {
struct NCR5380_hostdata *hostdata;
struct scsi_cmnd *ptr;
-   unsigned long flags;
 
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-   local_irq_save(flags);
if (!hostdata->connected)
printk("scsi%d: no currently connected command\n", HOSTNO);
else
@@ -704,8 +700,6 @@ static void __maybe_unused NCR5380_print
for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
 ptr = NEXT(ptr))
lprint_Scsi_Cmnd(ptr);
-
-   local_irq_restore(flags);
printk("\n");
 }
 
@@ -732,7 +726,7 @@ static int __maybe_unused NCR5380_show_i
 
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-   local_irq_save(flags);
+   spin_lock_irqsave(>lock, flags);
if (!hostdata->connected)
seq_printf(m, "scsi%d: no currently connected command\n", 
HOSTNO);
else
@@ -746,7 +740,7 @@ static int __maybe_unused NCR5380_show_i
 ptr = NEXT(ptr))
show_Scsi_Cmnd(ptr, m);
 
-   local_irq_restore(flags);
+   spin_unlock_irqrestore(>lock, flags);
return 0;
 }
 
@@ -784,6 +778,7 @@ static int __init NCR5380_init(struct Sc
 #if defined (REAL_DMA)
hostdata->dma_len = 0;
 #endif
+   spin_lock_init(>lock);
hostdata->connected = NULL;
hostdata->issue_queue = NULL;

[PATCH v3 66/77] ncr5380: Fix soft lockups

2015-12-21 Thread Finn Thain
Because of the rudimentary design of the chip, it is necessary to poll the
SCSI bus signals during PIO and this tends to hog the CPU. The driver will
accept new commands while others execute, and this causes a soft lockup
because the workqueue item will not terminate until the issue queue is
emptied.

When exercising dmx3191d using sequential IO from dd, the driver is sent
512 KiB WRITE commands and 128 KiB READs. For a PIO transfer, the rate is
is only about 300 KiB/s, so these are long-running commands. And although
PDMA may run at several MiB/s, interrupts are disabled for the duration
of the transfer.

Fix the unresponsiveness and soft lockup issues by calling cond_resched()
after each command is completed and by limiting max_sectors for drivers
that don't implement real DMA.

Signed-off-by: Finn Thain 

---

Changed since v2:
- Moved max_sectors initialization to wrapper drivers. It isn't really
  relevant to the core driver and compile-time configuration using macros
  like REAL_DMA should be avoided.

---
 drivers/scsi/NCR5380.c   |6 --
 drivers/scsi/arm/cumana_1.c  |1 +
 drivers/scsi/arm/oak.c   |1 +
 drivers/scsi/atari_NCR5380.c |6 --
 drivers/scsi/dmx3191d.c  |1 +
 drivers/scsi/dtc.c   |1 +
 drivers/scsi/g_NCR5380.c |1 +
 drivers/scsi/mac_scsi.c  |1 +
 drivers/scsi/pas16.c |1 +
 drivers/scsi/t128.c  |1 +
 10 files changed, 16 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:12.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:15.0 +1100
@@ -890,10 +890,10 @@ static void NCR5380_main(struct work_str
struct scsi_cmnd *cmd;
int done;

-   spin_lock_irq(>lock);
do {
done = 1;
 
+   spin_lock_irq(>lock);
while (!hostdata->connected &&
   (cmd = dequeue_next_cmd(instance))) {
 
@@ -930,8 +930,10 @@ static void NCR5380_main(struct work_str
NCR5380_information_transfer(instance);
done = 0;
}
+   spin_unlock_irq(>lock);
+   if (!done)
+   cond_resched();
} while (!done);
-   spin_unlock_irq(>lock);
 }
 
 #ifndef DONT_USE_INTR
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:14.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:15.0 +1100
@@ -976,10 +976,10 @@ static void NCR5380_main(struct work_str
 * alter queues and touch the Falcon lock.
 */
 
-   spin_lock_irq(>lock);
do {
done = 1;
 
+   spin_lock_irq(>lock);
while (!hostdata->connected &&
   (cmd = dequeue_next_cmd(instance))) {
 
@@ -1026,8 +1026,10 @@ static void NCR5380_main(struct work_str
NCR5380_information_transfer(instance);
done = 0;
}
+   spin_unlock_irq(>lock);
+   if (!done)
+   cond_resched();
} while (!done);
-   spin_unlock_irq(>lock);
 }
 
 
Index: linux/drivers/scsi/arm/cumana_1.c
===
--- linux.orig/drivers/scsi/arm/cumana_1.c  2015-12-22 12:16:58.0 
+1100
+++ linux/drivers/scsi/arm/cumana_1.c   2015-12-22 12:17:15.0 +1100
@@ -209,6 +209,7 @@ static struct scsi_host_template cumanas
.use_clustering = DISABLE_CLUSTERING,
.proc_name  = "CumanaSCSI-1",
.cmd_size   = NCR5380_CMD_SIZE,
+   .max_sectors= 128,
 };
 
 static int cumanascsi1_probe(struct expansion_card *ec,
Index: linux/drivers/scsi/arm/oak.c
===
--- linux.orig/drivers/scsi/arm/oak.c   2015-12-22 12:16:58.0 +1100
+++ linux/drivers/scsi/arm/oak.c2015-12-22 12:17:15.0 +1100
@@ -115,6 +115,7 @@ static struct scsi_host_template oakscsi
.use_clustering = DISABLE_CLUSTERING,
.proc_name  = "oakscsi",
.cmd_size   = NCR5380_CMD_SIZE,
+   .max_sectors= 128,
 };
 
 static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
Index: linux/drivers/scsi/dmx3191d.c
===
--- linux.orig/drivers/scsi/dmx3191d.c  2015-12-22 12:16:58.0 +1100
+++ linux/drivers/scsi/dmx3191d.c   2015-12-22 12:17:15.0 +1100
@@ -62,6 +62,7 @@ static struct scsi_host_template dmx3191
.cmd_per_lun= 2,

[PATCH v3 58/77] ncr5380: Refactor command completion

2015-12-21 Thread Finn Thain
Implement a 'complete_cmd' function to complete commands. This is needed
by the following patch; the new function provides a site for the logic
needed to correctly handle REQUEST SENSE commands.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   31 ++--
 drivers/scsi/atari_NCR5380.c |   46 ---
 2 files changed, 55 insertions(+), 22 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:58.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:02.0 +1100
@@ -765,6 +765,27 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
+ * complete_cmd - finish processing a command and return it to the SCSI ML
+ * @instance: the host instance
+ * @cmd: command to complete
+ */
+
+static void complete_cmd(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
+{
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+   dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
+
+#ifdef SUPPORT_TAGS
+   cmd_free_tag(cmd);
+#else
+   hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+#endif
+   cmd->scsi_done(cmd);
+}
+
+/**
  * NCR5380_queue_command - queue a command
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
@@ -1352,10 +1373,7 @@ static int NCR5380_select(struct Scsi_Ho
spin_lock_irq(>lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
-#ifdef SUPPORT_TAGS
-   cmd_free_tag(cmd);
-#endif
-   cmd->scsi_done(cmd);
+   complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond 
within 250ms\n", HOSTNO);
return 0;
@@ -1866,7 +1884,7 @@ static void NCR5380_information_transfer
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
-   cmd->scsi_done(cmd);
+   complete_cmd(instance, cmd);
return;
 #endif
case PHASE_DATAIN:
@@ -1926,7 +1944,7 @@ static void NCR5380_information_transfer
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
-   cmd->scsi_done(cmd);
+   complete_cmd(instance, cmd);
/* XXX - need to source or sink 
data here, as appropriate */
} else {
 #ifdef REAL_DMA
@@ -1982,8 +2000,6 @@ static void NCR5380_information_transfer
if (ta->queue_size > 
ta->nr_allocated)
ta->queue_size = 
ta->nr_allocated;
}
-#else
-   hostdata->busy[cmd->device->id] &= ~(1 
<< cmd->device->lun);
 #endif
 
/*
@@ -2021,8 +2037,13 @@ static void NCR5380_information_transfer
dsprintk(NDEBUG_AUTOSENSE | 
NDEBUG_QUEUES,
 instance, "REQUEST 
SENSE cmd %p added to head of issue queue\n",
 cmd);
+#ifdef SUPPORT_TAGS
+   cmd_free_tag(cmd);
+#else
+   hostdata->busy[cmd->device->id] 
&= ~(1 << cmd->device->lun);
+#endif
} else {
-   cmd->scsi_done(cmd);
+   complete_cmd(instance, cmd);
}
 
/*
@@ -2193,15 +2214,10 @@ static void NCR5380_information_transfer
hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, , , 
);
if (msgout == ABORT) {
-#ifdef SUPPORT_TAGS
-   cmd_free_tag(cmd);
-#else
-   hostdata->busy[cmd->device->id] &= ~(1 
<< cmd->device->lun);
-#endif
hostdata->connected = NULL;
cmd->result = DID_ERROR << 16;
+   complete_cmd(instance, cmd);

[PATCH v3 56/77] ncr5380: Remove redundant volatile qualifiers

2015-12-21 Thread Finn Thain
The hostdata struct is now protected by a spin lock so the volatile
qualifiers are redundant. Remove them.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.h   |   12 ++--
 drivers/scsi/atari_NCR5380.c |2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:51.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:57.0 +1100
@@ -248,14 +248,14 @@ struct NCR5380_hostdata {
NCR5380_implementation_fields;  /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */
unsigned char id_mask, id_higher_mask;  /* 1 << id, all bits greater */
-   volatile unsigned char busy[8]; /* index = target, bit = lun */
+   unsigned char busy[8];  /* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-   volatile int dma_len;   /* requested length of DMA */
+   int dma_len;/* requested length of DMA */
 #endif
-   volatile unsigned char last_message;/* last message OUT */
-   volatile struct scsi_cmnd *connected;   /* currently connected command 
*/
-   volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */
-   volatile struct scsi_cmnd *disconnected_queue;  /* waiting for 
reconnect */
+   unsigned char last_message; /* last message OUT */
+   struct scsi_cmnd *connected;/* currently connected cmnd */
+   struct scsi_cmnd *issue_queue;  /* waiting to be issued */
+   struct scsi_cmnd *disconnected_queue;   /* waiting for reconnect */
spinlock_t lock;/* protects this struct */
int flags;
struct scsi_eh_save ses;
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:56.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:57.0 +1100
@@ -1009,7 +1009,7 @@ static void NCR5380_dma_complete(struct
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int transferred;
unsigned char **data;
-   volatile int *count;
+   int *count;
int saved_data = 0, overrun = 0;
unsigned char p;
 


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 59/77] ncr5380: Fix autosense bugs

2015-12-21 Thread Finn Thain
NCR5380_information_transfer() may re-queue a command for autosense,
after calling scsi_eh_prep_cmnd(). This creates several possibilities:

1. Reselection may intervene before the re-queued command gets processed.
   If the reconnected command then undergoes autosense, this causes the
   scsi_eh_save data from the previous command to be overwritten.

2. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
   a new REQUEST SENSE command may arrive. This would be queued ahead
   of any command already undergoing autosense, which means the
   scsi_eh_save data might be restored to the wrong command.

3. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
   eh_abort_handler() may abort the command. But the scsi_eh_save data is
   not discarded, which means the scsi_eh_save data might be incorrectly
   restored to the next REQUEST SENSE command issued.

This patch adds a new autosense list so that commands that are re-queued
because of a CHECK CONDITION result can be kept apart from the REQUEST
SENSE commands that arrive via queuecommand.

This patch also adds a function dedicated to dequeueing and preparing the
next command for processing. By refactoring the main loop in this way,
scsi_eh_save takes place when an autosense command is dequeued rather
than when re-queued.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  194 +++---
 drivers/scsi/NCR5380.h   |2 
 drivers/scsi/atari_NCR5380.c |  239 ---
 3 files changed, 249 insertions(+), 186 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:58.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:17:03.0 +1100
@@ -256,10 +256,12 @@ struct NCR5380_hostdata {
unsigned char last_message; /* last message OUT */
struct scsi_cmnd *connected;/* currently connected cmnd */
struct list_head unissued;  /* waiting to be issued */
+   struct list_head autosense; /* priority issue queue */
struct list_head disconnected;  /* waiting for reconnect */
spinlock_t lock;/* protects this struct */
int flags;
struct scsi_eh_save ses;
+   struct scsi_cmnd *sensing;
char info[256];
int read_overruns;/* number of bytes to cut from a
   * transfer to handle chip overruns */
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:02.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:03.0 +1100
@@ -418,6 +418,9 @@ static inline void initialize_SCp(struct
cmd->SCp.ptr = NULL;
cmd->SCp.this_residual = 0;
}
+
+   cmd->SCp.Status = 0;
+   cmd->SCp.Message = 0;
 }
 
 /**
@@ -661,6 +664,8 @@ static int __init NCR5380_init(struct Sc
 #endif
spin_lock_init(>lock);
hostdata->connected = NULL;
+   hostdata->sensing = NULL;
+   INIT_LIST_HEAD(>autosense);
INIT_LIST_HEAD(>unissued);
INIT_LIST_HEAD(>disconnected);
 
@@ -777,6 +782,16 @@ static void complete_cmd(struct Scsi_Hos
 
dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
 
+   if (hostdata->sensing == cmd) {
+   /* Autosense processing ends here */
+   if ((cmd->result & 0xff) != SAM_STAT_GOOD) {
+   scsi_eh_restore_cmnd(cmd, >ses);
+   set_host_byte(cmd, DID_ERROR);
+   } else
+   scsi_eh_restore_cmnd(cmd, >ses);
+   hostdata->sensing = NULL;
+   }
+
 #ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
 #else
@@ -868,12 +883,77 @@ static inline void maybe_release_dma_irq
/* Caller does the locking needed to set & test these data atomically */
if (list_empty(>disconnected) &&
list_empty(>unissued) &&
+   list_empty(>autosense) &&
!hostdata->connected &&
!hostdata->retain_dma_intr)
NCR5380_release_dma_irq(instance);
 }
 
 /**
+ * dequeue_next_cmd - dequeue a command for processing
+ * @instance: the scsi host instance
+ *
+ * Priority is given to commands on the autosense queue. These commands
+ * need autosense because of a CHECK CONDITION result.
+ *
+ * Returns a command pointer if a command is found for a target that is
+ * not already busy. Otherwise returns NULL.
+ */
+
+static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
+{
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
+   struct NCR5380_cmd *ncmd;
+   struct scsi_cmnd *cmd;
+
+   if 

[PATCH v3 64/77] atari_NCR5380: Eliminate HOSTNO macro

2015-12-21 Thread Finn Thain
Keep the two core driver forks in sync.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   71 +++--
 drivers/scsi/atari_NCR5380.c |  102 +++
 2 files changed, 84 insertions(+), 89 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:11.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:12.0 +1100
@@ -175,8 +175,6 @@
  * possible) function may be used.
  */
 
-#defineHOSTNO  instance->host_no
-
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -1024,10 +1022,8 @@ static void NCR5380_main(struct work_str
&& !hostdata->dma_len
 #endif
) {
-   dprintk(NDEBUG_MAIN, "scsi%d: main: performing 
information transfer\n",
-   HOSTNO);
+   dsprintk(NDEBUG_MAIN, instance, "main: performing 
information transfer\n");
NCR5380_information_transfer(instance);
-   dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", 
HOSTNO);
done = 0;
}
} while (!done);
@@ -1064,7 +1060,7 @@ static void NCR5380_dma_complete(struct
(BASR_PHASE_MATCH|BASR_ACK)) {
saved_data = NCR5380_read(INPUT_DATA_REG);
overrun = 1;
-   dprintk(NDEBUG_DMA, "scsi%d: read overrun 
handled\n", HOSTNO);
+   dsprintk(NDEBUG_DMA, instance, "read overrun 
handled\n");
}
}
}
@@ -1169,8 +1165,8 @@ static irqreturn_t NCR5380_intr(int irq,
unsigned char mr = NCR5380_read(MODE_REG);
unsigned char sr = NCR5380_read(STATUS_REG);
 
-   dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, 
MR 0x%02x\n",
-   HOSTNO, irq, basr, sr, mr);
+   dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 
0x%02x, MR 0x%02x\n",
+irq, basr, sr, mr);
 
 #if defined(REAL_DMA)
if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
@@ -1179,7 +1175,7 @@ static irqreturn_t NCR5380_intr(int irq,
 * for End of DMA errata need to happen in DMA Mode.
 */
 
-   dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", 
HOSTNO);
+   dsprintk(NDEBUG_INTR, instance, "interrupt in DMA 
mode\n");
 
if (hostdata->connected) {
NCR5380_dma_complete(instance);
@@ -1196,8 +1192,7 @@ static irqreturn_t NCR5380_intr(int irq,
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-   dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and 
IO\n",
-   HOSTNO);
+   dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and 
IO\n");
 
if (!hostdata->connected) {
NCR5380_reselect(instance);
@@ -1209,7 +1204,7 @@ static irqreturn_t NCR5380_intr(int irq,
/* Probably Bus Reset */
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-   dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", 
HOSTNO);
+   dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
 #ifdef SUN3_SCSI_VME
dregs->csr |= CSR_DMA_ENABLE;
 #endif
@@ -1266,8 +1261,8 @@ static struct scsi_cmnd *NCR5380_select(
int err;
 
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-   dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", 
HOSTNO,
-  instance->this_id);
+   dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = 
%d\n",
+instance->this_id);
 
/*
 * Arbitration and selection phases are slow and involve dropping the
@@ -1321,8 +1316,7 @@ static struct scsi_cmnd *NCR5380_select(
(NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
-   dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, 
deasserting MR_ARBITRATE\n",
-  HOSTNO);
+   dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, 
deasserting MR_ARBITRATE\n");
spin_lock_irq(>lock);
goto out;
}
@@ -1356,7 +1350,7 @@ static struct scsi_cmnd *NCR5380_select(
goto out;
   

[PATCH v3 53/77] ncr5380: Use shost_priv helper

2015-12-21 Thread Finn Thain
Make use of the shost_priv() helper. Remove HOSTDATA and SETUP_HOSTDATA
macros because they harm readability.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   23 ++-
 drivers/scsi/atari_NCR5380.c |   20 +++-
 2 files changed, 17 insertions(+), 26 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:51.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:53.0 +1100
@@ -464,7 +464,7 @@ static irqreturn_t __init probe_intr(int
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
int possible)
 {
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned long timeout;
int trying_irqs, i, mask;
 
@@ -586,9 +586,7 @@ static int __maybe_unused NCR5380_write_
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
struct Scsi_Host *instance)
 {
-   struct NCR5380_hostdata *hostdata;
-
-   hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
hostdata->spin_max_w, hostdata->spin_max_r);
@@ -614,8 +612,8 @@ static int __maybe_unused NCR5380_show_i
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
int i;
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
unsigned long deadline;
 
if(in_interrupt())
@@ -728,7 +726,7 @@ static int NCR5380_maybe_reset_bus(struc
 
 static void NCR5380_exit(struct Scsi_Host *instance)
 {
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
cancel_work_sync(>main_task);
destroy_workqueue(hostdata->work_q);
@@ -1037,7 +1035,7 @@ static irqreturn_t NCR5380_intr(int irq,
  
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char tmp[3], phase;
unsigned char *data;
int len;
@@ -1511,7 +1509,7 @@ static int NCR5380_transfer_dma(struct S
unsigned char saved_data = 0, overrun = 0, residue;
 #endif
 
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
*phase = tmp;
@@ -1743,7 +1741,7 @@ static int NCR5380_transfer_dma(struct S
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata 
*)instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char msgout = NOP;
int sink = 0;
int len;
@@ -2090,8 +2088,7 @@ static void NCR5380_information_transfer
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char target_mask;
unsigned char lun, phase;
int len;
@@ -2214,7 +2211,7 @@ static void NCR5380_reselect(struct Scsi
 
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
int transferred;
 
/*
@@ -2268,7 +2265,7 @@ static void NCR5380_dma_complete(NCR5380
 static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
struct Scsi_Host *instance = cmd->device->host;
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
struct scsi_cmnd *tmp, **prev;
unsigned long flags;
 
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:51.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:53.0 +1100
@@ -196,12 +196,6 @@
  * possible) function may be used.
  */
 
-/* Macros ease life... :-) */
-#defineSETUP_HOSTDATA(in)  \
-struct NCR5380_hostdata *hostdata = 

[PATCH v3 54/77] ncr5380: Use dsprintk() for queue debugging

2015-12-21 Thread Finn Thain
Print the command pointers in the log messages for debugging queue data
structures. The LIST and REMOVE macros can then be removed.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   36 
 drivers/scsi/atari_NCR5380.c |   43 +++
 2 files changed, 47 insertions(+), 32 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:53.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:54.0 +1100
@@ -936,10 +936,8 @@ static void NCR5380_main(struct work_str
 prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
u8 lun = tmp->device->lun;
 
-   dprintk(NDEBUG_LISTS,
-   "MAIN tmp=%p target=%d busy=%d 
lun=%d\n",
-   tmp, scmd_id(tmp), 
hostdata->busy[scmd_id(tmp)],
-   lun);
+   dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p 
target=%d busy=%d lun=%d\n",
+tmp, scmd_id(tmp), 
hostdata->busy[scmd_id(tmp)], lun);
/*  When we find one, remove it from the issue 
queue. */
if (
 #ifdef SUPPORT_TAGS
@@ -956,6 +954,10 @@ static void NCR5380_main(struct work_str
hostdata->issue_queue = 
NEXT(tmp);
}
SET_NEXT(tmp, NULL);
+   dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+instance, "main: removed %p 
from issue queue %p\n",
+tmp, prev);
+
hostdata->retain_dma_intr++;
 
/*
@@ -964,9 +966,6 @@ static void NCR5380_main(struct work_str
 * On failure, we must add the command 
back to the
 *   issue queue so we can keep trying.
 */
-   dprintk(NDEBUG_MAIN, "scsi%d: main(): 
command for target %d "
-   "lun %d removed from 
issue_queue\n",
-   HOSTNO, tmp->device->id, 
lun);
/*
 * REQUEST SENSE commands are issued 
without tagged
 * queueing, even on SCSI-II devices 
because the
@@ -989,13 +988,14 @@ static void NCR5380_main(struct work_str
LIST(tmp, 
hostdata->issue_queue);
SET_NEXT(tmp, 
hostdata->issue_queue);
hostdata->issue_queue = tmp;
+   dsprintk(NDEBUG_MAIN | 
NDEBUG_QUEUES,
+instance, "main: 
select() failed, %p returned to issue queue\n",
+tmp);
 #ifdef SUPPORT_TAGS
cmd_free_tag(tmp);
 #endif
hostdata->retain_dma_intr--;
done = 0;
-   dprintk(NDEBUG_MAIN, "scsi%d: 
main(): select() failed, "
-   "returned to 
issue_queue\n", HOSTNO);
}
if (hostdata->connected)
break;
@@ -2017,8 +2017,9 @@ static void NCR5380_information_transfer
case COMMAND_COMPLETE:
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, 
ICR_BASE);
-   dprintk(NDEBUG_QUEUES, "scsi%d: command 
for target %d, lun %llu "
- "completed\n", HOSTNO, 
cmd->device->id, cmd->device->lun);
+   dsprintk(NDEBUG_QUEUES, instance,
+"COMMAND COMPLETE %p target %d 
lun %llu\n",
+cmd, scmd_id(cmd), 
cmd->device->lun);
 
hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
@@ -2067,13 +2068,11 @@ static void NCR5380_information_transfer
  

[PATCH v3 62/77] ncr5380: Implement new eh_bus_reset_handler

2015-12-21 Thread Finn Thain
NCR5380.c lacks a sane eh_bus_reset_handler. The atari_NCR5380.c code is
much better but it should not throw out the issue queue (that would be
a host reset) and it neglects to set the result code for commands that it
throws out. Fix these bugs and keep the two core drivers in sync.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   50 ++-
 drivers/scsi/atari_NCR5380.c |   39 +++--
 2 files changed, 72 insertions(+), 17 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:07.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:09.0 +1100
@@ -2694,11 +2694,12 @@ static int NCR5380_bus_reset(struct scsi
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int i;
unsigned long flags;
+   struct NCR5380_cmd *ncmd;
 
spin_lock_irqsave(>lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
-   scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
+   scmd_printk(KERN_INFO, cmd, __func__);
 #endif
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2718,27 +2719,32 @@ static int NCR5380_bus_reset(struct scsi
 
hostdata->selecting = NULL;
 
-   if (hostdata->connected)
-   dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected 
command\n");
-   hostdata->connected = NULL;
+   list_for_each_entry(ncmd, >disconnected, list) {
+   struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+   set_host_byte(cmd, DID_RESET);
+   cmd->scsi_done(cmd);
+   }
+
+   list_for_each_entry(ncmd, >autosense, list) {
+   struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+   set_host_byte(cmd, DID_RESET);
+   cmd->scsi_done(cmd);
+   }
+
+   if (hostdata->connected) {
+   set_host_byte(hostdata->connected, DID_RESET);
+   complete_cmd(instance, hostdata->connected);
+   hostdata->connected = NULL;
+   }
 
if (hostdata->sensing) {
+   set_host_byte(hostdata->connected, DID_RESET);
complete_cmd(instance, hostdata->sensing);
hostdata->sensing = NULL;
}
 
-   if (!list_empty(>autosense))
-   dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense 
list\n");
-   INIT_LIST_HEAD(>autosense);
-
-   if (!list_empty(>unissued))
-   dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued 
list\n");
-   INIT_LIST_HEAD(>unissued);
-
-   if (!list_empty(>disconnected))
-   dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected 
list\n");
-   INIT_LIST_HEAD(>disconnected);
-
 #ifdef SUPPORT_TAGS
free_all_tags(hostdata);
 #endif
@@ -2748,6 +2754,7 @@ static int NCR5380_bus_reset(struct scsi
hostdata->dma_len = 0;
 #endif
 
+   queue_work(hostdata->work_q, >main_task);
maybe_release_dma_irq(instance);
spin_unlock_irqrestore(>lock, flags);
 
Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:07.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:09.0 +1100
@@ -2482,18 +2482,66 @@ static int NCR5380_bus_reset(struct scsi
 {
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
+   int i;
unsigned long flags;
+   struct NCR5380_cmd *ncmd;
 
spin_lock_irqsave(>lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
-   scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
+   scmd_printk(KERN_INFO, cmd, __func__);
 #endif
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
do_reset(instance);
 
+   /* reset NCR registers */
+   NCR5380_write(MODE_REG, MR_BASE);
+   NCR5380_write(TARGET_COMMAND_REG, 0);
+   NCR5380_write(SELECT_ENABLE_REG, 0);
+
+   /* After the reset, there are no more connected or disconnected commands
+* and no busy units; so clear the low-level status here to avoid
+* conflicts when the mid-level code tries to wake up the affected
+* commands!
+*/
+
+   hostdata->selecting = NULL;
+
+   list_for_each_entry(ncmd, >disconnected, list) {
+   struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+   set_host_byte(cmd, DID_RESET);
+   cmd->scsi_done(cmd);
+   }
+
+   list_for_each_entry(ncmd, >autosense, list) {
+   struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+   set_host_byte(cmd, DID_RESET);
+   cmd->scsi_done(cmd);
+   }
+
+   if 

[PATCH v3 76/77] ncr5380: Fix wait for 53C80 registers registers after PDMA

2015-12-21 Thread Finn Thain
From: Ondrej Zary 

The check for 53C80 registers accessibility was commented out because
it was broken (inverted). Fix and enable it.

Signed-off-by: Ondrej Zary 
Signed-off-by: Finn Thain 

---
 drivers/scsi/g_NCR5380.c |   37 ++---
 1 file changed, 6 insertions(+), 31 deletions(-)

Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:17:31.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:17:32.0 +1100
@@ -609,14 +609,10 @@ static inline int NCR5380_pread(struct S
if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
printk("53C400r: no 53C80 gated irq after transfer");
 
-#if 0
-   /*
-*  DON'T DO THIS - THEY NEVER ARRIVE!
-*/
-   printk("53C400r: Waiting for 53C80 registers\n");
-   while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
+   /* wait for 53C80 registers to be available */
+   while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
;
-#endif
+
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
printk(KERN_ERR "53C400r: no end dma signal\n");

@@ -638,7 +634,6 @@ static inline int NCR5380_pwrite(struct
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int blocks = len / 128;
int start = 0;
-   int i;
 
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
NCR5380_write(hostdata->c400_blk_cnt, blocks);
@@ -687,36 +682,16 @@ static inline int NCR5380_pwrite(struct
blocks--;
}
 
-#if 0
-   printk("53C400w: waiting for registers to be available\n");
-   THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & 
CSR_53C80_REG);
-   printk("53C400w: Got em\n");
-#endif
-
-   /* Let's wait for this instead - could be ugly */
-   /* All documentation says to check for this. Maybe my hardware is too
-* fast. Waiting for it seems to work fine! KLL
-*/
-   while (!(i = NCR5380_read(hostdata->c400_ctl_status) & 
CSR_GATED_53C80_IRQ)) {
+   /* wait for 53C80 registers to be available */
+   while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
udelay(4); /* DTC436 chip hangs without this */
/* FIXME - no timeout */
}
 
-   /*
-* I know. i is certainly != 0 here but the loop is new. See previous
-* comment.
-*/
-   if (i) {
-   if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & 
BASR_END_DMA_TRANSFER))
-   printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! 
BASR=%0x\n", i);
-   } else
-   printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer 
(last block)\n");
-
-#if 0
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
printk(KERN_ERR "53C400w: no end dma signal\n");
}
-#endif
+
while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
;   // TIMEOUT
return 0;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 63/77] atari_NCR5380: Remove HOSTNO macro from printk() and seq_printf() calls

2015-12-21 Thread Finn Thain
Remove the HOSTNO macro that is peculiar to atari_NCR5380.c and
contributes to the problem of divergence of the NCR5380 core drivers.
Keep NCR5380.c in sync.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   17 +
 drivers/scsi/atari_NCR5380.c |   23 +--
 2 files changed, 18 insertions(+), 22 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:09.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:11.0 +1100
@@ -569,12 +569,12 @@ static void NCR5380_print_phase(struct S
 
status = NCR5380_read(STATUS_REG);
if (!(status & SR_REQ))
-   printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", 
HOSTNO);
+   shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase 
unknown.\n");
else {
for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
 (phases[i].value != (status & PHASE_MASK)); ++i)
;
-   printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
+   shost_printk(KERN_DEBUG, instance, "phase %s\n", 
phases[i].name);
}
 }
 
@@ -1428,8 +1428,7 @@ static struct scsi_cmnd *NCR5380_select(
NCR5380_reselect(instance);
if (!hostdata->connected)
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
-  HOSTNO);
+   shost_printk(KERN_ERR, instance, "reselection after won 
arbitration?\n");
goto out;
}
 
@@ -1957,8 +1956,7 @@ static void NCR5380_information_transfer
switch (phase) {
case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-   printk("scsi%d: NDEBUG_NO_DATAOUT set, 
attempted DATAOUT "
-  "aborted\n", HOSTNO);
+   shost_printk(KERN_DEBUG, instance, 
"NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
@@ -2219,13 +2217,11 @@ static void NCR5380_information_transfer
tmp = 0;
}
} else if (len) {
-   printk(KERN_NOTICE "scsi%d: 
error receiving "
-  "extended message\n", 
HOSTNO);
+   shost_printk(KERN_ERR, 
instance, "error receiving extended message\n");
tmp = 0;
} else {
-   printk(KERN_NOTICE "scsi%d: 
extended message "
-  "code %02x length %d 
is too long\n",
-  HOSTNO, 
extended_msg[2], extended_msg[1]);
+   shost_printk(KERN_NOTICE, 
instance, "extended message code %02x length %d is too long\n",
+extended_msg[2], 
extended_msg[1]);
tmp = 0;
}
 
@@ -2241,8 +2237,7 @@ static void NCR5380_information_transfer
 */
default:
if (!tmp) {
-   printk(KERN_INFO "scsi%d: 
rejecting message ",
-  instance->host_no);
+   shost_printk(KERN_ERR, 
instance, "rejecting message ");
spi_print_msg(extended_msg);
printk("\n");
} else if (tmp != EXTENDED_MESSAGE)
@@ -2291,7 +2286,7 @@ static void NCR5380_information_transfer
cmd->SCp.Status = tmp;
break;
default:
-   printk("scsi%d: unknown phase\n", HOSTNO);
+   shost_printk(KERN_ERR, instance, "unknown 
phase\n");
NCR5380_dprint(NDEBUG_ANY, instance);
} /* switch(phase) */
} else {
Index: linux/drivers/scsi/NCR5380.c
===
--- 

[PATCH v3 74/77] ncr5380: Enable PDMA for NCR53C400A

2015-12-21 Thread Finn Thain
From: Ondrej Zary 

Add I/O register mapping for NCR53C400A and enable PDMA mode to
improve performance and fix non-working IRQ.

Tested with HP C2502 (and user-space enabler).

Signed-off-by: Ondrej Zary 
Signed-off-by: Finn Thain 

---

Changes to Ondrej's version:
- An 'if' statement is now a 'switch' statement.
- Throw an error if MMIO register locations are not known.

---
 drivers/scsi/g_NCR5380.c |   23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:17:28.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:17:30.0 +1100
@@ -323,7 +323,7 @@ static int __init generic_NCR5380_detect
 #endif
break;
case BOARD_NCR53C400A:
-   flags = FLAG_NO_PSEUDO_DMA;
+   flags = FLAG_NO_DMA_FIXUP;
ports = ncr_53c400a_ports;
break;
case BOARD_DTC3181E:
@@ -405,27 +405,42 @@ static int __init generic_NCR5380_detect
 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
 * the base address.
 */
-   if (overrides[current_override].board == BOARD_NCR53C400) {
+   switch (overrides[current_override].board) {
+   case BOARD_NCR53C400:
instance->io_port += 8;
hostdata->c400_ctl_status = 0;
hostdata->c400_blk_cnt = 1;
hostdata->c400_host_buf = 4;
+   break;
+   case BOARD_NCR53C400A:
+   hostdata->c400_ctl_status = 9;
+   hostdata->c400_blk_cnt = 10;
+   hostdata->c400_host_buf = 8;
+   break;
}
 #else
instance->base = overrides[current_override].NCR5380_map_name;
hostdata->iomem = iomem;
-   if (overrides[current_override].board == BOARD_NCR53C400) {
+   switch (overrides[current_override].board) {
+   case BOARD_NCR53C400:
hostdata->c400_ctl_status = 0x100;
hostdata->c400_blk_cnt = 0x101;
hostdata->c400_host_buf = 0x104;
+   break;
+   case BOARD_NCR53C400A:
+   pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
+   goto out_unregister;
}
 #endif
 
if (NCR5380_init(instance, flags))
goto out_unregister;
 
-   if (overrides[current_override].board == BOARD_NCR53C400)
+   switch (overrides[current_override].board) {
+   case BOARD_NCR53C400:
+   case BOARD_NCR53C400A:
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+   }
 
NCR5380_maybe_reset_bus(instance);
 


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 67/77] ncr5380: Cleanup comments

2015-12-21 Thread Finn Thain
The CVS revision log is not nearly as useful as the history/history.git
repo, so remove it. Roman's commentary at the top of his driver repeats
the same information elsewhere in the file so remove it. Also remove
some other redundant or obsolete comments.

Both the driver and the datasheets confusingly refer to a DMA access
for a SCSI WRITE command as a "DMA write". Similarly a SCSI READ command
is called a "DMA read". This is the opposite of the usual convention.
Thankfully, the chip documentation and driver code also use "DMA send" and
"DMA receive", so adopt this terminology.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  154 ++-
 drivers/scsi/atari_NCR5380.c |   97 +++
 2 files changed, 48 insertions(+), 203 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:15.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:18.0 +1100
@@ -25,45 +25,8 @@
  */
 
 /*
- * Revision 1.10 1998/9/2  Alan Cox
- * (a...@lxorguk.ukuu.org.uk)
- * Fixed up the timer lockups reported so far. Things still suck. Looking 
- * forward to 2.3 and per device request queues. Then it'll be possible to
- * SMP thread this beast and improve life no end.
- 
- * Revision 1.9  1997/7/27 Ronald van Cuijlenborg
- * (ronald.van.cuijlenb...@tip.nl or nu...@dds.nl)
- * (hopefully) fixed and enhanced USLEEP
- * added support for DTC3181E card (for Mustek scanner)
- *
-
- * Revision 1.8Ingmar Baumgart
- * (ing...@gonzo.schwaben.de)
- * added support for NCR53C400a card
- *
-
- * Revision 1.7  1996/3/2   Ray Van Tassle (ra...@comm.mot.com)
- * added proc_info
- * added support needed for DTC 3180/3280
- * fixed a couple of bugs
- *
-
- * Revision 1.5  1994/01/19  09:14:57  drew
- * Fixed udelay() hack that was being used on DATAOUT phases
- * instead of a proper wait for the final handshake.
- *
- * Revision 1.4  1994/01/19  06:44:25  drew
- * *** empty log message ***
- *
- * Revision 1.3  1994/01/19  05:24:40  drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.2  1994/01/15  06:14:11  drew
- * REAL DMA support, bug fixes.
- *
- * Revision 1.1  1994/01/15  06:00:54  drew
- * Initial revision
- *
+ * With contributions from Ray Van Tassle, Ingmar Baumgart,
+ * Ronald van Cuijlenborg, Alan Cox and others.
  */
 
 /*
@@ -98,12 +61,6 @@
  * transfer - some PC's will use the I/O bus, 68K's must use 
  * memory mapped) and drops this file in their 'C' wrapper.
  *
- * (Note from hch:  unfortunately it was not enough for the different
- * m68k folks and instead of improving this driver they copied it
- * and hacked it up for their needs.  As a consequence they lost
- * most updates to this driver.  Maybe someone will fix all these
- * drivers to use a common core one day..)
- *
  * As far as command queueing, two queues are maintained for 
  * each 5380 in the system - commands that haven't been issued yet,
  * and commands that are currently executing.  This means that an 
@@ -180,9 +137,6 @@
  *  rely on phase mismatch and EOP interrupts to determine end 
  *  of phase.
  *
- * Defaults for these will be provided although the user may want to adjust 
- * these to allocate CPU resources to the SCSI driver or "real" code.
- * 
  * These macros MUST be defined :
  * 
  * NCR5380_read(register)  - read from the specified register
@@ -219,7 +173,7 @@
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
-/*
+/**
  * initialize_SCp  -   init the scsi pointer field
  * @cmd: command block to set up
  *
@@ -368,8 +322,6 @@ mrs[] = {
  * @instance:  adapter state to dump
  *
  * Print the SCSI bus signals for debugging purposes
- *
- * Locks: caller holds hostdata lock (not essential)
  */
 
 static void NCR5380_print(struct Scsi_Host *instance)
@@ -402,13 +354,11 @@ static void NCR5380_print(struct Scsi_Ho
 }
 
 
-/* 
+/**
  * NCR5380_print_phase -   show SCSI phase
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
- *
- * Locks: none
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -452,8 +402,6 @@ static irqreturn_t __init probe_intr(int
  *
  * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
  * and then looking to see what interrupt actually turned up.
- *
- * Locks: none, irqs must be enabled on entry
  */
 
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
@@ -503,8 +451,6 

[PATCH v3 75/77] ncr5380: Enable PDMA for DTC chips

2015-12-21 Thread Finn Thain
From: Ondrej Zary 

Add I/O register mapping for DTC chips and enable PDMA mode.

These chips have 16-bit wide HOST BUFFER register and it must be read
by 16-bit accesses (we lose data otherwise).

Large PIO transfers crash at least the DTCT-436P chip (all reads result
in 0xFF) so this patch actually makes it work.

The chip also crashes when we bang on the C400 host status register too
heavily after PDMA write - a small udelay is needed.

Tested on DTCT-436P and verified that it does not break 53C400A.

Signed-off-by: Ondrej Zary 
Signed-off-by: Finn Thain 

---
Changes to Ondrej's version:
- Rebased.

---
 drivers/scsi/g_NCR5380.c |   38 +++---
 drivers/scsi/g_NCR5380.h |3 ++-
 2 files changed, 33 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:17:30.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:17:31.0 +1100
@@ -327,7 +327,7 @@ static int __init generic_NCR5380_detect
ports = ncr_53c400a_ports;
break;
case BOARD_DTC3181E:
-   flags = FLAG_NO_PSEUDO_DMA;
+   flags = FLAG_NO_DMA_FIXUP;
ports = dtc_3181e_ports;
break;
}
@@ -400,6 +400,7 @@ static int __init generic_NCR5380_detect
 #ifndef SCSI_G_NCR5380_MEM
instance->io_port = 
overrides[current_override].NCR5380_map_name;
instance->n_io_port = region_size;
+   hostdata->io_width = 1; /* 8-bit PDMA by default */
 
/*
 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
@@ -412,6 +413,9 @@ static int __init generic_NCR5380_detect
hostdata->c400_blk_cnt = 1;
hostdata->c400_host_buf = 4;
break;
+   case BOARD_DTC3181E:
+   hostdata->io_width = 2; /* 16-bit PDMA */
+   /* fall through */
case BOARD_NCR53C400A:
hostdata->c400_ctl_status = 9;
hostdata->c400_blk_cnt = 10;
@@ -427,6 +431,7 @@ static int __init generic_NCR5380_detect
hostdata->c400_blk_cnt = 0x101;
hostdata->c400_host_buf = 0x104;
break;
+   case BOARD_DTC3181E:
case BOARD_NCR53C400A:
pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
goto out_unregister;
@@ -438,6 +443,7 @@ static int __init generic_NCR5380_detect
 
switch (overrides[current_override].board) {
case BOARD_NCR53C400:
+   case BOARD_DTC3181E:
case BOARD_NCR53C400A:
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
}
@@ -565,7 +571,11 @@ static inline int NCR5380_pread(struct S
; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-   insb(instance->io_port + hostdata->c400_host_buf,
+   if (hostdata->io_width == 2)
+   insw(instance->io_port + hostdata->c400_host_buf,
+   dst + start, 64);
+   else
+   insb(instance->io_port + hostdata->c400_host_buf,
dst + start, 128);
 #else
/* implies SCSI_G_NCR5380_MEM */
@@ -581,7 +591,11 @@ static inline int NCR5380_pread(struct S
; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-   insb(instance->io_port + hostdata->c400_host_buf,
+   if (hostdata->io_width == 2)
+   insw(instance->io_port + hostdata->c400_host_buf,
+   dst + start, 64);
+   else
+   insb(instance->io_port + hostdata->c400_host_buf,
dst + start, 128);
 #else
/* implies SCSI_G_NCR5380_MEM */
@@ -639,7 +653,11 @@ static inline int NCR5380_pwrite(struct
while (NCR5380_read(hostdata->c400_ctl_status) & 
CSR_HOST_BUF_NOT_RDY)
; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-   outsb(instance->io_port + hostdata->c400_host_buf,
+   if (hostdata->io_width == 2)
+   outsw(instance->io_port + hostdata->c400_host_buf,
+   src + start, 64);
+   else
+   outsb(instance->io_port + hostdata->c400_host_buf,
 

[PATCH v3 71/77] ncr5380: Cleanup whitespace and parentheses

2015-12-21 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   30 +++---
 drivers/scsi/atari_NCR5380.c |   26 +-
 2 files changed, 32 insertions(+), 24 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:23.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:26.0 +1100
@@ -1113,7 +1113,7 @@ static struct scsi_cmnd *NCR5380_select(
 * the host and target ID's on the SCSI bus.
 */
 
-   NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << 
scmd_id(cmd;
+   NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
/*
 * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1121,7 +1121,8 @@ static struct scsi_cmnd *NCR5380_select(
 * phase immediately after selection.
 */
 
-   NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | 
ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
NCR5380_write(MODE_REG, MR_BASE);
 
/*
@@ -1139,7 +1140,8 @@ static struct scsi_cmnd *NCR5380_select(
udelay(1);/* wingel -- wait two bus deskew delay >2*45ns */
 
/* Reset BSY */
-   NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | 
ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
+ ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 
/*
 * Something weird happens when we cease to drive BSY - looks
@@ -1249,7 +1251,7 @@ static struct scsi_cmnd *NCR5380_select(
/* XXX need to handle errors here */
 
hostdata->connected = cmd;
-   hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
+   hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 
initialize_SCp(cmd);
 
@@ -1340,11 +1342,14 @@ static int NCR5380_transfer_pio(struct S
if (!((p & SR_MSG) && c > 1)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_DATA);
NCR5380_dprint(NDEBUG_PIO, instance);
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_DATA | ICR_ASSERT_ACK);
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_DATA | ICR_ASSERT_ACK);
} else {
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN);
NCR5380_dprint(NDEBUG_PIO, instance);
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN 
| ICR_ASSERT_ACK);
}
} else {
NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1775,10 +1780,12 @@ static void NCR5380_information_transfer
if (sink && (phase != PHASE_MSGOUT)) {
NCR5380_write(TARGET_COMMAND_REG, 
PHASE_SR_TO_TCR(tmp));
 
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_ATN |
+ ICR_ASSERT_ACK);
while (NCR5380_read(STATUS_REG) & SR_REQ)
;
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_ATN);
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_ATN);
sink = 0;
continue;
}
@@ -1848,8 +1855,9 @@ static void NCR5380_information_transfer
 #endif /* defined(PSEUDO_DMA) || 
defined(REAL_DMA_POLL) */
{
spin_unlock_irq(>lock);
-   NCR5380_transfer_pio(instance, , 
(int *) >SCp.this_residual, (unsigned char **)
->SCp.ptr);
+   NCR5380_transfer_pio(instance, ,

[PATCH v3 72/77] ncr5380: Fix pseudo DMA transfers on 53C400

2015-12-21 Thread Finn Thain
From: Ondrej Zary 

Pseudo-DMA (PDMA) has been broken for ages, resulting in hangs on
53C400-based cards.

According to 53C400 datasheet, PDMA transfer length must be a multiple
of 128. Check if that's true and use PIO if it's not.

This makes PDMA work on 53C400 (Canon FG2-5202).

Signed-off-by: Ondrej Zary 
Signed-off-by: Finn Thain 

---
 drivers/scsi/g_NCR5380.c |4 
 1 file changed, 4 insertions(+)

Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:17:15.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:17:27.0 +1100
@@ -702,6 +702,10 @@ static int generic_NCR5380_dma_xfer_len(
!(cmd->SCp.this_residual % transfersize))
transfersize = 32 * 1024;
 
+   /* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
+   if (transfersize % 128)
+   transfersize = 0;
+
return transfersize;
 }
 


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 49/77] ncr5380: Remove redundant ICR_ARBITRATION_LOST test and eliminate FLAG_DTC3181E

2015-12-21 Thread Finn Thain
Remove FLAG_DTC3181E. It was used to suppress a final Arbitration Lost
(SEL asserted) test that isn't actually needed. The test was suppressed
because it causes problems for DTC436 and DTC536 chips. It takes place
after the host wins arbitration, so SEL has been asserted. These chips
can't seem to tell whether it was the host or another bus device that
did so.

This questionable final test appears in a flow chart in an early NCR5380
datasheet. It was removed from later documents like the DP5380 datasheet.

By the time this final test takes place, the driver has already tested
the Arbitration Lost bit several times. The first test happens 3 us after
BUS FREE (or longer due to register access delays). The protocol requires
that a device stop signalling within 1.8 us after BUS FREE unless it won
arbitration, in which case it must assert SEL, which is detected 1.2 us
later by the first Arbitration Lost test.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   14 +-
 drivers/scsi/NCR5380.h   |1 -
 drivers/scsi/atari_NCR5380.c |9 -
 drivers/scsi/dmx3191d.c  |2 +-
 drivers/scsi/g_NCR5380.c |2 +-
 5 files changed, 3 insertions(+), 25 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:40.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:45.0 +1100
@@ -528,14 +528,13 @@ static void prepare_info(struct Scsi_Hos
 "base 0x%lx, irq %d, "
 "can_queue %d, cmd_per_lun %d, "
 "sg_tablesize %d, this_id %d, "
-"flags { %s%s%s%s}, "
+"flags { %s%s%s}, "
 "options { %s} ",
 instance->hostt->name, instance->io_port, instance->n_io_port,
 instance->base, instance->irq,
 instance->can_queue, instance->cmd_per_lun,
 instance->sg_tablesize, instance->this_id,
 hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
-hostdata->flags & FLAG_DTC3181E  ? "DTC3181E "  : "",
 hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #ifdef AUTOPROBE_IRQ
@@ -1159,17 +1158,6 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(INITIATOR_COMMAND_REG,
  ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-   if (!(hostdata->flags & FLAG_DTC3181E) &&
-   /* RvC: DTC3181E has some trouble with this
-*  so we simply removed it. Seems to work with
-*  only Mustek scanner attached
-*/
-   (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
-   NCR5380_write(MODE_REG, MR_BASE);
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-   dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, 
deasserting ICR_ASSERT_SEL\n", instance->host_no);
-   return -1;
-   }
/* 
 * Again, bus clear + bus settle time is 1.2us, however, this is 
 * a minimum so we'll udelay ceil(1.2)
Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:37.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:45.0 +1100
@@ -232,7 +232,6 @@
 
 #define FLAG_NO_DMA_FIXUP  1   /* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA 8   /* Inhibit DMA */
-#define FLAG_DTC3181E  16  /* DTC3181E */
 #define FLAG_LATE_DMA_SETUP32  /* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING64  /* as X3T9.2 spelled it */
 #define FLAG_TOSHIBA_DELAY 128 /* Allow for borken CD-ROMs */
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:44.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:45.0 +1100
@@ -1420,15 +1420,6 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(INITIATOR_COMMAND_REG,
  ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-   if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-   hostdata->connected) {
-   NCR5380_write(MODE_REG, MR_BASE);
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-   dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, 
deasserting ICR_ASSERT_SEL\n",
-  HOSTNO);
-   return -1;
-   }
-
/*
 * Again, bus clear + bus settle time is 1.2us, however, this is
 * a minimum so we'll udelay 

[PATCH v3 44/77] ncr5380: Fix off-by-one bug in extended_msg[] bounds check

2015-12-21 Thread Finn Thain
Fix the array bounds check when transferring an extended message from the
target.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |3 ++-
 drivers/scsi/atari_NCR5380.c |4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:35.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:36.0 +1100
@@ -2039,7 +2039,8 @@ static void NCR5380_information_transfer
 
dprintk(NDEBUG_EXTENDED, "scsi%d : 
length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) 
extended_msg[2]);
 
-   if (!len && extended_msg[1] <= 
(sizeof(extended_msg) - 1)) {
+   if (!len && extended_msg[1] > 0 &&
+   extended_msg[1] <= 
sizeof(extended_msg) - 2) {
/* Accept third byte by 
clearing ACK */

NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
len = extended_msg[1] - 1;
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:35.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:36.0 +1100
@@ -2330,8 +2330,8 @@ static void NCR5380_information_transfer
dprintk(NDEBUG_EXTENDED, "scsi%d: 
length=%d, code=0x%02x\n", HOSTNO,
   (int)extended_msg[1], 
(int)extended_msg[2]);
 
-   if (!len && extended_msg[1] <=
-   (sizeof(extended_msg) - 1)) {
+   if (!len && extended_msg[1] > 0 &&
+   extended_msg[1] <= 
sizeof(extended_msg) - 2) {
/* Accept third byte by 
clearing ACK */

NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
len = extended_msg[1] - 1;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 41/77] ncr5380: Replace redundant flags with FLAG_NO_DMA_FIXUP

2015-12-21 Thread Finn Thain
The flags DMA_WORKS_RIGHT, FLAG_NCR53C400 and FLAG_HAS_LAST_BYTE_SENT
all mean the same thing, i.e. the chip is not a 538[01]. (More recent
devices such as the 53C80 have a 'Last Byte Sent' bit in the Target
Command Register as well as other fixes for End-of-DMA errata.)

These flags have no additional meanings since previous cleanup patches
eliminated the NCR53C400 macro, moved g_NCR5380-specific code out of the
core driver and standardized interrupt handling.

Use the FLAG_NO_DMA_FIXUP flag to suppress End-of-DMA errata workarounds,
for those cards and drivers that make use of the TCR_LAST_BYTE_SENT bit.
Remove the old flags.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   68 +++
 drivers/scsi/NCR5380.h   |4 --
 drivers/scsi/dtc.c   |4 --
 drivers/scsi/g_NCR5380.c |2 -
 4 files changed, 25 insertions(+), 53 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:30.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:32.0 +1100
@@ -541,7 +541,7 @@ static void prepare_info(struct Scsi_Hos
 instance->base, instance->irq,
 instance->can_queue, instance->cmd_per_lun,
 instance->sg_tablesize, instance->this_id,
-hostdata->flags & FLAG_NCR53C400 ? "NCR53C400 " : "",
+hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
 hostdata->flags & FLAG_DTC3181E  ? "DTC3181E "  : "",
 hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
@@ -702,6 +702,7 @@ static int NCR5380_init(struct Scsi_Host
hostdata->connected = NULL;
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;
+   hostdata->flags = flags;

INIT_WORK(>main_task, NCR5380_main);
hostdata->work_q = alloc_workqueue("ncr5380_%d",
@@ -710,12 +711,6 @@ static int NCR5380_init(struct Scsi_Host
if (!hostdata->work_q)
return -ENOMEM;
 
-   /* The CHECK code seems to break the 53C400. Will check it later maybe 
*/
-   if (flags & FLAG_NCR53C400)
-   hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
-   else
-   hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
-
hostdata->host = instance;
 
prepare_info(instance);
@@ -1614,7 +1609,7 @@ static int NCR5380_transfer_dma(struct S
 * before the setting of DMA mode to after transfer of the last byte.
 */
 
-   if (hostdata->flags & FLAG_NCR53C400)
+   if (hostdata->flags & FLAG_NO_DMA_FIXUP)
NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
MR_ENABLE_EOP_INTR);
else
@@ -1734,14 +1729,9 @@ static int NCR5380_transfer_dma(struct S
return 0;
 #else  /* defined(REAL_DMA_POLL) */
if (p & SR_IO) {
-#ifdef DMA_WORKS_RIGHT
-   foo = NCR5380_pread(instance, d, c);
-#else
-   int diff = 1;
-   if (hostdata->flags & FLAG_NCR53C400) {
-   diff = 0;
-   }
-   if (!(foo = NCR5380_pread(instance, d, c - diff))) {
+   foo = NCR5380_pread(instance, d,
+   hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1);
+   if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
/*
 * We can't disable DMA mode after successfully 
transferring 
 * what we plan to be the last byte, since that would 
open up
@@ -1764,46 +1754,32 @@ static int NCR5380_transfer_dma(struct S
 * byte.
 */
 
-   if (!(hostdata->flags & FLAG_NCR53C400)) {
-   while (!(NCR5380_read(BUS_AND_STATUS_REG) & 
BASR_DRQ));
-   /* Wait for clean handshake */
-   while (NCR5380_read(STATUS_REG) & SR_REQ);
-   d[c - 1] = NCR5380_read(INPUT_DATA_REG);
+   if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+ BASR_DRQ, BASR_DRQ, HZ) < 0) {
+   foo = -1;
+   shost_printk(KERN_ERR, instance, "PDMA read: 
DRQ timeout\n");
+   }
+   if (NCR5380_poll_politely(instance, STATUS_REG,
+ SR_REQ, 0, HZ) < 0) {
+   foo = -1;
+   shost_printk(KERN_ERR, instance, "PDMA read: 
!REQ timeout\n");
}
+   

[PATCH v3 65/77] atari_scsi, sun3_scsi: Remove global Scsi_Host pointer

2015-12-21 Thread Finn Thain
This refactoring removes two global Scsi_Host pointers. This
improves consistency with other ncr5380 drivers. Adopting the same
conventions as the other drivers makes them easier to read.

Signed-off-by: Finn Thain 

---
 drivers/scsi/atari_NCR5380.c |5 +-
 drivers/scsi/atari_scsi.c|   29 -
 drivers/scsi/sun3_scsi.c |   72 ++-
 3 files changed, 36 insertions(+), 70 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-12-22 12:16:58.0 
+1100
+++ linux/drivers/scsi/atari_scsi.c 2015-12-22 12:17:14.0 +1100
@@ -159,14 +159,10 @@ static inline unsigned long SCSI_DMA_GET
return adr;
 }
 
-#define HOSTDATA_DMALEN(((struct NCR5380_hostdata *) \
-   (atari_scsi_host->hostdata))->dma_len)
-
 #ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
 #endif
 
-static struct Scsi_Host *atari_scsi_host;
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
 static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
 
@@ -262,15 +258,17 @@ static void scsi_dma_buserr(int irq, voi
 #endif
 
 
-static irqreturn_t scsi_tt_intr(int irq, void *dummy)
+static irqreturn_t scsi_tt_intr(int irq, void *dev)
 {
 #ifdef REAL_DMA
+   struct Scsi_Host *instance = dev;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat;
 
dma_stat = tt_scsi_dma.dma_ctrl;
 
-   dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n",
-  atari_scsi_host->host_no, dma_stat & 0xff);
+   dsprintk(NDEBUG_INTR, instance, "NCR5380 interrupt, DMA status = 
%02x\n",
+dma_stat & 0xff);
 
/* Look if it was the DMA that has interrupted: First possibility
 * is that a bus error occurred...
@@ -293,7 +291,8 @@ static irqreturn_t scsi_tt_intr(int irq,
 * data reg!
 */
if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
-   atari_dma_residual = HOSTDATA_DMALEN - 
(SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
+   atari_dma_residual = hostdata->dma_len -
+   (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
 
dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
   atari_dma_residual);
@@ -345,15 +344,17 @@ static irqreturn_t scsi_tt_intr(int irq,
 
 #endif /* REAL_DMA */
 
-   NCR5380_intr(irq, dummy);
+   NCR5380_intr(irq, dev);
 
return IRQ_HANDLED;
 }
 
 
-static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
+static irqreturn_t scsi_falcon_intr(int irq, void *dev)
 {
 #ifdef REAL_DMA
+   struct Scsi_Host *instance = dev;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat;
 
/* Turn off DMA and select sector counter register before
@@ -388,7 +389,7 @@ static irqreturn_t scsi_falcon_intr(int
printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
   "ST-DMA fifo\n", transferred & 15);
 
-   atari_dma_residual = HOSTDATA_DMALEN - transferred;
+   atari_dma_residual = hostdata->dma_len - transferred;
dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
   atari_dma_residual);
} else
@@ -400,13 +401,14 @@ static irqreturn_t scsi_falcon_intr(int
 * data to the original destination address.
 */
memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
-  HOSTDATA_DMALEN - atari_dma_residual);
+  hostdata->dma_len - atari_dma_residual);
atari_dma_orig_addr = NULL;
}
 
 #endif /* REAL_DMA */
 
-   NCR5380_intr(irq, dummy);
+   NCR5380_intr(irq, dev);
+
return IRQ_HANDLED;
 }
 
@@ -873,7 +875,6 @@ static int __init atari_scsi_probe(struc
error = -ENOMEM;
goto fail_alloc;
}
-   atari_scsi_host = instance;
 
instance->irq = irq->start;
 
Index: linux/drivers/scsi/sun3_scsi.c
===
--- linux.orig/drivers/scsi/sun3_scsi.c 2015-12-22 12:16:58.0 +1100
+++ linux/drivers/scsi/sun3_scsi.c  2015-12-22 12:17:14.0 +1100
@@ -56,9 +56,9 @@
 #define NCR5380_infosun3scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
-sun3scsi_dma_setup(data, count, 0)
+sun3scsi_dma_setup(instance, data, count, 0)
 #define NCR5380_dma_write_setup(instance, data, count) \
-sun3scsi_dma_setup(data, count, 1)
+sun3scsi_dma_setup(instance, data, count, 1)
 #define NCR5380_dma_residual(instance) \
 

[PATCH v3 60/77] ncr5380: Implement new eh_abort_handler

2015-12-21 Thread Finn Thain
Introduce a new eh_abort_handler implementation. This one attempts to
follow all of the rules relating to EH handlers. There is still a known
bug: during selection, a command becomes invisible to the EH handlers
because it only appears in a pointer on the stack of a different thread.
This bug is addressed in a subsequent patch.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  155 ++
 drivers/scsi/atari_NCR5380.c |  157 ++-
 2 files changed, 282 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:03.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:05.0 +1100
@@ -2480,41 +2480,168 @@ static void NCR5380_reselect(struct Scsi
 }
 
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
+/**
+ * list_find_cmd - test for presence of a command in a linked list
+ * @haystack: list of commands
+ * @needle: command to search for
+ */
+
+static bool list_find_cmd(struct list_head *haystack,
+  struct scsi_cmnd *needle)
+{
+   struct NCR5380_cmd *ncmd;
+
+   list_for_each_entry(ncmd, haystack, list)
+   if (NCR5380_to_scmd(ncmd) == needle)
+   return true;
+   return false;
+}
+
+/**
+ * list_remove_cmd - remove a command from linked list
+ * @haystack: list of commands
+ * @needle: command to remove
+ */
+
+static bool list_del_cmd(struct list_head *haystack,
+ struct scsi_cmnd *needle)
+{
+   if (list_find_cmd(haystack, needle)) {
+   struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle);
+
+   list_del(>list);
+   return true;
+   }
+   return false;
+}
+
+/**
+ * NCR5380_abort - scsi host eh_abort_handler() method
+ * @cmd: the command to be aborted
  *
- * Purpose : abort a command
+ * Try to abort a given command by removing it from queues and/or sending
+ * the target an abort message. This may not succeed in causing a target
+ * to abort the command. Nonetheless, the low-level driver must forget about
+ * the command because the mid-layer reclaims it and it may be re-issued.
  *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- * host byte of the result field to, if zero DID_ABORTED is
- * used.
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
  *
- * Returns : SUCCESS - success, FAILED on failure.
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
  *
- * XXX - there is no way to abort the command that is currently
- *  connected, you have to wait for it to complete.  If this is
- *  a problem, we could implement longjmp() / setjmp(), setjmp()
- *  called where the loop started in NCR5380_main().
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * If cmd was not found at all then presumably it has already been completed,
+ * in which case return SUCCESS to try to avoid further EH measures.
+ * If the command has not completed yet, we must not fail to find it.
  */
 
-static
-int NCR5380_abort(struct scsi_cmnd *cmd)
+static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned long flags;
+   int result = SUCCESS;
 
spin_lock_irqsave(>lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
-   scmd_printk(KERN_INFO, cmd, "aborting command\n");
+   scmd_printk(KERN_INFO, cmd, __func__);
 #endif
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
+   if (list_del_cmd(>unissued, cmd)) {
+   dsprintk(NDEBUG_ABORT, instance,
+"abort: removed %p from issue queue\n", cmd);
+   cmd->result = DID_ABORT << 16;
+   cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
+   }
+
+   if (list_del_cmd(>disconnected, cmd)) {
+   dsprintk(NDEBUG_ABORT, instance,
+"abort: removed %p from disconnected list\n", cmd);
+   cmd->result = DID_ERROR << 16;
+   if (!hostdata->connected)
+   NCR5380_select(instance, cmd);
+   if (hostdata->connected != cmd) {
+   complete_cmd(instance, cmd);
+   result = FAILED;
+   goto out;
+   }
+   }
+
+   if 

[PATCH v3 61/77] ncr5380: Fix EH during arbitration and selection

2015-12-21 Thread Finn Thain
During arbitration and selection, the relevant command is invisible to
exception handlers and can be found only in a pointer on the stack of a
different thread.

When eh_abort_handler can't find a given command, it can't decide whether
that command was completed already or is still in arbitration or selection
phase. But it must return either SUCCESS (e.g. command completed earlier)
or FAILED (could not abort the nexus, try bus reset).

The solution is to make sure all commands belonging to the LLD are always
visible to exception handlers. Add another scsi_cmnd pointer to the
hostdata struct to track the command in arbitration or selection phase.

Replace 'retain_dma_irq' with the new 'selecting' pointer, to bring
atari_NCR5380.c into line with NCR5380.c.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   76 +--
 drivers/scsi/NCR5380.h   |4 +-
 drivers/scsi/atari_NCR5380.c |   82 +++
 3 files changed, 119 insertions(+), 43 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:05.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:07.0 +1100
@@ -912,9 +912,9 @@ static void NCR5380_main(struct work_str
 * entire unit.
 */
 
-   if (!NCR5380_select(instance, cmd)) {
-   dsprintk(NDEBUG_MAIN, instance, "main: selected 
target %d for command %p\n",
-scmd_id(cmd), cmd);
+   cmd = NCR5380_select(instance, cmd);
+   if (!cmd) {
+   dsprintk(NDEBUG_MAIN, instance, "main: select 
complete\n");
} else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 "main: select failed, returning %p to 
queue\n", cmd);
@@ -1061,9 +1061,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this 
  *  target lives, cmd - SCSI command to execute.
  * 
- * Returns : -1 if selection failed but should be retried.
- *  0 if selection failed and should not be retried.
- *  0 if selection succeeded completely (hostdata->connected == cmd).
+ * Returns cmd if selection failed but should be retried,
+ * NULL if selection failed and should not be retried, or
+ * NULL if selection succeeded (hostdata->connected == cmd).
  *
  * Side effects : 
  *  If bus busy, arbitration failed, etc, NCR5380_select() will exit 
@@ -1081,7 +1081,8 @@ static irqreturn_t NCR5380_intr(int irq,
  * Locks: caller holds hostdata lock in IRQ mode
  */
  
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
+struct scsi_cmnd *cmd)
 {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char tmp[3], phase;
@@ -1092,6 +1093,15 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", 
instance->host_no, instance->this_id);
 
+   /*
+* Arbitration and selection phases are slow and involve dropping the
+* lock, so we have to watch out for EH. An exception handler may
+* change 'selecting' to NULL. This function will then return NULL
+* so that the caller will forget about 'cmd'. (During information
+* transfer phases, EH may change 'connected' to NULL.)
+*/
+   hostdata->selecting = cmd;
+
/* 
 * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
 * data bus during SELECTION.
@@ -1117,13 +1127,13 @@ static int NCR5380_select(struct Scsi_Ho
spin_lock_irq(>lock);
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
/* Reselection interrupt */
-   return -1;
+   goto out;
}
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,
 "select: arbitration timeout\n");
-   return -1;
+   goto out;
}
spin_unlock_irq(>lock);
 
@@ -1135,7 +1145,7 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(MODE_REG, MR_BASE);
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, 
deasserting MR_ARBITRATE\n", instance->host_no);
spin_lock_irq(>lock);
-   return -1;
+   goto out;
}
 
/* After/during arbitration, BSY should be asserted.
@@ -1159,7 +1169,13 @@ static int NCR5380_select(struct Scsi_Ho

[PATCH v3 46/77] ncr5380: Fix NDEBUG_NO_DATAOUT flag

2015-12-21 Thread Finn Thain
NDEBUG_NO_DATAOUT should not disable DATA IN phases too. Fix this.
(This bug has long been fixed in atari_NCR5380.c.)

Signed-off-by: Finn Thain 

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

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:37.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:40.0 +1100
@@ -1838,7 +1838,6 @@ static void NCR5380_information_transfer
continue;
}
switch (phase) {
-   case PHASE_DATAIN:
case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
printk("scsi%d : NDEBUG_NO_DATAOUT set, 
attempted DATAOUT aborted\n", instance->host_no);
@@ -1848,6 +1847,7 @@ static void NCR5380_information_transfer
cmd->scsi_done(cmd);
return;
 #endif
+   case PHASE_DATAIN:
/* 
 * If there is no room left in the current 
buffer in the
 * scatter-gather list, move onto the next one.


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 51/77] ncr5380: Remove command list debug code

2015-12-21 Thread Finn Thain
Some NCR5380 hosts offer a .show_info method to access the contents of
the various command list data structures from a procfs file. When NDEBUG
is set, the same information is sent to the console during EH.

The two core drivers, atari_NCR5380.c and NCR5380.c differ here. Because
it is just for debugging, the easiest way to fix the discrepancy is
simply remove this code.

The only remaining users of NCR5380_show_info() and NCR5380_write_info()
are drivers that define PSEUDO_DMA. The others have no use for the
.show_info method, so don't initialize it.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   70 ++--
 drivers/scsi/arm/oak.c   |2 
 drivers/scsi/atari_NCR5380.c |   94 +--
 drivers/scsi/atari_scsi.c|2 
 drivers/scsi/g_NCR5380.c |1 
 drivers/scsi/sun3_scsi.c |2 
 6 files changed, 9 insertions(+), 162 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:47.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:49.0 +1100
@@ -558,22 +558,6 @@ static void prepare_info(struct Scsi_Hos
 "");
 }
 
-/**
- * NCR5380_print_status-   dump controller info
- * @instance: controller to dump
- *
- * Print commands in the various queues, called from NCR5380_abort 
- * and NCR5380_debug to aid debugging.
- *
- * Locks: called functions disable irqs
- */
-
-static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
-{
-   NCR5380_dprint(NDEBUG_ANY, instance);
-   NCR5380_dprint_phase(NDEBUG_ANY, instance);
-}
-
 #ifdef PSEUDO_DMA
 /**/
 /*
@@ -598,65 +582,19 @@ static int __maybe_unused NCR5380_write_
hostdata->spin_max_w = 0;
return 0;
 }
-#endif
-
-static
-void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m);
-static
-void lprint_command(unsigned char *cmd, struct seq_file *m);
-static
-void lprint_opcode(int opcode, struct seq_file *m);
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
struct Scsi_Host *instance)
 {
struct NCR5380_hostdata *hostdata;
-   struct scsi_cmnd *ptr;
-   unsigned long flags;
 
hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-#ifdef PSEUDO_DMA
seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
hostdata->spin_max_w, hostdata->spin_max_r);
-#endif
-   spin_lock_irqsave(>lock, flags);
-   if (!hostdata->connected)
-   seq_printf(m, "scsi%d: no currently connected command\n", 
instance->host_no);
-   else
-   lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-   seq_printf(m, "scsi%d: issue_queue\n", instance->host_no);
-   for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = 
(struct scsi_cmnd *) ptr->host_scribble)
-   lprint_Scsi_Cmnd(ptr, m);
-
-   seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
-   for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr 
= (struct scsi_cmnd *) ptr->host_scribble)
-   lprint_Scsi_Cmnd(ptr, m);
-   spin_unlock_irqrestore(>lock, flags);
return 0;
 }
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-   seq_printf(m, "scsi%d : destination target %d, lun %llu\n", 
cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
-   seq_puts(m, "command = ");
-   lprint_command(cmd->cmnd, m);
-}
-
-static void lprint_command(unsigned char *command, struct seq_file *m)
-{
-   int i, s;
-   lprint_opcode(command[0], m);
-   for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-   seq_printf(m, "%02x ", command[i]);
-   seq_putc(m, '\n');
-}
-
-static void lprint_opcode(int opcode, struct seq_file *m)
-{
-   seq_printf(m, "%2d (0x%02x)", opcode, opcode);
-}
-
+#endif
 
 /**
  * NCR5380_init-   initialise an NCR5380
@@ -2335,7 +2273,8 @@ static int NCR5380_abort(struct scsi_cmn
 
spin_lock_irqsave(>lock, flags);
 
-   NCR5380_print_status(instance);
+   NCR5380_dprint(NDEBUG_ANY, instance);
+   NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
dprintk(NDEBUG_ABORT, "basr 0x%X, sr 0x%X\n", 
NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
@@ -2490,8 +2429,9 @@ static int NCR5380_bus_reset(struct scsi
 
 #if (NDEBUG & NDEBUG_ANY)
scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
-   NCR5380_print_status(instance);
 #endif
+   NCR5380_dprint(NDEBUG_ANY, instance);
+   NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
do_reset(instance);
 
Index: 

[PATCH v3 37/77] ncr5380: Standardize work queueing algorithm

2015-12-21 Thread Finn Thain
The complex main_running/queue_main mechanism is peculiar to
atari_NCR5380.c. It isn't SMP safe and offers little value given that
the work queue already offers concurrency management. Remove this
complexity to bring atari_NCR5380.c closer to NCR5380.c.

It is not a good idea to call the information transfer state machine from
queuecommand because, according to Documentation/scsi/scsi_mid_low_api.txt
that could happen in soft irq context. Fix this.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.h   |1 
 drivers/scsi/atari_NCR5380.c |   80 +++
 2 files changed, 6 insertions(+), 75 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:24.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:25.0 +1100
@@ -262,7 +262,6 @@ struct NCR5380_hostdata {
   * transfer to handle chip overruns */
int retain_dma_intr;
struct work_struct main_task;
-   volatile int main_running;
 #ifdef SUPPORT_TAGS
struct tag_alloc TagAlloc[8][8];/* 8 targets and 8 LUNs */
 #endif
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:23.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:25.0 +1100
@@ -602,36 +602,6 @@ static void NCR5380_print_phase(struct S
 
 #endif
 
-/*
- * ++roman: New scheme of calling NCR5380_main()
- *
- * If we're not in an interrupt, we can call our main directly, it cannot be
- * already running. Else, we queue it on a task queue, if not 'main_running'
- * tells us that a lower level is already executing it. This way,
- * 'main_running' needs not be protected in a special way.
- *
- * queue_main() is a utility function for putting our main onto the task
- * queue, if main_running is false. It should be called only from a
- * interrupt or bottom half.
- */
-
-#include 
-#include 
-#include 
-
-static inline void queue_main(struct NCR5380_hostdata *hostdata)
-{
-   if (!hostdata->main_running) {
-   /* If in interrupt and NCR5380_main() not already running,
-  queue it on the 'immediate' task queue, to be processed
-  immediately after the current interrupt processing has
-  finished. */
-   queue_work(hostdata->work_q, >main_task);
-   }
-   /* else: nothing to do: the running NCR5380_main() will pick up
-  any newly queued command. */
-}
-
 /**
  * NCR58380_info - report driver and host information
  * @instance: relevant scsi host instance
@@ -714,8 +684,6 @@ static void __maybe_unused NCR5380_print
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
local_irq_save(flags);
-   printk("NCR5380: coroutine is%s running.\n",
-   hostdata->main_running ? "" : "n't");
if (!hostdata->connected)
printk("scsi%d: no currently connected command\n", HOSTNO);
else
@@ -757,8 +725,6 @@ static int __maybe_unused NCR5380_show_i
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
local_irq_save(flags);
-   seq_printf(m, "NCR5380: coroutine is%s running.\n",
-   hostdata->main_running ? "" : "n't");
if (!hostdata->connected)
seq_printf(m, "scsi%d: no currently connected command\n", 
HOSTNO);
else
@@ -997,17 +963,8 @@ static int NCR5380_queue_command(struct
dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", 
H_NO(cmd),
  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-   /* If queue_command() is called from an interrupt (real one or bottom
-* half), we let queue_main() do the job of taking care about main. If 
it
-* is already running, this is a no-op, else main will be queued.
-*
-* If we're not in an interrupt, we can call NCR5380_main()
-* unconditionally, because it cannot be already running.
-*/
-   if (in_interrupt() || irqs_disabled())
-   queue_main(hostdata);
-   else
-   NCR5380_main(>main_task);
+   /* Kick off command processing */
+   queue_work(hostdata->work_q, >main_task);
return 0;
 }
 
@@ -1044,30 +1001,11 @@ static void NCR5380_main(struct work_str
unsigned long flags;
 
/*
-* We run (with interrupts disabled) until we're sure that none of
-* the host adapters have anything that can be done, at which point
-* we set main_running to 0 and exit.
-*
-* Interrupts are enabled before doing various other internal
-* instructions, after we've decided that we need to run through
-* the loop again.
-*
-* 

[PATCH v3 45/77] ncr5380: Cleanup #include directives

2015-12-21 Thread Finn Thain
Remove unused includes (stat.h, signal.h, proc_fs.h) and move includes
needed by the core drivers into the common header (delay.h etc).

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |2 --
 drivers/scsi/NCR5380.h   |4 
 drivers/scsi/arm/cumana_1.c  |4 
 drivers/scsi/arm/oak.c   |2 --
 drivers/scsi/atari_NCR5380.c |5 -
 drivers/scsi/atari_scsi.c|1 -
 drivers/scsi/dmx3191d.c  |5 -
 drivers/scsi/dtc.c   |4 +---
 drivers/scsi/g_NCR5380.c |6 ++
 drivers/scsi/mac_scsi.c  |1 -
 drivers/scsi/pas16.c |4 
 drivers/scsi/t128.c  |3 ---
 12 files changed, 7 insertions(+), 34 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:36.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:37.0 +1100
@@ -79,8 +79,6 @@
  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
  *  tagged queueing)
  */
-#include 
-#include 
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), 
(void*)(y)); if ((x)==(y)) udelay(5); }
Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:32.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:37.0 +1100
@@ -22,8 +22,12 @@
 #ifndef NCR5380_H
 #define NCR5380_H
 
+#include 
 #include 
+#include 
+#include 
 #include 
+#include 
 
 #define NDEBUG_ARBITRATION 0x1
 #define NDEBUG_AUTOSENSE   0x2
Index: linux/drivers/scsi/arm/cumana_1.c
===
--- linux.orig/drivers/scsi/arm/cumana_1.c  2015-12-22 12:16:07.0 
+1100
+++ linux/drivers/scsi/arm/cumana_1.c   2015-12-22 12:16:37.0 +1100
@@ -4,9 +4,7 @@
  * Copyright 1995-2002, Russell King
  */
 #include 
-#include 
 #include 
-#include 
 #include 
 #include 
 
@@ -15,8 +13,6 @@
 
 #include 
 
-#include 
-
 #define PSEUDO_DMA
 
 #define priv(host) ((struct NCR5380_hostdata 
*)(host)->hostdata)
Index: linux/drivers/scsi/arm/oak.c
===
--- linux.orig/drivers/scsi/arm/oak.c   2015-12-22 12:16:07.0 +1100
+++ linux/drivers/scsi/arm/oak.c2015-12-22 12:16:37.0 +1100
@@ -5,9 +5,7 @@
  */
 
 #include 
-#include 
 #include 
-#include 
 #include 
 #include 
 
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:36.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:37.0 +1100
@@ -68,9 +68,6 @@
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#include 
-#include 
-
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x, y) \
do {\
@@ -517,8 +514,6 @@ static inline int NCR5380_poll_politely(
reg, bit, val, wait);
 }
 
-#include 
-
 #if NDEBUG
 static struct {
unsigned char mask;
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-12-22 12:15:56.0 
+1100
+++ linux/drivers/scsi/atari_scsi.c 2015-12-22 12:16:37.0 +1100
@@ -66,7 +66,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
Index: linux/drivers/scsi/dmx3191d.c
===
--- linux.orig/drivers/scsi/dmx3191d.c  2015-12-22 12:15:56.0 +1100
+++ linux/drivers/scsi/dmx3191d.c   2015-12-22 12:16:37.0 +1100
@@ -41,11 +41,6 @@
 
 #define NCR5380_implementation_fields  /* none */
 
-/*
- * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
- */
-#include 
-
 #include "NCR5380.h"
 #include "NCR5380.c"
 
Index: linux/drivers/scsi/dtc.c
===
--- linux.orig/drivers/scsi/dtc.c   2015-12-22 12:16:32.0 +1100
+++ linux/drivers/scsi/dtc.c2015-12-22 12:16:37.0 +1100
@@ -46,15 +46,13 @@
 
 
 #include 
-#include 
 #include 
-#include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+
 #include "dtc.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:16:32.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:16:37.0 +1100
@@ -63,16 +63,14 @@
 #endif
 
 #include 
-#include 
 #include 
+#include 
 #include 
 #include 

[PATCH v3 19/77] ncr5380: Cleanup bogus {request,release}_region() calls

2015-12-21 Thread Finn Thain
Commit 8b801ead3d7a ("[ARM] rpc: update Acorn SCSI drivers to modern ecard
interfaces") neglected to remove a request_region() call in cumana_1.c.

Commit eda32612f7b2 ("[PATCH] give all LLDD driver a ->release method") in
history/history.git added some pointless release_region() calls in dtc.c,
pas16.c and t128.c.

Fix these issues.

Signed-off-by: Finn Thain 

---
 drivers/scsi/arm/cumana_1.c |6 --
 drivers/scsi/dtc.c  |2 --
 drivers/scsi/pas16.c|2 --
 drivers/scsi/t128.c |2 --
 4 files changed, 12 deletions(-)

Index: linux/drivers/scsi/arm/cumana_1.c
===
--- linux.orig/drivers/scsi/arm/cumana_1.c  2015-12-22 12:15:35.0 
+1100
+++ linux/drivers/scsi/arm/cumana_1.c   2015-12-22 12:15:54.0 +1100
@@ -245,12 +245,6 @@ static int cumanascsi1_probe(struct expa
 priv(host)->ctrl = 0;
 writeb(0, priv(host)->base + CTRL);
 
-   host->n_io_port = 255;
-   if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
-   ret = -EBUSY;
-   goto out_unmap;
-   }
-
ret = request_irq(host->irq, cumanascsi_intr, 0,
  "CumanaSCSI-1", host);
if (ret) {
Index: linux/drivers/scsi/dtc.c
===
--- linux.orig/drivers/scsi/dtc.c   2015-12-22 12:15:35.0 +1100
+++ linux/drivers/scsi/dtc.c2015-12-22 12:15:54.0 +1100
@@ -423,8 +423,6 @@ static int dtc_release(struct Scsi_Host
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
-   if (shost->io_port && shost->n_io_port)
-   release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
iounmap(hostdata->base);
return 0;
Index: linux/drivers/scsi/pas16.c
===
--- linux.orig/drivers/scsi/pas16.c 2015-12-22 12:15:35.0 +1100
+++ linux/drivers/scsi/pas16.c  2015-12-22 12:15:54.0 +1100
@@ -540,8 +540,6 @@ static int pas16_release(struct Scsi_Hos
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
-   if (shost->io_port && shost->n_io_port)
-   release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
 }
Index: linux/drivers/scsi/t128.c
===
--- linux.orig/drivers/scsi/t128.c  2015-12-22 12:15:35.0 +1100
+++ linux/drivers/scsi/t128.c   2015-12-22 12:15:54.0 +1100
@@ -255,8 +255,6 @@ static int t128_release(struct Scsi_Host
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
-   if (shost->io_port && shost->n_io_port)
-   release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
iounmap(hostdata->base);
return 0;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 27/77] ncr5380: Add missing lock in eh_abort_handler

2015-12-21 Thread Finn Thain
The host spin lock needs to be acquired by NCR5380_abort() before it calls
NCR5380_select(). This patch doesn't actually fix the EH issues in this
driver but it does avoid this:

BUG: spinlock already unlocked on CPU#0, kworker/u4:1/14
 lock: 0xc0c0f834, .magic: dead4ead, .owner: /-1, .owner_cpu: -1
 CPU: 0 PID: 14 Comm: kworker/u4:1 Not tainted 3.15.5 #5
 Workqueue: scsi_tmf_4 scmd_eh_abort_handler
 Call Trace:
 [ef885d70] [c0008acc] show_stack+0x70/0x1bc (unreliable)
 [ef885db0] [c0492a00] dump_stack+0x84/0x684
 [ef885dc0] [c006f314] spin_dump+0xd0/0xe8
 [ef885dd0] [c006f460] do_raw_spin_unlock+0xd4/0xd8
 [ef885df0] [c0491c8c] _raw_spin_unlock_irq+0x10/0x3c
 [ef885e00] [f381fe3c] NCR5380_select+0x3e4/0x6e8 [dmx3191d]
 [ef885e40] [f382026c] NCR5380_abort+0x12c/0x190 [dmx3191d]
 [ef885e60] [c02fec9c] scmd_eh_abort_handler+0x100/0x460
 [ef885e80] [c0046470] process_one_work+0x16c/0x420
 [ef885ea0] [c0046870] worker_thread+0x14c/0x430
 [ef885ed0] [c004e4f4] kthread+0xd8/0xec
 [ef885f40] [c00124d4] ret_from_kernel_thread+0x5c/0x64

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:12.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:14.0 +1100
@@ -2374,6 +2374,7 @@ static int NCR5380_abort(struct scsi_cmn
 
scmd_printk(KERN_WARNING, cmd, "aborting command\n");
 
+   spin_lock_irq(instance->host_lock);
NCR5380_print_status(instance);
 
dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2420,6 +2421,7 @@ static int NCR5380_abort(struct scsi_cmn
REMOVE(5, *prev, tmp, tmp->host_scribble);
(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
+   spin_unlock_irq(instance->host_lock);
tmp->result = DID_ABORT << 16;
dprintk(NDEBUG_ABORT, "scsi%d : abort removed command 
from issue queue.\n", instance->host_no);
tmp->scsi_done(tmp);
@@ -2443,6 +2445,7 @@ static int NCR5380_abort(struct scsi_cmn
  */
 
if (hostdata->connected) {
+   spin_unlock_irq(instance->host_lock);
dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command 
connected.\n", instance->host_no);
return FAILED;
}
@@ -2475,8 +2478,10 @@ static int NCR5380_abort(struct scsi_cmn
if (cmd == tmp) {
dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected 
command.\n", instance->host_no);
 
-   if (NCR5380_select(instance, cmd))
+   if (NCR5380_select(instance, cmd)) {
+   spin_unlock_irq(instance->host_lock);
return FAILED;
+   }
dprintk(NDEBUG_ABORT, "scsi%d : nexus 
reestablished.\n", instance->host_no);
 
do_abort(instance);
@@ -2486,6 +2491,7 @@ static int NCR5380_abort(struct scsi_cmn
REMOVE(5, *prev, tmp, 
tmp->host_scribble);
*prev = (struct scsi_cmnd *) 
tmp->host_scribble;
tmp->host_scribble = NULL;
+   spin_unlock_irq(instance->host_lock);
tmp->result = DID_ABORT << 16;
tmp->scsi_done(tmp);
return SUCCESS;
@@ -2500,6 +2506,7 @@ static int NCR5380_abort(struct scsi_cmn
  * so we won't panic, but we will notify the user in case something really
  * broke.
  */
+   spin_unlock_irq(instance->host_lock);
printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed 
successfully\n"
" before abortion\n", instance->host_no);
return FAILED;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 43/77] ncr5380: Standardize reselection handling

2015-12-21 Thread Finn Thain
Bring the two NCR5380_reselect() implementations into agreement.

Replace infinite loops in atari_NCR5380.c with timeouts, as per NCR5380.c.

Remove 'abort' flag in NCR5380.c as per atari_NCR5380.c -- if reselection
fails, there may be no MESSAGE IN phase so don't attempt data transfer.

During selection, don't interfere with the chip registers after a
reselection interrupt intervenes.

Clean up some trivial issues with code style, comments and printk.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  115 +++
 drivers/scsi/atari_NCR5380.c |   50 ++
 2 files changed, 93 insertions(+), 72 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:34.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:35.0 +1100
@@ -1182,6 +1182,10 @@ static int NCR5380_select(struct Scsi_Ho
else
udelay(2);
 
+   /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+   if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
+   return -1;
+
dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", 
instance->host_no);
 
/* 
@@ -1953,12 +1957,14 @@ static void NCR5380_information_transfer
cmd->scsi_done(cmd);
}
 
-   NCR5380_write(SELECT_ENABLE_REG, 
hostdata->id_mask);
/* 
 * Restore phase bits to 0 so an 
interrupted selection, 
 * arbitration can resume.
 */
NCR5380_write(TARGET_COMMAND_REG, 0);
+
+   /* Enable reselect interrupts */
+   NCR5380_write(SELECT_ENABLE_REG, 
hostdata->id_mask);
return;
case MESSAGE_REJECT:
/* Accept message by clearing ACK */
@@ -2144,7 +2150,6 @@ static void NCR5380_reselect(struct Scsi
unsigned char msg[3];
unsigned char *data;
struct scsi_cmnd *tmp = NULL, *prev;
-   int abort = 0;
 
/*
 * Disable arbitration, etc. since the host adapter obviously
@@ -2154,7 +2159,7 @@ static void NCR5380_reselect(struct Scsi
NCR5380_write(MODE_REG, MR_BASE);
 
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & 
~(hostdata->id_mask);
-   dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
+   dprintk(NDEBUG_RESELECTION, "scsi%d : reselect\n", instance->host_no);
 
/* 
 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2166,77 +2171,85 @@ static void NCR5380_reselect(struct Scsi
 */
 
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-   /* FIXME: timeout too long, must fail to workqueue */   
-   if(NCR5380_poll_politely(instance, STATUS_REG, SR_SEL, 0, 2*HZ)<0)
-   abort = 1;
-   
+   if (NCR5380_poll_politely(instance,
+ STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+   return;
+   }
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
/*
 * Wait for target to go into MSGIN.
-* FIXME: timeout needed and fail to work queeu
 */
 
if (NCR5380_poll_politely(instance,
- STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0)
-   abort = 1;
+ STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+   do_abort(instance);
+   return;
+   }
 
len = 1;
data = msg;
phase = PHASE_MSGIN;
NCR5380_transfer_pio(instance, , , );
 
+   if (len) {
+   do_abort(instance);
+   return;
+   }
+
if (!(msg[0] & 0x80)) {
-   printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", 
instance->host_no);
+   shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, 
got ");
spi_print_msg(msg);
-   abort = 1;
-   } else {
-   /* Accept message by clearing ACK */
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-   lun = (msg[0] & 0x07);
-
-   /* 
-* We need to add code for SCSI-II to track which devices have
-* I_T_L_Q nexuses established, and which have simple I_T_L
-* nexuses so we can chose to do additional data transfer.
-*/
+   printk("\n");
+   

[PATCH v3 33/77] atari_NCR5380: Set do_abort() timeouts

2015-12-21 Thread Finn Thain
Use timeouts in do_abort() in atari_NCR5380.c instead of infinite loops.
Also fix the kernel-doc comment. Keep the two core driver forks in sync.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   26 +-
 drivers/scsi/atari_NCR5380.c |   34 +-
 2 files changed, 34 insertions(+), 26 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:16.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:20.0 +1100
@@ -1835,19 +1835,19 @@ static void do_reset(struct Scsi_Host *i
local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Purpose : abort the currently established nexus.  Should only be
- * called from a routine which can drop into a
- *
- * Returns : 0 on success, -1 on failure.
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
 {
unsigned char tmp, *msgptr, phase;
int len;
+   int rc;
 
/* Request message out phase */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1862,16 +1862,20 @@ static int do_abort(struct Scsi_Host *in
 * the target sees, so we just handshake.
 */
 
-   while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-   ;
+   rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * 
HZ);
+   if (rc < 0)
+   goto timeout;
+
+   tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-   if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
- ICR_ASSERT_ACK);
-   while (NCR5380_read(STATUS_REG) & SR_REQ)
-   ;
+   if (tmp != PHASE_MSGOUT) {
+   NCR5380_write(INITIATOR_COMMAND_REG,
+ ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+   rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * 
HZ);
+   if (rc < 0)
+   goto timeout;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
}
 
@@ -1887,6 +1891,10 @@ static int do_abort(struct Scsi_Host *in
 */
 
return len ? -1 : 0;
+
+timeout:
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+   return -1;
 }
 
 #if defined(REAL_DMA)
Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:19.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:20.0 +1100
@@ -1458,16 +1458,12 @@ static void do_reset(struct Scsi_Host *i
local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
- * 
- * Purpose : abort the currently established nexus.  Should only be 
- *  called from a routine which can drop into a 
- * 
- * Returns : 0 on success, -1 on failure.
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Locks: queue lock held by caller
- * FIXME: sort this out and get new_eh running
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
@@ -1489,9 +1485,9 @@ static int do_abort(struct Scsi_Host *in
 * the target sees, so we just handshake.
 */
 
-   rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * 
HZ);
+   rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * 
HZ);
if (rc < 0)
-   return -1;
+   goto timeout;
 
tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;

@@ -1500,9 +1496,9 @@ static int do_abort(struct Scsi_Host *in
if (tmp != PHASE_MSGOUT) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN 
| ICR_ASSERT_ACK);
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * 
HZ);
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
if (rc < 0)
-   return -1;
+   goto timeout;
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
}
tmp = ABORT;
msgptr = 
@@ -1516,6 +1512,10 @@ static int do_abort(struct Scsi_Host *in
 */
 
return len ? -1 : 0;
+
+timeout:
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+   return -1;
 }
 
 #if defined(REAL_DMA) || 

[PATCH v3 34/77] atari_NCR5380: Use arbitration timeout

2015-12-21 Thread Finn Thain
Allow target selection to fail with a timeout instead of waiting in
infinite loops. This gets rid of the unused NCR_TIMEOUT macro, it is more
defensive and has proved helpful in debugging.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   44 ++---
 drivers/scsi/atari_NCR5380.c |   57 ++-
 2 files changed, 49 insertions(+), 52 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:20.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:22.0 +1100
@@ -1412,6 +1412,7 @@ static int NCR5380_select(struct Scsi_Ho
int len;
int err;
unsigned long flags;
+   unsigned long timeout;
 
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", 
HOSTNO,
@@ -1436,42 +1437,28 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(MODE_REG, MR_ARBITRATE);
 
-   local_irq_restore(flags);
+   /* The chip now waits for BUS FREE phase. Then after the 800 ns
+* Bus Free Delay, arbitration will begin.
+*/
 
-   /* Wait for arbitration logic to complete */
-#if defined(NCR_TIMEOUT)
-   {
-   unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
-
-   while (!(NCR5380_read(INITIATOR_COMMAND_REG) & 
ICR_ARBITRATION_PROGRESS) &&
-  time_before(jiffies, timeout) && !hostdata->connected)
-   ;
-   if (time_after_eq(jiffies, timeout)) {
-   printk("scsi : arbitration timeout at %d\n", __LINE__);
+   local_irq_restore(flags);
+   timeout = jiffies + HZ;
+   while (1) {
+   if (time_is_before_jiffies(timeout)) {
NCR5380_write(MODE_REG, MR_BASE);
-   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+   shost_printk(KERN_ERR, instance,
+"select: arbitration timeout\n");
return -1;
}
+   if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+   /* Reselection interrupt */
+   return -1;
+   }
+   if (NCR5380_read(INITIATOR_COMMAND_REG) & 
ICR_ARBITRATION_PROGRESS)
+   break;
}
-#else /* NCR_TIMEOUT */
-   while (!(NCR5380_read(INITIATOR_COMMAND_REG) & 
ICR_ARBITRATION_PROGRESS) &&
-  !hostdata->connected)
-   ;
-#endif
-
-   dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
-
-   if (hostdata->connected) {
-   NCR5380_write(MODE_REG, MR_BASE);
-   return -1;
-   }
-   /*
-* The arbitration delay is 2.2us, but this is a minimum and there is
-* no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-* the integral nature of udelay().
-*
-*/
 
+   /* The SCSI-2 arbitration delay is 2.4 us */
udelay(3);
 
/* Check for lost arbitration */
@@ -1634,8 +1621,14 @@ static int NCR5380_select(struct Scsi_Ho
 */
 
/* Wait for start of REQ/ACK handshake */
-   while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-   ;
+
+   err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+   if (err < 0) {
+   shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+   return -1;
+   }
 
dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into 
MESSAGE OUT phase.\n",
   HOSTNO, cmd->device->id);
Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:20.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:22.0 +1100
@@ -1083,6 +1083,7 @@ static int NCR5380_select(struct Scsi_Ho
unsigned char *data;
int len;
int err;
+   unsigned long timeout;
 
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", 
instance->host_no, instance->this_id);
@@ -1101,28 +1102,31 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(MODE_REG, MR_ARBITRATE);
 
+   /* The chip now waits for BUS FREE phase. Then after the 800 ns
+* Bus Free Delay, arbitration will begin.
+*/
 
-   /* We can be relaxed here, interrupts are on, we are
-   

[PATCH v3 38/77] ncr5380: Remove UNSAFE macro

2015-12-21 Thread Finn Thain
Configuring core drivers using macros like this one prevents re-unifying
the core driver forks, and prevents implementing the core driver as a
library or a platform driver.

The UNSAFE macro in particular is a poor workaround for the problem of
interrupt latency. Releasing the locks complicates things because then we
would have to handle the possibility of EH handler invocation during a
PDMA transfer.

The comments say that instead of using this macro, "you're going to be
better off twiddling with transfersize". I agree. Remove this stuff.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |   15 ---
 drivers/scsi/dtc.c |2 --
 drivers/scsi/pas16.c   |1 -
 3 files changed, 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:24.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:27.0 +1100
@@ -195,12 +195,6 @@
  *  rely on phase mismatch and EOP interrupts to determine end 
  *  of phase.
  *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
- *  only really want to use this if you're having a problem with
- *  dropped characters during high speed communications, and even
- *  then, you're going to be better off twiddling with transfersize
- *  in the high level code.
- *
  * Defaults for these will be provided although the user may want to adjust 
  * these to allocate CPU resources to the SCSI driver or "real" code.
  * 
@@ -554,9 +548,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef PSEUDO_DMA
 "PSEUDO_DMA "
 #endif
-#ifdef UNSAFE
-"UNSAFE "
-#endif
 "");
 }
 
@@ -1582,9 +1573,6 @@ static int NCR5380_transfer_dma(struct S
 * before the setting of DMA mode to after transfer of the last byte.
 */
 
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-   spin_unlock_irq(instance->host_lock);
-#endif
/* KLL May need eop and parity in 53c400 */
if (hostdata->flags & FLAG_NCR53C400)
NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
@@ -1793,9 +1781,6 @@ static int NCR5380_transfer_dma(struct S
*data = d + c;
*count = 0;
*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-   spin_lock_irq(instance->host_lock);
-#endif /* defined(REAL_DMA_POLL) */
return foo;
 #endif /* def REAL_DMA */
 }
Index: linux/drivers/scsi/dtc.c
===
--- linux.orig/drivers/scsi/dtc.c   2015-12-22 12:16:07.0 +1100
+++ linux/drivers/scsi/dtc.c2015-12-22 12:16:27.0 +1100
@@ -1,7 +1,5 @@
-
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define UNSAFE /* Leave interrupts enabled during pseudo-dma 
I/O */
 #define DMA_WORKS_RIGHT
 
 
Index: linux/drivers/scsi/pas16.c
===
--- linux.orig/drivers/scsi/pas16.c 2015-12-22 12:15:56.0 +1100
+++ linux/drivers/scsi/pas16.c  2015-12-22 12:16:27.0 +1100
@@ -1,5 +1,4 @@
 #define PSEUDO_DMA
-#define UNSAFE  /* Not unsafe for PAS16 -- use it */
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 29/77] ncr5380: Remove references to linked commands

2015-12-21 Thread Finn Thain
From: Hannes Reinecke 

Some old drivers partially implemented support for linked commands using
a "proposed" next_link pointer in struct scsi_cmnd that never actually
existed. Remove this code.

Signed-off-by: Finn Thain 

---

This is a modified version of Hannes' patch so I have dropped his
signed-off-by tag. This version has a rewritten commit log and also
removes additional references to linked commands from comments. This
version also omits the sun3_NCR5380.c changes since that file no
longer exists.

---
 drivers/scsi/NCR5380.c   |   42 --
 drivers/scsi/atari_NCR5380.c |   60 ---
 2 files changed, 102 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:15.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:16.0 +1100
@@ -78,9 +78,6 @@
  * 
  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
  *  tagged queueing)
- *
- * 5.  Test linked command handling code after Eric is ready with 
- *  the high level code.
  */
 #include 
 #include 
@@ -94,7 +91,6 @@
 #endif
 
 #ifndef notyet
-#undef LINKED
 #undef REAL_DMA
 #endif
 
@@ -191,8 +187,6 @@
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
  *  override-configure an IRQ.
  *
- * LINKED - if defined, linked commands are supported.
- *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
@@ -1923,42 +1917,6 @@ static void NCR5380_information_transfer
cmd->SCp.Message = tmp;
 
switch (tmp) {
-   /*
-* Linking lets us reduce the time 
required to get the 
-* next command out to the device, 
hopefully this will
-* mean we don't waste another 
revolution due to the delays
-* required by ARBITRATION and another 
SELECTION.
-*
-* In the current implementation 
proposal, low level drivers
-* merely have to start the next 
command, pointed to by 
-* next_link, done() is called as with 
unlinked commands.
-*/
-#ifdef LINKED
-   case LINKED_CMD_COMPLETE:
-   case LINKED_FLG_CMD_COMPLETE:
-   /* Accept message by clearing ACK */
-   NCR5380_write(INITIATOR_COMMAND_REG, 
ICR_BASE);
-   dprintk(NDEBUG_LINKED, "scsi%d : target 
%d lun %llu linked command complete.\n", instance->host_no, cmd->device->id, 
cmd->device->lun);
-   /* 
-* Sanity check : A linked command 
should only terminate with
-* one of these messages if there are 
more linked commands
-* available.
-*/
-   if (!cmd->next_link) {
-   printk("scsi%d : target %d lun %llu 
linked command complete, no next_link\n" instance->host_no, cmd->device->id, 
cmd->device->lun);
-   sink = 1;
-   do_abort(instance);
-   return;
-   }
-   initialize_SCp(cmd->next_link);
-   /* The next command is still part of 
this process */
-   cmd->next_link->tag = cmd->tag;
-   cmd->result = cmd->SCp.Status | 
(cmd->SCp.Message << 8);
-   dprintk(NDEBUG_LINKED, "scsi%d : target 
%d lun %llu linked request done, calling scsi_done().\n", instance->host_no, 
cmd->device->id, cmd->device->lun);
-   cmd->scsi_done(cmd);
-   cmd = hostdata->connected;
-   break;
-#endif /* def LINKED */
case ABORT:
case COMMAND_COMPLETE:
/* Accept message by clearing ACK */
Index: linux/drivers/scsi/atari_NCR5380.c

[PATCH v3 57/77] ncr5380: Use standard list data structure

2015-12-21 Thread Finn Thain
The NCR5380 drivers have a home-spun linked list implementation for
scsi_cmnd structs that uses cmd->host_scribble as a 'next' pointer. Adopt
the standard list_head data structure and list operations instead. Remove
the eh_abort_handler rather than convert it. Doing the conversion would
only be churn because the existing EH handlers don't work and get replaced
in a subsequent patch.

Signed-off-by: Finn Thain 

---

Changed since v2:
- Fix NULL pointer dereference in NCR5380_reselect() when SUPPORT_TAGS is
  enabled in the atari_NCR5380.c core driver.

---
 drivers/scsi/NCR5380.c   |  214 +---
 drivers/scsi/NCR5380.h   |   16 ++
 drivers/scsi/arm/cumana_1.c  |1 
 drivers/scsi/arm/oak.c   |1 
 drivers/scsi/atari_NCR5380.c |  287 ++-
 drivers/scsi/atari_scsi.c|1 
 drivers/scsi/dmx3191d.c  |1 
 drivers/scsi/dtc.c   |1 
 drivers/scsi/g_NCR5380.c |1 
 drivers/scsi/mac_scsi.c  |1 
 drivers/scsi/pas16.c |1 
 drivers/scsi/sun3_scsi.c |1 
 drivers/scsi/t128.c  |1 
 13 files changed, 106 insertions(+), 421 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:56.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:58.0 +1100
@@ -622,8 +622,9 @@ static int NCR5380_init(struct Scsi_Host
 #endif
spin_lock_init(>lock);
hostdata->connected = NULL;
-   hostdata->issue_queue = NULL;
-   hostdata->disconnected_queue = NULL;
+   INIT_LIST_HEAD(>unissued);
+   INIT_LIST_HEAD(>disconnected);
+
hostdata->flags = flags;

INIT_WORK(>main_task, NCR5380_main);
@@ -738,7 +739,7 @@ static int NCR5380_queue_command(struct
  struct scsi_cmnd *cmd)
 {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
-   struct scsi_cmnd *tmp;
+   struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
@@ -752,12 +753,6 @@ static int NCR5380_queue_command(struct
}
 #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
-   /* 
-* We use the host_scribble field as a pointer to the next command  
-* in a queue 
-*/
-
-   cmd->host_scribble = NULL;
cmd->result = 0;
 
spin_lock_irqsave(>lock, flags);
@@ -769,13 +764,11 @@ static int NCR5380_queue_command(struct
 * sense data is only guaranteed to be valid while the condition exists.
 */
 
-   if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-   cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
-   hostdata->issue_queue = cmd;
-   } else {
-   for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; 
tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-   tmp->host_scribble = (unsigned char *) cmd;
-   }
+   if (cmd->cmnd[0] == REQUEST_SENSE)
+   list_add(>list, >unissued);
+   else
+   list_add_tail(>list, >unissued);
+
spin_unlock_irqrestore(>lock, flags);
 
dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n",
@@ -803,7 +796,7 @@ static void NCR5380_main(struct work_str
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
-   struct scsi_cmnd *tmp, *prev;
+   struct NCR5380_cmd *ncmd, *n;
int done;

spin_lock_irq(>lock);
@@ -816,23 +809,20 @@ static void NCR5380_main(struct work_str
 * Search through the issue_queue for a command destined
 * for a target that's not busy.
 */
-   for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, 
prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-   {
+   list_for_each_entry_safe(ncmd, n, >unissued,
+list) {
+   struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
+
dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p 
target=%d busy=%d lun=%llu\n",
 tmp, scmd_id(tmp), 
hostdata->busy[scmd_id(tmp)],
 tmp->device->lun);
/*  When we find one, remove it from the issue 
queue. */
if (!(hostdata->busy[tmp->device->id] &
  (1 << (u8)(tmp->device->lun & 0xff {
-   if (prev) {
-  

[PATCH v3 36/77] ncr5380: Use work_struct instead of delayed_work

2015-12-21 Thread Finn Thain
Each host instance now has it's own work queue so the main() work item can
sleep when necessary. That means we can use a simple work item rather than
a delayed work item. This brings NCR5380.c closer to atari_NCR5380.c.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |   12 +---
 drivers/scsi/NCR5380.h |1 -
 2 files changed, 5 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:23.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:24.0 +1100
@@ -697,7 +697,7 @@ static int NCR5380_init(struct Scsi_Host
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;

-   INIT_DELAYED_WORK(>coroutine, NCR5380_main);
+   INIT_WORK(>main_task, NCR5380_main);
hostdata->work_q = alloc_workqueue("ncr5380_%d",
WQ_UNBOUND | WQ_MEM_RECLAIM,
1, instance->host_no);
@@ -797,7 +797,7 @@ static void NCR5380_exit(struct Scsi_Hos
 {
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
 
-   cancel_delayed_work_sync(>coroutine);
+   cancel_work_sync(>main_task);
destroy_workqueue(hostdata->work_q);
 }
 
@@ -859,9 +859,8 @@ static int NCR5380_queue_command(struct
 
dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", 
instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-   /* Run the coroutine if it isn't already running. */
/* Kick off command processing */
-   queue_delayed_work(hostdata->work_q, >coroutine, 0);
+   queue_work(hostdata->work_q, >main_task);
return 0;
 }
 
@@ -880,7 +879,7 @@ static int NCR5380_queue_command(struct
 static void NCR5380_main(struct work_struct *work)
 {
struct NCR5380_hostdata *hostdata =
-   container_of(work, struct NCR5380_hostdata, coroutine.work);
+   container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *tmp, *prev;
int done;
@@ -1037,8 +1036,7 @@ static irqreturn_t NCR5380_intr(int dumm
}   /* if BASR_IRQ */
spin_unlock_irqrestore(instance->host_lock, flags);
if(!done)
-   queue_delayed_work(hostdata->work_q,
-  >coroutine, 0);
+   queue_work(hostdata->work_q, >main_task);
} while (!done);
return IRQ_HANDLED;
 }
Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:10.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:24.0 +1100
@@ -256,7 +256,6 @@ struct NCR5380_hostdata {
volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */
volatile struct scsi_cmnd *disconnected_queue;  /* waiting for 
reconnect */
int flags;
-   struct delayed_work coroutine;  /* our co-routine */
struct scsi_eh_save ses;
char info[256];
int read_overruns;/* number of bytes to cut from a


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 35/77] ncr5380: Dont wait for BUS FREE after disconnect

2015-12-21 Thread Finn Thain
When there is a queued command and no connected command, NCR5380_select()
is called and arbitration begins. The chip waits for BUS FREE once the
MR_ARBITRATE bit in the mode register is enabled. That means there is
no need to wait for BUS FREE after disconnecting.

There is presently no polling for BUS FREE after sending an ABORT or
other message that might lead to disconnection. It only happens after
COMMAND COMPLETE or DISCONNECT messages, which seems inconsistent.
Remove the polling for !BSY in the COMMAND COMPLETE and DISCONNECT
cases.

BTW, the comments say "avoid nasty timeouts" and perhaps BUS FREE polling
was somehow helpful back in Linux v0.99.14u, when it was introduced.
The relevant timeout is presently 1 second (for bus arbitration).

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |7 ---
 drivers/scsi/atari_NCR5380.c |   11 ---
 2 files changed, 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:22.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:23.0 +1100
@@ -1976,9 +1976,6 @@ static void NCR5380_information_transfer
 * arbitration can resume.
 */
NCR5380_write(TARGET_COMMAND_REG, 0);
-
-   while ((NCR5380_read(STATUS_REG) & 
SR_BSY) && !hostdata->connected)
-   barrier();
return;
case MESSAGE_REJECT:
/* Accept message by clearing ACK */
@@ -2011,10 +2008,6 @@ static void NCR5380_information_transfer
 
/* Enable reselect interrupts */

NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   /* Wait for bus free to avoid 
nasty timeouts - FIXME timeout !*/
-   /* 
NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */
-   while 
((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-   barrier();
return;
}
/* 
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:22.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:23.0 +1100
@@ -2213,7 +2213,6 @@ static void NCR5380_information_transfer
  "completed\n", HOSTNO, 
cmd->device->id, cmd->device->lun);
 
local_irq_save(flags);
-   hostdata->retain_dma_intr++;
hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
@@ -2282,8 +2281,6 @@ static void NCR5380_information_transfer
cmd->scsi_done(cmd);
}
 
-   local_irq_restore(flags);
-
NCR5380_write(SELECT_ENABLE_REG, 
hostdata->id_mask);
/*
 * Restore phase bits to 0 so an 
interrupted selection,
@@ -2291,11 +2288,6 @@ static void NCR5380_information_transfer
 */
NCR5380_write(TARGET_COMMAND_REG, 0);
 
-   while ((NCR5380_read(STATUS_REG) & 
SR_BSY) && !hostdata->connected)
-   barrier();
-
-   local_irq_save(flags);
-   hostdata->retain_dma_intr--;
/* ++roman: For Falcon SCSI, release 
the lock on the
 * ST-DMA here if no other commands are 
waiting on the
 * disconnected queue.
@@ -2349,9 +2341,6 @@ static void NCR5380_information_transfer
 
/* Enable reselect interrupts */
NCR5380_write(SELECT_ENABLE_REG, 
hostdata->id_mask);
-   /* Wait for bus free to avoid nasty 
timeouts */
-   while ((NCR5380_read(STATUS_REG) & 
SR_BSY) && !hostdata->connected)
-   

[PATCH v3 39/77] ncr5380: Standardize interrupt handling

2015-12-21 Thread Finn Thain
Because interrupt handling is crucial to the core driver(s), all wrapper
drivers need to agree on this code. This patch removes discrepancies.

NCR5380_intr() in NCR5380.c has the following pointless loop that differs
from the code in atari_NCR5380.c.

done = 1;
do {
/* ... */
} while (!done);

The 'done' flag gets cleared when a reconnected command is to be processed
from the work queue. But in NCR5380.c, the flag is also used to cause the
interrupt conditions to be re-examined. Perhaps this was because
NCR5380_reselect() was expected to cause another interrupt, or perhaps
the remaining present interrupt conditions need to be handled after the
NCR5380_reselect() call?

Actually, both possibilities are bogus, as is the loop itself. It seems
have been overlooked in the hit-and-miss removal of scsi host instance
list iteration many years ago; see history/history.git commit 491447e1fcff
("[PATCH] next NCR5380 updates") and commit 69e1a9482e57 ("[PATCH] fix up
NCR5380 private data"). See also my earlier patch, "Always retry
arbitration and selection".

The datasheet says, "IRQ can be reset simply by reading the Reset
Parity/Interrupt Register". So don't treat the chip IRQ like a
level-triggered interrupt. Of the conditions that set the IRQ flag,
some are level-triggered and some are edge-triggered, which means IRQ
itself must be edge-triggered.

Some interrupt conditions are latched and some are not. Before clearing
the chip IRQ flag, clear all state that may cause it to be raised. That
means clearing the DMA Mode and Busy Monitor bits in the Mode Register
and clearing the host ID in the Select Enable register.

Also clean up some printk's and some comments. Keep atari_NCR5380.c and
NCR5380.c in agreement.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  187 +++
 drivers/scsi/atari_NCR5380.c |  156 +--
 drivers/scsi/dtc.c   |8 -
 drivers/scsi/g_NCR5380.c |2 
 4 files changed, 180 insertions(+), 173 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:27.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:28.0 +1100
@@ -951,85 +951,114 @@ static void NCR5380_main(struct work_str
 #ifndef DONT_USE_INTR
 
 /**
- * NCR5380_intr-   generic NCR5380 irq handler
- * @irq: interrupt number
- * @dev_id: device info
- *
- * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
- *  from the disconnected queue, and restarting NCR5380_main() 
- *  as required.
- *
- * Locks: takes the needed instance locks
+ * NCR5380_intr - generic NCR5380 irq handler
+ * @irq: interrupt number
+ * @dev_id: device info
+ *
+ * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
+ * from the disconnected queue, and restarting NCR5380_main()
+ * as required.
+ *
+ * The chip can assert IRQ in any of six different conditions. The IRQ flag
+ * is then cleared by reading the Reset Parity/Interrupt Register (RPIR).
+ * Three of these six conditions are latched in the Bus and Status Register:
+ * - End of DMA (cleared by ending DMA Mode)
+ * - Parity error (cleared by reading RPIR)
+ * - Loss of BSY (cleared by reading RPIR)
+ * Two conditions have flag bits that are not latched:
+ * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode)
+ * - Bus reset (non-maskable)
+ * The remaining condition has no flag bit at all:
+ * - Selection/reselection
+ *
+ * Hence, establishing the cause(s) of any interrupt is partly guesswork.
+ * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor
+ * claimed that "the design of the [DP8490] interrupt logic ensures
+ * interrupts will not be lost (they can be on the DP5380)."
+ * The L5380/53C80 datasheet from LOGIC Devices has more details.
+ *
+ * Checking for bus reset by reading RST is futile because of interrupt
+ * latency, but a bus reset will reset chip logic. Checking for parity error
+ * is unnecessary because that interrupt is never enabled. A Loss of BSY
+ * condition will clear DMA Mode. We can tell when this occurs because the
+ * the Busy Monitor interrupt is enabled together with DMA Mode.
  */
 
-static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
+static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
struct Scsi_Host *instance = dev_id;
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
-   int done;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
+   int handled = 0;
unsigned char basr;
unsigned long flags;
 
-   dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n",
-   instance->irq);
+   spin_lock_irqsave(instance->host_lock, flags);
+
+   basr = 

[PATCH v3 55/77] ncr5380: Remove LIST and REMOVE macros

2015-12-21 Thread Finn Thain
Printing command pointers can be useful when debugging queues. Other than
that, the LIST and REMOVE macros are just clutter. These macros are
redundant now that NDEBUG_QUEUES causes pointers to be printed, so remove
them.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   19 ---
 drivers/scsi/atari_NCR5380.c |   32 
 2 files changed, 51 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:54.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:56.0 +1100
@@ -80,14 +80,6 @@
  *  tagged queueing)
  */
 
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), 
(void*)(y)); if ((x)==(y)) udelay(5); }
-#define REMOVE(w,x,y,z) {printk("LINE:%d   Removing: %p->%p  %p->%p \n", 
__LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) 
udelay(5); }
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
 #ifndef notyet
 #undef REAL_DMA
 #endif
@@ -778,12 +770,10 @@ static int NCR5380_queue_command(struct
 */
 
if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-   LIST(cmd, hostdata->issue_queue);
cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
hostdata->issue_queue = cmd;
} else {
for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; 
tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-   LIST(cmd, tmp);
tmp->host_scribble = (unsigned char *) cmd;
}
spin_unlock_irqrestore(>lock, flags);
@@ -835,10 +825,8 @@ static void NCR5380_main(struct work_str
if (!(hostdata->busy[tmp->device->id] &
  (1 << (u8)(tmp->device->lun & 0xff {
if (prev) {
-   REMOVE(prev, 
prev->host_scribble, tmp, tmp->host_scribble);
prev->host_scribble = 
tmp->host_scribble;
} else {
-   REMOVE(-1, 
hostdata->issue_queue, tmp, tmp->host_scribble);
hostdata->issue_queue = (struct 
scsi_cmnd *) tmp->host_scribble;
}
tmp->host_scribble = NULL;
@@ -863,7 +851,6 @@ static void NCR5380_main(struct work_str
/* OK or bad target */
} else {
/* Need to retry */
-   LIST(tmp, 
hostdata->issue_queue);
tmp->host_scribble = (unsigned 
char *) hostdata->issue_queue;
hostdata->issue_queue = tmp;
dsprintk(NDEBUG_MAIN | 
NDEBUG_QUEUES,
@@ -1888,7 +1875,6 @@ static void NCR5380_information_transfer
if ((cmd->cmnd[0] != REQUEST_SENSE) && 
(status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
scsi_eh_prep_cmnd(cmd, 
>ses, NULL, 0, ~0);
 
-   LIST(cmd, 
hostdata->issue_queue);
cmd->host_scribble = (unsigned 
char *)
hostdata->issue_queue;
hostdata->issue_queue = (struct 
scsi_cmnd *) cmd;
@@ -1925,7 +1911,6 @@ static void NCR5380_information_transfer
case DISCONNECT:{
/* Accept message by clearing 
ACK */

NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-   LIST(cmd, 
hostdata->disconnected_queue);
cmd->host_scribble = (unsigned 
char *)

hostdata->disconnected_queue;
hostdata->connected = NULL;
@@ -2175,10 +2160,8 @@ static void NCR5380_reselect(struct Scsi
 tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
if ((target_mask == (1 << tmp->device->id)) && (lun == 
(u8)tmp->device->lun)) {
if (prev) {
-   REMOVE(prev, prev->host_scribble, tmp, 
tmp->host_scribble);
prev->host_scribble = tmp->host_scribble;
} else {
- 

[PATCH v3 47/77] ncr5380: Fix and cleanup scsi_host_template initializers

2015-12-21 Thread Finn Thain
Add missing .module initializer. Use distinct .proc_name values for the
g_NCR5380 and g_NCR5380_mmio modules. Remove pointless CAN_QUEUE and
CMD_PER_LUN override macros. Cleanup whitespace and code style.

Signed-off-by: Finn Thain 

---
 drivers/scsi/atari_scsi.c |2 +-
 drivers/scsi/dmx3191d.c   |1 +
 drivers/scsi/dtc.c|   32 
 drivers/scsi/dtc.h|8 
 drivers/scsi/g_NCR5380.c  |   26 +-
 drivers/scsi/g_NCR5380.h  |   10 ++
 drivers/scsi/mac_scsi.c   |   28 ++--
 drivers/scsi/pas16.c  |   32 
 drivers/scsi/pas16.h  |8 
 drivers/scsi/sun3_scsi.c  |6 +++---
 drivers/scsi/t128.c   |   32 
 drivers/scsi/t128.h   |8 
 12 files changed, 82 insertions(+), 111 deletions(-)

Index: linux/drivers/scsi/dmx3191d.c
===
--- linux.orig/drivers/scsi/dmx3191d.c  2015-12-22 12:16:37.0 +1100
+++ linux/drivers/scsi/dmx3191d.c   2015-12-22 12:16:41.0 +1100
@@ -49,6 +49,7 @@
 
 
 static struct scsi_host_template dmx3191d_driver_template = {
+   .module = THIS_MODULE,
.proc_name  = DMX3191D_DRIVER_NAME,
.name   = "Domex DMX3191D",
.info   = NCR5380_info,
Index: linux/drivers/scsi/dtc.c
===
--- linux.orig/drivers/scsi/dtc.c   2015-12-22 12:16:37.0 +1100
+++ linux/drivers/scsi/dtc.c2015-12-22 12:16:41.0 +1100
@@ -436,21 +436,21 @@ static int dtc_release(struct Scsi_Host
 }
 
 static struct scsi_host_template driver_template = {
-   .name   = "DTC 3180/3280 ",
-   .detect = dtc_detect,
-   .release= dtc_release,
-   .proc_name  = "dtc3x80",
-   .show_info  = dtc_show_info,
-   .write_info = dtc_write_info,
-   .info   = dtc_info,
-   .queuecommand   = dtc_queue_command,
-   .eh_abort_handler   = dtc_abort,
-   .eh_bus_reset_handler   = dtc_bus_reset,
-   .bios_param = dtc_biosparam,
-   .can_queue  = CAN_QUEUE,
-   .this_id= 7,
-   .sg_tablesize   = SG_ALL,
-   .cmd_per_lun= CMD_PER_LUN,
-   .use_clustering = DISABLE_CLUSTERING,
+   .name   = "DTC 3180/3280",
+   .detect = dtc_detect,
+   .release= dtc_release,
+   .proc_name  = "dtc3x80",
+   .show_info  = dtc_show_info,
+   .write_info = dtc_write_info,
+   .info   = dtc_info,
+   .queuecommand   = dtc_queue_command,
+   .eh_abort_handler   = dtc_abort,
+   .eh_bus_reset_handler   = dtc_bus_reset,
+   .bios_param = dtc_biosparam,
+   .can_queue  = 32,
+   .this_id= 7,
+   .sg_tablesize   = SG_ALL,
+   .cmd_per_lun= 2,
+   .use_clustering = DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/dtc.h
===
--- linux.orig/drivers/scsi/dtc.h   2015-12-22 12:16:07.0 +1100
+++ linux/drivers/scsi/dtc.h2015-12-22 12:16:41.0 +1100
@@ -10,14 +10,6 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
 #define NCR5380_implementation_fields \
 void __iomem *base
 
Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:16:37.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:16:41.0 +1100
@@ -305,7 +305,6 @@ static int __init generic_NCR5380_detect
}
}
 #endif
-   tpnt->proc_name = "g_NCR5380";
 
for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
if (!(overrides[current_override].NCR5380_map_name))
@@ -715,20 +714,21 @@ static int generic_NCR5380_dma_xfer_len(
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-   .show_info  = generic_NCR5380_show_info,
-   .name   = "Generic NCR5380/NCR53C400 SCSI",
-   .detect = generic_NCR5380_detect,
-   .release= generic_NCR5380_release_resources,
-   .info   = generic_NCR5380_info,
-   .queuecommand   = 

[PATCH v3 52/77] ncr5380: Remove H_NO macro and introduce dsprintk

2015-12-21 Thread Finn Thain
Replace all H_NO and some HOSTNO macros (both peculiar to atari_NCR5380.c)
with a new dsprintk macro that's more useful and more consistent. The new
macro avoids a lot of boilerplate in new code in subsequent patches. Keep
NCR5380.c in sync. Remaining HOSTNO macros are removed as side-effects
of subsequent patches.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |9 ---
 drivers/scsi/NCR5380.h   |5 +++
 drivers/scsi/atari_NCR5380.c |   54 +--
 3 files changed, 38 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:16:47.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:16:51.0 +1100
@@ -285,6 +285,11 @@ struct NCR5380_hostdata {
do { if ((NDEBUG) & (flg)) \
printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0)
 
+#define dsprintk(flg, host, fmt, ...) \
+   do { if ((NDEBUG) & (flg)) \
+   shost_printk(KERN_DEBUG, host, fmt, ## __VA_ARGS__); \
+   } while (0)
+
 #if NDEBUG
 #define NCR5380_dprint(flg, arg) \
do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0)
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:49.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:51.0 +1100
@@ -207,7 +207,6 @@
 #defineNEXTADDR(cmd)   ((struct scsi_cmnd 
**)&(cmd)->host_scribble)
 
 #defineHOSTNO  instance->host_no
-#defineH_NO(cmd)   (cmd)->device->host->host_no
 
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
@@ -280,7 +279,8 @@ static void __init init_tags(struct NCR5
 static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 {
u8 lun = cmd->device->lun;
-   SETUP_HOSTDATA(cmd->device->host);
+   struct Scsi_Host *instance = cmd->device->host;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
if (hostdata->busy[cmd->device->id] & (1 << lun))
return 1;
@@ -290,8 +290,8 @@ static int is_lun_busy(struct scsi_cmnd
return 0;
if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-   dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
-  H_NO(cmd), cmd->device->id, lun);
+   dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free 
tags\n",
+scmd_id(cmd), lun);
return 1;
}
return 0;
@@ -306,7 +306,8 @@ static int is_lun_busy(struct scsi_cmnd
 static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 {
u8 lun = cmd->device->lun;
-   SETUP_HOSTDATA(cmd->device->host);
+   struct Scsi_Host *instance = cmd->device->host;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
/* If we or the target don't support tagged queuing, allocate the LUN 
for
 * an untagged command.
@@ -316,18 +317,16 @@ static void cmd_get_tag(struct scsi_cmnd
!cmd->device->tagged_supported) {
cmd->tag = TAG_NONE;
hostdata->busy[cmd->device->id] |= (1 << lun);
-   dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by 
untagged "
-  "command\n", H_NO(cmd), cmd->device->id, lun);
+   dsprintk(NDEBUG_TAGS, instance, "target %d lun %d now allocated 
by untagged command\n",
+scmd_id(cmd), lun);
} else {
struct tag_alloc *ta = >TagAlloc[scmd_id(cmd)][lun];
 
cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
set_bit(cmd->tag, ta->allocated);
ta->nr_allocated++;
-   dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d 
"
-  "(now %d tags in use)\n",
-  H_NO(cmd), cmd->tag, cmd->device->id,
-  lun, ta->nr_allocated);
+   dsprintk(NDEBUG_TAGS, instance, "using tag %d for target %d lun 
%d (%d tags allocated)\n",
+cmd->tag, scmd_id(cmd), lun, ta->nr_allocated);
}
 }
 
@@ -339,21 +338,22 @@ static void cmd_get_tag(struct scsi_cmnd
 static void cmd_free_tag(struct scsi_cmnd *cmd)
 {
u8 lun = cmd->device->lun;
-   SETUP_HOSTDATA(cmd->device->host);
+   struct Scsi_Host *instance = cmd->device->host;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
if (cmd->tag == TAG_NONE) {
hostdata->busy[cmd->device->id] &= ~(1 << lun);
-   dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd 

[PATCH v3 42/77] ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS

2015-12-21 Thread Finn Thain
The workarounds for chip errata appear twice, in slightly different
forms. One is used when defined(REAL_DMA) || defined(REAL_DMA_POLL), the
other when defined(PSEUDO_DMA). In the PDMA case, the workarounds have
been made conditional on FLAG_NO_DMA_FIXUPS. Do the same for the DMA case,
to eliminate the READ_OVERRUNS macro.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |   28 +++-
 1 file changed, 11 insertions(+), 17 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:32.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:34.0 +1100
@@ -94,11 +94,6 @@
 #undef REAL_DMA
 #endif
 
-#ifdef REAL_DMA_POLL
-#undef READ_OVERRUNS
-#define READ_OVERRUNS
-#endif
-
 #ifdef BOARD_REQUIRES_NO_DELAY
 #define io_recovery_delay(x)
 #else
@@ -1586,11 +1581,10 @@ static int NCR5380_transfer_dma(struct S
return -1;
}
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-#ifdef READ_OVERRUNS
if (p & SR_IO) {
-   c -= 2;
+   if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
+   c -= 2;
}
-#endif
dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d 
bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? 
"reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, 
c) : NCR5380_dma_write_setup(instance, d, c);
 #endif
@@ -1676,13 +1670,14 @@ static int NCR5380_transfer_dma(struct S
  */
 
if (p & SR_IO) {
-#ifdef READ_OVERRUNS
-   udelay(10);
-   if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | 
BASR_ACK)) == (BASR_PHASE_MATCH | BASR_ACK))) {
-   saved_data = NCR5380_read(INPUT_DATA_REGISTER);
-   overrun = 1;
+   if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS)) {
+   udelay(10);
+   if ((NCR5380_read(BUS_AND_STATUS_REG) & 
(BASR_PHASE_MATCH | BASR_ACK)) ==
+   (BASR_PHASE_MATCH | BASR_ACK)) {
+   saved_data = NCR5380_read(INPUT_DATA_REGISTER);
+   overrun = 1;
+   }
}
-#endif
} else {
int limit = 100;
while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || 
(NCR5380_read(STATUS_REG) & SR_REQ)) {
@@ -1704,8 +1699,8 @@ static int NCR5380_transfer_dma(struct S
*data += c;
*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
-#ifdef READ_OVERRUNS
-   if (*phase == p && (p & SR_IO) && residue == 0) {
+   if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS) &&
+   *phase == p && (p & SR_IO) && residue == 0) {
if (overrun) {
dprintk(NDEBUG_DMA, "Got an input overrun, using saved 
byte\n");
**data = saved_data;
@@ -1720,7 +1715,6 @@ static int NCR5380_transfer_dma(struct S
NCR5380_transfer_pio(instance, phase, , data);
*count -= toPIO - cnt;
}
-#endif
 
dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, 
next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count));
return 0;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 32/77] ncr5380: Fix bus phase in do_abort()

2015-12-21 Thread Finn Thain
NCR5380_poll_politely() returns either 0 (success) or -ETIMEDOUT. However,
in do_abort(), the return value is incorrectly taken to be the status
register value. This means that the bus is put into DATA OUT phase instead
of MESSAGE OUT. Fix this.

Signed-off-by: Finn Thain 

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

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:18.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:19.0 +1100
@@ -1493,11 +1493,11 @@ static int do_abort(struct Scsi_Host *in
if (rc < 0)
return -1;
 
-   tmp = (unsigned char)rc;
+   tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;

NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-   if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
+   if (tmp != PHASE_MSGOUT) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN 
| ICR_ASSERT_ACK);
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * 
HZ);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 40/77] ncr5380: Introduce NCR5380_poll_politely2

2015-12-21 Thread Finn Thain
SCSI bus protocol sometimes requires monitoring two related conditions
simultaneously. Enhance NCR5380_poll_politely() for this purpose, and
put it to use in the arbitration algorithm. It will also find use in
pseudo DMA.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   66 ---
 drivers/scsi/atari_NCR5380.c |   62 
 2 files changed, 75 insertions(+), 53 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:28.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:30.0 +1100
@@ -457,11 +457,14 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for chip register value
+ * NCR5380_poll_politely2 - wait for two chip register values
  * @instance: controller to poll
- * @reg: 5380 register to poll
- * @bit: Bitmask to check
- * @val: Value required to exit
+ * @reg1: 5380 register to poll
+ * @bit1: Bitmask to check
+ * @val1: Expected value
+ * @reg2: Second 5380 register to poll
+ * @bit2: Second bitmask to check
+ * @val2: Second expected value
  * @wait: Time-out in jiffies
  *
  * Polls the chip in a reasonably efficient manner waiting for an
@@ -469,11 +472,12 @@ static inline void initialize_SCp(struct
  * (if possible). In irq contexts the time-out is arbitrarily limited.
  * Callers may hold locks as long as they are held in irq mode.
  *
- * Returns 0 if event occurred otherwise -ETIMEDOUT.
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
  */
 
-static int NCR5380_poll_politely(struct Scsi_Host *instance,
- int reg, int bit, int val, int wait)
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+  int reg1, int bit1, int val1,
+  int reg2, int bit2, int val2, int wait)
 {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned long deadline = jiffies + wait;
@@ -482,9 +486,11 @@ static int NCR5380_poll_politely(struct
/* Busy-wait for up to 10 ms */
n = min(1U, jiffies_to_usecs(wait));
n *= hostdata->accesses_per_ms;
-   n /= 1000;
+   n /= 2000;
do {
-   if ((NCR5380_read(reg) & bit) == val)
+   if ((NCR5380_read(reg1) & bit1) == val1)
+   return 0;
+   if ((NCR5380_read(reg2) & bit2) == val2)
return 0;
cpu_relax();
} while (n--);
@@ -495,13 +501,22 @@ static int NCR5380_poll_politely(struct
/* Repeatedly sleep for 1 ms until deadline */
while (time_is_after_jiffies(deadline)) {
schedule_timeout_uninterruptible(1);
-   if ((NCR5380_read(reg) & bit) == val)
+   if ((NCR5380_read(reg1) & bit1) == val1)
+   return 0;
+   if ((NCR5380_read(reg2) & bit2) == val2)
return 0;
}
 
return -ETIMEDOUT;
 }
 
+static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
+int reg, int bit, int val, int wait)
+{
+   return NCR5380_poll_politely2(instance, reg, bit, val,
+   reg, bit, val, wait);
+}
+
 #include 
 
 #if NDEBUG
@@ -1348,7 +1363,6 @@ static int NCR5380_select(struct Scsi_Ho
int len;
int err;
unsigned long flags;
-   unsigned long timeout;
 
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", 
HOSTNO,
@@ -1378,20 +1392,18 @@ static int NCR5380_select(struct Scsi_Ho
 */
 
local_irq_restore(flags);
-   timeout = jiffies + HZ;
-   while (1) {
-   if (time_is_before_jiffies(timeout)) {
-   NCR5380_write(MODE_REG, MR_BASE);
-   shost_printk(KERN_ERR, instance,
-"select: arbitration timeout\n");
-   return -1;
-   }
-   if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-   /* Reselection interrupt */
-   return -1;
-   }
-   if (NCR5380_read(INITIATOR_COMMAND_REG) & 
ICR_ARBITRATION_PROGRESS)
-   break;
+   err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+   INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+  ICR_ARBITRATION_PROGRESS, HZ);
+   if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+   /* Reselection interrupt */
+   return -1;
+   }
+   if (err < 0) {
+   NCR5380_write(MODE_REG, MR_BASE);
+   

[PATCH v3 31/77] ncr5380: Fix !REQ timeout in do_abort()

2015-12-21 Thread Finn Thain
NCR5380_poll_politely() never returns -1. That means do_abort() can fail
to handle a timeout after waiting for the target to negate REQ. Fix this
and cleanup other NCR5380_poll_politely() call sites.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:17.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:18.0 +1100
@@ -1271,7 +1271,7 @@ static int NCR5380_select(struct Scsi_Ho
err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
spin_lock_irq(instance->host_lock);

-   if(err) {
+   if (err < 0) {
printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", 
instance->host_no, __LINE__);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
@@ -1490,8 +1490,7 @@ static int do_abort(struct Scsi_Host *in
 */
 
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * 
HZ);
-   
-   if(rc < 0)
+   if (rc < 0)
return -1;
 
tmp = (unsigned char)rc;
@@ -1502,7 +1501,7 @@ static int do_abort(struct Scsi_Host *in
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN 
| ICR_ASSERT_ACK);
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * 
HZ);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-   if(rc == -1)
+   if (rc < 0)
return -1;
}
tmp = ABORT;
@@ -2199,7 +2198,8 @@ static void NCR5380_reselect(struct Scsi
 * FIXME: timeout needed and fail to work queeu
 */
 
-   if(NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 2*HZ))
+   if (NCR5380_poll_politely(instance,
+ STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0)
abort = 1;
 
len = 1;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 48/77] atari_NCR5380: Fix queue_size limit

2015-12-21 Thread Finn Thain
When a target reports a QUEUE_FULL condition it causes the driver to
update the 'queue_size' limit with the number of currently allocated tags.
At least, that's what's supposed to happen, according to the comments.
Unfortunately the terms in the assignment are swapped. Fix this and
cleanup some obsolete comments.

Signed-off-by: Finn Thain 

---
 drivers/scsi/atari_NCR5380.c |   14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:37.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:44.0 +1100
@@ -229,9 +229,7 @@ static void do_reset(struct Scsi_Host *)
  * cannot know it in advance :-( We just see a QUEUE_FULL status being
  * returned. So, in this case, the driver internal queue size assumption is
  * reduced to the number of active tags if QUEUE_FULL is returned by the
- * target. The command is returned to the mid-level, but with status changed
- * to BUSY, since --as I've seen-- the mid-level can't handle QUEUE_FULL
- * correctly.
+ * target.
  *
  * We're also not allowed running tagged commands as long as an untagged
  * command is active. And REQUEST SENSE commands after a contingent allegiance
@@ -2152,21 +2150,13 @@ static void NCR5380_information_transfer
 #ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
if (status_byte(cmd->SCp.Status) == 
QUEUE_FULL) {
-   /* Turn a QUEUE FULL status 
into BUSY, I think the
-* mid level cannot handle 
QUEUE FULL :-( (The
-* command is retried after 
BUSY). Also update our
-* queue size to the number of 
currently issued
-* commands now.
-*/
-   /* ++Andreas: the mid level 
code knows about
-  QUEUE_FULL now. */
struct tag_alloc *ta = 
>TagAlloc[scmd_id(cmd)][cmd->device->lun];
dprintk(NDEBUG_TAGS, "scsi%d: 
target %d lun %llu returned "
   "QUEUE_FULL after %d 
commands\n",
   HOSTNO, 
cmd->device->id, cmd->device->lun,
   ta->nr_allocated);
if (ta->queue_size > 
ta->nr_allocated)
-   ta->nr_allocated = 
ta->queue_size;
+   ta->queue_size = 
ta->nr_allocated;
}
 #else
hostdata->busy[cmd->device->id] &= ~(1 
<< cmd->device->lun);


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/3] hpsa: add box and bay information for enclosure devices

2015-12-21 Thread Matthew R. Ochs
Reviewed-by: Matthew R. Ochs 

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] badblocks: Add core badblock management code

2015-12-21 Thread NeilBrown
On Sat, Dec 05 2015, Verma, Vishal L wrote:

> On Fri, 2015-12-04 at 15:30 -0800, James Bottomley wrote:
> [...]
>> > +ssize_t badblocks_store(struct badblocks *bb, const char *page,
>> > size_t len,
>> > +  int unack)
>> [...]
>> > +int badblocks_init(struct badblocks *bb, int enable)
>> > +{
>> > +  bb->count = 0;
>> > +  if (enable)
>> > +  bb->shift = 0;
>> > +  else
>> > +  bb->shift = -1;
>> > +  bb->page = kmalloc(PAGE_SIZE, GFP_KERNEL);
>> 
>> Why not __get_free_page(GFP_KERNEL)?  The problem with kmalloc of an
>> exactly known page sized quantity is that the slab tracker for this
>> requires two contiguous pages for each page because of the overhead.
>
> Cool, I didn't know about __get_free_page - I can fix this up too.
>

I was reminded of this just recently I thought I should clear up the
misunderstanding.

kmalloc(PAGE_SIZE) does *not* incur significant overhead and certainly
does not require two contiguous free pages.
If you "grep kmalloc-4096 /proc/slabinfo" you will note that both
objperslab and pagesperslab are 1.  So one page is used to store each
4096 byte allocation.

To quote the email from Linus which reminded me about this

> If you
> want to allocate a page, and get a pointer, just use "kmalloc()".
> Boom, done!

https://lkml.org/lkml/2015/12/21/605

There probably is a small CPU overhead from using kmalloc, but no memory
overhead.

NeilBrown


signature.asc
Description: PGP signature


[PATCH v3 04/77] ncr5380: Remove more pointless macros

2015-12-21 Thread Finn Thain
ASM macro is never defined. rtrc in pas16.c is not used.
NCR5380_map_config, do_NCR5380_intr, do_t128_intr and do_pas16_intr
are unused. NCR_NOT_SET harms readability. Remove them.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.h   |3 ---
 drivers/scsi/g_NCR5380.c |   29 ++---
 drivers/scsi/g_NCR5380.h |5 -
 drivers/scsi/pas16.c |   16 
 drivers/scsi/pas16.h |5 -
 drivers/scsi/t128.h  |4 
 6 files changed, 14 insertions(+), 48 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:15:28.0 +1100
@@ -244,8 +244,6 @@
 #define FLAG_LATE_DMA_SETUP32  /* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING64  /* as X3T9.2 spelled it */
 
-#ifndef ASM
-
 #ifdef SUPPORT_TAGS
 struct tag_alloc {
DECLARE_BITMAP(allocated, MAX_TAGS);
@@ -443,5 +441,4 @@ static __inline__ int NCR5380_pc_dma_res
 #endif /* defined(i386) || defined(__alpha__) */
 #endif /* defined(REAL_DMA)  */
 #endif /* __KERNEL__ */
-#endif /* ndef ASM */
 #endif /* NCR5380_H */
Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:15:24.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:15:28.0 +1100
@@ -82,14 +82,13 @@
 #include 
 #include 
 
-#define NCR_NOT_SET 0
-static int ncr_irq = NCR_NOT_SET;
-static int ncr_dma = NCR_NOT_SET;
-static int ncr_addr = NCR_NOT_SET;
-static int ncr_5380 = NCR_NOT_SET;
-static int ncr_53c400 = NCR_NOT_SET;
-static int ncr_53c400a = NCR_NOT_SET;
-static int dtc_3181e = NCR_NOT_SET;
+static int ncr_irq;
+static int ncr_dma;
+static int ncr_addr;
+static int ncr_5380;
+static int ncr_53c400;
+static int ncr_53c400a;
+static int dtc_3181e;
 
 static struct override {
NCR5380_map_type NCR5380_map_name;
@@ -271,19 +270,19 @@ static int __init generic_NCR5380_detect
void __iomem *iomem;
 #endif
 
-   if (ncr_irq != NCR_NOT_SET)
+   if (ncr_irq)
overrides[0].irq = ncr_irq;
-   if (ncr_dma != NCR_NOT_SET)
+   if (ncr_dma)
overrides[0].dma = ncr_dma;
-   if (ncr_addr != NCR_NOT_SET)
+   if (ncr_addr)
overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
-   if (ncr_5380 != NCR_NOT_SET)
+   if (ncr_5380)
overrides[0].board = BOARD_NCR5380;
-   else if (ncr_53c400 != NCR_NOT_SET)
+   else if (ncr_53c400)
overrides[0].board = BOARD_NCR53C400;
-   else if (ncr_53c400a != NCR_NOT_SET)
+   else if (ncr_53c400a)
overrides[0].board = BOARD_NCR53C400A;
-   else if (dtc_3181e != NCR_NOT_SET)
+   else if (dtc_3181e)
overrides[0].board = BOARD_DTC3181E;
 #ifndef SCSI_G_NCR5380_MEM
if (!current_override && isapnp_present()) {
Index: linux/drivers/scsi/g_NCR5380.h
===
--- linux.orig/drivers/scsi/g_NCR5380.h 2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/g_NCR5380.h  2015-12-22 12:15:28.0 +1100
@@ -21,8 +21,6 @@
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -36,7 +34,6 @@
 
 #ifndef SCSI_G_NCR5380_MEM
 
-#define NCR5380_map_config port
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 #define NCR5380_instance_name io_port
@@ -64,7 +61,6 @@
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
 
-#define NCR5380_map_config memory
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
 #define NCR5380_instance_name base
@@ -103,6 +99,5 @@
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E 3
 
-#endif /* ndef ASM */
 #endif /* GENERIC_NCR5380_H */
 
Index: linux/drivers/scsi/pas16.c
===
--- linux.orig/drivers/scsi/pas16.c 2015-12-22 12:15:26.0 +1100
+++ linux/drivers/scsi/pas16.c  2015-12-22 12:15:28.0 +1100
@@ -145,22 +145,6 @@ static const unsigned short  pas16_offse
* START_DMA_INITIATOR_RECEIVE_REG wo
*/
 };
-/**/
-/* the following will set the monitor border color (useful to find
- where something crashed or gets stuck at */
-/* 1 = blue
- 2 = green
- 3 = cyan
- 4 = red
- 5 = magenta
- 6 = yellow
- 7 = white
-*/
-#if 1
-#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
 
 
 /*
Index: 

[PATCH v3 08/77] ncr5380: Move NCR53C400-specific code

2015-12-21 Thread Finn Thain
Move board-specific code like this,
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
from the core driver to the board driver. Eliminate the NCR53C400 macro
from the core driver. Removal of all macros like this one will be
necessary in order to have one core driver that can support all kinds of
boards.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---

Changed since v1:
- Don't set FLAG_NO_PSEUDO_DMA when !defined(PSEUDO_DMA). It's pointless.

---
 drivers/scsi/NCR5380.c   |   18 --
 drivers/scsi/g_NCR5380.c |   21 -
 drivers/scsi/g_NCR5380.h |6 ++
 3 files changed, 18 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:35.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:38.0 +1100
@@ -654,9 +654,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef UNSAFE
 "UNSAFE "
 #endif
-#ifdef NCR53C400
-"NCR53C400 "
-#endif
 "");
 }
 
@@ -782,15 +779,6 @@ static int NCR5380_init(struct Scsi_Host
 
if(in_interrupt())
printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-   /* 
-* On NCR53C400 boards, NCR5380 registers are mapped 8 past 
-* the base address.
-*/
-
-#ifdef NCR53C400
-   if (flags & FLAG_NCR53C400)
-   instance->io_port += NCR53C400_address_adjust;
-#endif
 
hostdata->aborted = 0;
hostdata->id_mask = 1 << instance->this_id;
@@ -824,12 +812,6 @@ static int NCR5380_init(struct Scsi_Host
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, 0);
-
-#ifdef NCR53C400
-   if (hostdata->flags & FLAG_NCR53C400) {
-   NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-   }
-#endif
return 0;
 }
 
Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:15:35.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:15:38.0 +1100
@@ -64,9 +64,7 @@
 #define AUTOPROBE_IRQ
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR53C400_PSEUDO_DMA 1
 #define PSEUDO_DMA
-#define NCR53C400
 #endif
 
 #include 
@@ -263,7 +261,7 @@ static int __init generic_NCR5380_detect
static unsigned int __initdata dtc_3181e_ports[] = {
0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
};
-   int flags = 0;
+   int flags;
struct Scsi_Host *instance;
 #ifdef SCSI_G_NCR5380_MEM
unsigned long base;
@@ -324,12 +322,15 @@ static int __init generic_NCR5380_detect
continue;
 
ports = NULL;
+   flags = 0;
switch (overrides[current_override].board) {
case BOARD_NCR5380:
flags = FLAG_NO_PSEUDO_DMA;
break;
case BOARD_NCR53C400:
+#ifdef PSEUDO_DMA
flags = FLAG_NCR53C400;
+#endif
break;
case BOARD_NCR53C400A:
flags = FLAG_NO_PSEUDO_DMA;
@@ -415,6 +416,13 @@ static int __init generic_NCR5380_detect
 #ifndef SCSI_G_NCR5380_MEM
instance->io_port = 
overrides[current_override].NCR5380_map_name;
instance->n_io_port = region_size;
+
+   /*
+* On NCR53C400 boards, NCR5380 registers are mapped 8 past
+* the base address.
+*/
+   if (overrides[current_override].board == BOARD_NCR53C400)
+   instance->io_port += 8;
 #else
instance->base = overrides[current_override].NCR5380_map_name;
((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
@@ -422,6 +430,9 @@ static int __init generic_NCR5380_detect
 
NCR5380_init(instance, flags);
 
+   if (overrides[current_override].board == BOARD_NCR53C400)
+   NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+
NCR5380_maybe_reset_bus(instance);
 
if (overrides[current_override].irq != IRQ_AUTO)
@@ -506,7 +517,7 @@ generic_NCR5380_biosparam(struct scsi_de
 }
 #endif
 
-#ifdef NCR53C400_PSEUDO_DMA
+#ifdef PSEUDO_DMA
 
 /**
  * NCR5380_pread   -   pseudo DMA read
@@ -690,7 +701,7 @@ static inline int NCR5380_pwrite(struct
;   // TIMEOUT
return 0;
 }
-#endif /* PSEUDO_DMA */
+#endif /* PSEUDO_DMA */
 
 /*
  * Include the NCR5380 core code that we build our driver around   
Index: linux/drivers/scsi/g_NCR5380.h
===
--- 

[PATCH v3 05/77] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros

2015-12-21 Thread Finn Thain
The NCR5380_local_declare and NCR5380_setup macros exist to define and
initialize a particular local variable, to provide the address of the
chip registers needed for the driver's implementation of its
NCR5380_read/write register access macros.

In cumana_1 and macscsi, these macros generate pointless code like this,
struct Scsi_Host *_instance;
_instance = instance;

In pas16, the use of NCR5380_read/write in pas16_hw_detect() requires that
the io_port local variable has been defined and initialized, but the
NCR5380_local_declare and NCR5380_setup macros can't be used for that
purpose because the Scsi_Host struct has not yet been instantiated.

Moreover, these macros were removed from atari_NCR5380.c long ago and
now they constitute yet another discrepancy between the two core driver
forks.

Remove these "optimizations".

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---

Any performance penalty is highly unlikely given the algorithms involved
and the improvements made to compilers over the last two decades. (And
I'd probably accept some loss anyway given the maintainability benefit.)

Following the example of atari_NCR5380.c, the Scsi_Host pointer is now
always named "instance", and the NCR5380_read/write macros depend on this.
I think it is poor style to hard-code the identifier "instance" in these
macros but it is actually an improvement -- previously each NCR5380 driver
named a different local variable in its macro definitions.

Eventually, the NCR5380_read/write macros may have to become function
calls if this is to become a platform driver or a library. The instance
pointer or hostdata pointer will then have to be passed as an argument.

This patch is a step in that direction, in that it rewrites the
NCR5380_read/write macros in terms of hostdata and removes the
NCR5380_read/write usage from pas16_hw_detect() where there is no
Scsi_Host instance as yet.

---
 drivers/scsi/NCR5380.c  |   60 ++--
 drivers/scsi/arm/cumana_1.c |6 +---
 drivers/scsi/arm/oak.c  |9 +++---
 drivers/scsi/dmx3191d.c |6 +---
 drivers/scsi/dtc.c  |   14 +++---
 drivers/scsi/dtc.h  |9 +-
 drivers/scsi/g_NCR5380.c|   27 ++-
 drivers/scsi/g_NCR5380.h|   30 --
 drivers/scsi/mac_scsi.c |   15 +--
 drivers/scsi/pas16.c|   16 +--
 drivers/scsi/pas16.h|   11 +---
 drivers/scsi/t128.c |   26 +--
 drivers/scsi/t128.h |9 +-
 13 files changed, 77 insertions(+), 161 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:24.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:30.0 +1100
@@ -230,11 +230,6 @@
  * USLEEP_POLL - amount of time, in jiffies, to poll
  *
  * These macros MUST be defined :
- * NCR5380_local_declare() - declare any local variables needed for your
- *  transfer routines.
- *
- * NCR5380_setup(instance) - initialize any local variables needed from a given
- *  instance of the host adapter for NCR5380_{read,write,pread,pwrite}
  * 
  * NCR5380_read(register)  - read from the specified register
  *
@@ -267,8 +262,8 @@
  * possible) function may be used.
  */
 
-static int do_abort(struct Scsi_Host *host);
-static void do_reset(struct Scsi_Host *host);
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
 
 /*
  * initialize_SCp  -   init the scsi pointer field
@@ -313,12 +308,9 @@ static inline void initialize_SCp(struct
  
 static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, 
int val, int t)
 {
-   NCR5380_local_declare();
int n = 500;/* At about 8uS a cycle for the cpu access */
unsigned long end = jiffies + t;
int r;
-   
-   NCR5380_setup(instance);
 
while( n-- > 0)
{
@@ -406,9 +398,7 @@ mrs[] = {
 
 static void NCR5380_print(struct Scsi_Host *instance)
 {
-   NCR5380_local_declare();
unsigned char status, data, basr, mr, icr, i;
-   NCR5380_setup(instance);
 
data = NCR5380_read(CURRENT_SCSI_DATA_REG);
status = NCR5380_read(STATUS_REG);
@@ -447,10 +437,8 @@ static void NCR5380_print(struct Scsi_Ho
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
 {
-   NCR5380_local_declare();
unsigned char status;
int i;
-   NCR5380_setup(instance);
 
status = NCR5380_read(STATUS_REG);
if (!(status & SR_REQ))
@@ -566,11 +554,9 @@ static irqreturn_t __init probe_intr(int
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
int possible)
 {
-   NCR5380_local_declare();
struct 

[PATCH v3 03/77] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros

2015-12-21 Thread Finn Thain
Replace {P,T,DTC}DEBUG_INIT with NDEBUG_INIT. Remove dead debugging
code, including code that's conditional upon *DEBUG_TRANSFER.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/dtc.c   |   18 ++
 drivers/scsi/dtc.h   |   27 ---
 drivers/scsi/pas16.c |   21 +++--
 drivers/scsi/pas16.h |   16 
 drivers/scsi/t128.c  |   18 ++
 drivers/scsi/t128.h  |   16 
 6 files changed, 19 insertions(+), 97 deletions(-)

Index: linux/drivers/scsi/dtc.c
===
--- linux.orig/drivers/scsi/dtc.c   2015-12-22 12:15:24.0 +1100
+++ linux/drivers/scsi/dtc.c2015-12-22 12:15:26.0 +1100
@@ -205,9 +205,8 @@ static int __init dtc_detect(struct scsi
addr = 0;
} else
for (; !addr && (current_base < NO_BASES); 
++current_base) {
-#if (DTCDEBUG & DTCDEBUG_INIT)
-   printk(KERN_DEBUG "scsi-dtc : probing address 
%08x\n", bases[current_base].address);
-#endif
+   dprintk(NDEBUG_INIT, "dtc: probing address 
0x%08x\n",
+   (unsigned 
int)bases[current_base].address);
if (bases[current_base].noauto)
continue;
base = ioremap(bases[current_base].address, 
0x2000);
@@ -216,18 +215,14 @@ static int __init dtc_detect(struct scsi
for (sig = 0; sig < NO_SIGNATURES; ++sig) {
if (check_signature(base + 
signatures[sig].offset, signatures[sig].string, 
strlen(signatures[sig].string))) {
addr = 
bases[current_base].address;
-#if (DTCDEBUG & DTCDEBUG_INIT)
-   printk(KERN_DEBUG "scsi-dtc : 
detected board.\n");
-#endif
+   dprintk(NDEBUG_INIT, "dtc: 
detected board\n");
goto found;
}
}
iounmap(base);
}
 
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-   printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
-#endif
+   dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr);
 
if (!addr)
break;
@@ -271,9 +266,8 @@ found:
printk(KERN_WARNING "scsi%d : interrupts not used. 
Might as well not jumper it.\n", instance->host_no);
instance->irq = NO_IRQ;
 #endif
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-   printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+   dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+   instance->host_no, instance->irq);
 
++current_override;
++count;
Index: linux/drivers/scsi/dtc.h
===
--- linux.orig/drivers/scsi/dtc.h   2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/dtc.h2015-12-22 12:15:26.0 +1100
@@ -10,10 +10,6 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#define DTCDEBUG 0
-#define DTCDEBUG_INIT  0x1
-#define DTCDEBUG_TRANSFER 0x2
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -33,31 +29,8 @@
 
 #define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
 
-#define dbNCR5380_read(reg)  \
-(rval=readb(DTC_address(reg)), \
- (((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\
-, (reg), DTC_address(reg), rval)), rval ) )
-
-#define dbNCR5380_write(reg, value) do {  \
-printk("DTC : write %02x to register %d at address %p\n", \
-(value), (reg), DTC_address(reg)); \
-writeb(value, DTC_address(reg));} while(0)
-
-
-#if !(DTCDEBUG & DTCDEBUG_TRANSFER) 
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
-#else
-#define NCR5380_read(reg) (readb(DTC_address(reg)))
-#define xNCR5380_read(reg) \
-(((unsigned char) printk("DTC : read register %d at address %p\n"\
-, (reg), DTC_address(reg))), readb(DTC_address(reg)))
-
-#define NCR5380_write(reg, value) do { \
-printk("DTC : write %02x to register %d at address %p\n",  \
-   (value), (reg), DTC_address(reg));  \
-writeb(value, DTC_address(reg));} while(0)
-#endif
 
 #define NCR5380_intr   dtc_intr
 #define NCR5380_queue_command  dtc_queue_command
Index: 

Re: [PATCH 00/17] lpfc: Update to revision 11.0.0.10

2015-12-21 Thread Martin K. Petersen
> "James" == James Smart  writes:

James> This patch set updates the lpfc driver to revision 11.0.0.10

James> The patches were cut against scsi-misc

Applied to 4.5/scsi-queue except for 3/17.

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: st driver doesn't seem to grok LTO partitioning

2015-12-21 Thread Seymour, Shane M
If you need help with anything please let me know I'd be more than happy to 
contribute (with testing and a review if you want). I have a system with an 
older LTO-3 tape drive that I can use any time (it doesn’t support partitioning 
so if nothing else I can make sure partitioning attempts fail gracefully). I 
may be able to beg, borrow, or steal access to an LTO 5 or 6 drive though to 
help out in testing.

Kai, for the source of the HPE EverStore software should be available here:

http://h20564.www2.hpe.com/hpsc/swd/public/readIndex?sp4ts.oid=5111617

Select something like RHEL7 server from the dropdown on the page that loads 
click on the + in front of "Software - Storage (4)". If you click on the first 
product listed then click on select (at the next screen you will unfortunately 
need to create a HP Passport account) and then you need to give a lot of 
personal information when you get the option to download the source make sure 
you change the pulldown above the download buttons to standard download. The 
version 3.0 source is about 1.2Mb in size (GPL version 2.1).

This seems to be the relevant code from the driver though (the same download 
has the ibm tape driver as well). You'll need to look at the following:

ltotape.c - ltotape_readposition to determine the current partition
ltotape.c - ltotape_locate - to move to a position on tape (includes setting 
the partition and has a special flag for changing partitions between the two it 
supports if required)
ltotape.c - ltotape_format - for creating and destroying partitions
ltotape.c - ltotape_remaining_capacity - will get you the remaining and maximum 
capacity for the partitions

When you look at those functions you'll see TC_FORMAT_TYPE referenced this is 
the enum referred it is in src/libltfs/tape_ops.h:

typedef enum {
TC_FORMAT_DEFAULT   = 0x00,   /* Make 1 partition medium */
TC_FORMAT_PARTITION = 0x01,   /* Make 2 partition medium */
TC_FORMAT_DEST_PART = 0x02,   /* Destroy all data and make 2 partition 
medium */
TC_FORMAT_MAX   = 0x03
} TC_FORMAT_TYPE;/* Space command operations */

The driver at that download looks like it only supports two partitions though 
and if you go looking around the code (grep for partition) some LTO drives 
(probably older ones) look like they may be partition aware but may not 
actually support partitions, see this comment:

ltotape_platform.c:  * For an LTO drive, need to determine whether it is 
partition-capable or only partition-aware:

So you may need to check for firmware that is partition aware but not partition 
capable.

The IBM LTO SCSI reference is nice and long and it looks like you can either 
make SET CAPACITY calls on the currently mounted medium to set the sizes and 
then format the medium it also refers to the medium partition mode page in 
terms of changing the partitioning of the tape.
N�r��yb�X��ǧv�^�)޺{.n�+{���"�{ay�ʇڙ�,j��f���h���z��w���
���j:+v���w�j�mzZ+�ݢj"��!�i

Re: [PATCH v3 17/77] ncr5380: Keep BSY asserted when entering SELECTION phase

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:17 AM, Finn Thain wrote:

NCR5380.c is not compliant with the SCSI-2 standard (at least, not with
the draft revision 10L that I have to refer to). The selection algorithm
in atari_NCR5380.c is correct, so use that.

Signed-off-by: Finn Thain 


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 25/77] ncr5380: Rework disconnect versus poll logic

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

The atari_NCR5380.c and NCR5380.c core drivers differ in their handling of
target disconnection. This is partly because atari_NCR5380.c had all of
the polling and sleeping removed to become entirely interrupt-driven, and
it is partly because of damage done to NCR5380.c after atari_NCR5380.c was
forked. See commit 37cd23b44929 ("Linux 2.1.105") in history/history.git.

The polling changes that were made in v2.1.105 are questionable at best:
if REQ is not already asserted when NCR5380_transfer_pio() is invoked, and
if the expected phase is DATA IN or DATA OUT, the function will schedule
main() to execute after USLEEP_SLEEP jiffies and then return. The problems
here are the expected REQ timing and the sleep interval*. Avoid this issue
by using NCR5380_poll_politely() instead of scheduling main().

The atari_NCR5380.c core driver requires the use of the chip interrupt and
always permits target disconnection. It sets the cmd->device->disconnect
flag when a device disconnects, but never tests this flag.

The NCR5380.c core driver permits disconnection only when
instance->irq != NO_IRQ. It sets the cmd->device->disconnect flag when
a device disconnects and it tests this flag in a couple of places:

1. During NCR5380_information_transfer(), following COMMAND OUT phase,
if !cmd->device->disconnect, the initiator will take a guess as to
whether or not the target will then choose to go to MESSAGE IN phase
and disconnect. If the driver guesses "yes", it will schedule main()
to execute after USLEEP_SLEEP jiffies and then return there.

Unfortunately the driver may guess "yes" even after it has denied
the target the disconnection privilege. When the target does not
disconnect, the sleep can be beneficial, assuming the sleep interval
is appropriate (mostly it is not*).

And even if the driver guesses "yes" correctly, and the target would
then disconnect, the driver still has to go through the MESSAGE IN
phase in order to get to BUS FREE phase. The main loop can do nothing
useful until BUS FREE, and sleeping just delays the phase transition.

2. If !cmd->device->disconnect and REQ is not already asserted when
NCR5380_information_transfer() is invoked, the function polls for REQ
for USLEEP_POLL jiffies. If REQ is not asserted, it then schedules
main() to execute after USLEEP_SLEEP jiffies and returns.

The idea is apparently to yeild the CPU while waiting for REQ.
This is conditional upon !cmd->device->disconnect, but there seems
to be no rhyme or reason for that. For example, the flag may be
unset because disconnection privilege was denied because the driver
has no IRQ. Or the flag may be unset because the device has never
needed to disconnect before. Or if the flag is set, disconnection
may have no relevance to the present bus phase.

Another deficiency of the existing algorithm is as follows. When the
driver has no IRQ, it prevents disconnection, and generally polls and
sleeps more than it would normally. Now, if the driver is going to poll
anyway, why not allow the target to disconnect? That way the driver can do
something useful with the bus instead of polling unproductively!

Avoid this pointless latency, complexity and guesswork by using
NCR5380_poll_politely() instead of scheduling main().

* For g_NCR5380, the time intervals for USLEEP_SLEEP and USLEEP_POLL are
   200 ms and 10 ms, respectively. They are 20 ms and 200 ms respectively
   for the other NCR5380 drivers. There doesn't seem to be any reason for
   this discrepancy. The timing seems to have no relation to the type of
   adapter. Bizarrely, the timing in g_NCR5380 seems to relate only to one
   particular type of target device. This patch attempts to solve the
   problem for all NCR5380 drivers and all target devices.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |  137 
++-
  drivers/scsi/NCR5380.h   |   11 ---
  drivers/scsi/atari_NCR5380.c |   24 ++-
  drivers/scsi/g_NCR5380.c |4 -
  4 files changed, 15 insertions(+), 161 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 60/77] ncr5380: Implement new eh_abort_handler

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Introduce a new eh_abort_handler implementation. This one attempts to
follow all of the rules relating to EH handlers. There is still a known
bug: during selection, a command becomes invisible to the EH handlers
because it only appears in a pointer on the stack of a different thread.
This bug is addressed in a subsequent patch.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |  155 ++
  drivers/scsi/atari_NCR5380.c |  157 
++-
  2 files changed, 282 insertions(+), 30 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 59/77] ncr5380: Fix autosense bugs

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

NCR5380_information_transfer() may re-queue a command for autosense,
after calling scsi_eh_prep_cmnd(). This creates several possibilities:

1. Reselection may intervene before the re-queued command gets processed.
If the reconnected command then undergoes autosense, this causes the
scsi_eh_save data from the previous command to be overwritten.

2. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
a new REQUEST SENSE command may arrive. This would be queued ahead
of any command already undergoing autosense, which means the
scsi_eh_save data might be restored to the wrong command.

3. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
eh_abort_handler() may abort the command. But the scsi_eh_save data is
not discarded, which means the scsi_eh_save data might be incorrectly
restored to the next REQUEST SENSE command issued.

This patch adds a new autosense list so that commands that are re-queued
because of a CHECK CONDITION result can be kept apart from the REQUEST
SENSE commands that arrive via queuecommand.

This patch also adds a function dedicated to dequeueing and preparing the
next command for processing. By refactoring the main loop in this way,
scsi_eh_save takes place when an autosense command is dequeued rather
than when re-queued.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |  194 +++---
  drivers/scsi/NCR5380.h   |2
  drivers/scsi/atari_NCR5380.c |  239 
---
  3 files changed, 249 insertions(+), 186 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] hisi_sas v1 hw itct fixes

2015-12-21 Thread John Garry
This patchset introduces some minor fixes for v1 hw
itct configuration.

John Garry (3):
  hisi_sas: fix v1 itct masks
  hisi_sas: fix typo in setup_itct_v1_hw()
  hisi_sas: use u64 for qw0 in free_device_v1_hw()

 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 40 +++---
 1 file changed, 18 insertions(+), 22 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] hisi_sas: fix typo in setup_itct_v1_hw()

2015-12-21 Thread John Garry
We were doing a arithmetic comparison instead
of logical shift by accident.
Mis-programming the itct did not seem to make
a difference to operation.

Fixes: abda97c2fe874 ("hisi_sas: Add dev_found")

Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 0af682c..38ff575 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -528,10 +528,10 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba,
itct->sas_addr = __swab64(itct->sas_addr);
 
/* qw2 */
-   itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
-   (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) |
-   (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) |
-   (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF));
+   itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
+   (0xff00ULL << ITCT_HDR_BUS_INACTIVE_TL_OFF) |
+   (0xff00ULL << ITCT_HDR_MAX_CONN_TL_OFF) |
+   (0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF));
 }
 
 static void free_device_v1_hw(struct hisi_hba *hisi_hba,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] hisi_sas: use u64 for qw0 in free_device_v1_hw()

2015-12-21 Thread John Garry
By reading in itct.qw0 into a 32b variable the top
32 bits were being lost.
In practice this was OK as they were zeroes.

Fixes: 27a3f229 ("hisi_sas: Add cq interrupt")

Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 38ff575..057fdeb 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -539,7 +539,8 @@ static void free_device_v1_hw(struct hisi_hba *hisi_hba,
 {
u64 dev_id = sas_dev->device_id;
struct hisi_sas_itct *itct = _hba->itct[dev_id];
-   u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
+   u64 qw0;
+   u32 reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
 
reg_val |= CFG_AGING_TIME_ITCT_REL_MSK;
hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 23/77] ncr5380: Always retry arbitration and selection

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

If NCR5380_select() returns -1, it means arbitration was lost or selection
failed and should be retried. If the main loop simply terminates when there
are still commands on the issue queue, they will remain queued until they
expire.

Fix this by clearing the 'done' flag after selection failure or lost
arbitration.

The "else break" clause in NCR5380_main() that gets removed here appears
to be a vestige of a long-gone loop that iterated over host instances.
See commit 491447e1fcff ("[PATCH] next NCR5380 updates") in
history/history.git.

Signed-off-by: Finn Thain 


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 22/77] ncr5380: Eliminate selecting state

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Linux v2.1.105 changed the algorithm for polling for the BSY signal
in NCR5380_select() and NCR5380_main().

Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
provided the recommended 250 ms selection time-out delay. This got broken
when HZ became configurable.

We could fix this but there's no need to reschedule the main loop. This
BSY polling presently happens when the NCR5380_main() work queue item
calls NCR5380_select(), which in turn schedules NCR5380_main(), which
calls NCR5380_select() again, and so on.

This algorithm is a deviation from the simpler one in atari_NCR5380.c.
The extra complexity and state is pointless. There's no reason to
stop selection half-way and return to to the main loop when the main
loop can do nothing useful until selection completes.

So just poll for BSY. We can sleep while polling now that we have a
suitable workqueue.

Signed-off-by: Finn Thain 


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 29/77] ncr5380: Remove references to linked commands

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

From: Hannes Reinecke 

Some old drivers partially implemented support for linked commands using
a "proposed" next_link pointer in struct scsi_cmnd that never actually
existed. Remove this code.

Signed-off-by: Finn Thain 

---

This is a modified version of Hannes' patch so I have dropped his
signed-off-by tag. This version has a rewritten commit log and also
removes additional references to linked commands from comments. This
version also omits the sun3_NCR5380.c changes since that file no
longer exists.

---
  drivers/scsi/NCR5380.c   |   42 --
  drivers/scsi/atari_NCR5380.c |   60 
---
  2 files changed, 102 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 28/77] ncr5380: Drop DEF_SCSI_QCMD macro

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Remove the DEF_SCSI_QCMD macro (already removed from atari_NCR5380.c). The
lock provided by DEF_SCSI_QCMD is only needed for queue data structures.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |   30 +++---
  drivers/scsi/atari_NCR5380.c |2 +-
  2 files changed, 16 insertions(+), 16 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 36/77] ncr5380: Use work_struct instead of delayed_work

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Each host instance now has it's own work queue so the main() work item can
sleep when necessary. That means we can use a simple work item rather than
a delayed work item. This brings NCR5380.c closer to atari_NCR5380.c.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c |   12 +---
  drivers/scsi/NCR5380.h |1 -
  2 files changed, 5 insertions(+), 8 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 37/77] ncr5380: Standardize work queueing algorithm

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

The complex main_running/queue_main mechanism is peculiar to
atari_NCR5380.c. It isn't SMP safe and offers little value given that
the work queue already offers concurrency management. Remove this
complexity to bring atari_NCR5380.c closer to NCR5380.c.

It is not a good idea to call the information transfer state machine from
queuecommand because, according to Documentation/scsi/scsi_mid_low_api.txt
that could happen in soft irq context. Fix this.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.h   |1
  drivers/scsi/atari_NCR5380.c |   80 
+++
  2 files changed, 6 insertions(+), 75 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 35/77] ncr5380: Dont wait for BUS FREE after disconnect

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

When there is a queued command and no connected command, NCR5380_select()
is called and arbitration begins. The chip waits for BUS FREE once the
MR_ARBITRATE bit in the mode register is enabled. That means there is
no need to wait for BUS FREE after disconnecting.

There is presently no polling for BUS FREE after sending an ABORT or
other message that might lead to disconnection. It only happens after
COMMAND COMPLETE or DISCONNECT messages, which seems inconsistent.
Remove the polling for !BSY in the COMMAND COMPLETE and DISCONNECT
cases.

BTW, the comments say "avoid nasty timeouts" and perhaps BUS FREE polling
was somehow helpful back in Linux v0.99.14u, when it was introduced.
The relevant timeout is presently 1 second (for bus arbitration).

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |7 ---
  drivers/scsi/atari_NCR5380.c |   11 ---
  2 files changed, 18 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 42/77] ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

The workarounds for chip errata appear twice, in slightly different
forms. One is used when defined(REAL_DMA) || defined(REAL_DMA_POLL), the
other when defined(PSEUDO_DMA). In the PDMA case, the workarounds have
been made conditional on FLAG_NO_DMA_FIXUPS. Do the same for the DMA case,
to eliminate the READ_OVERRUNS macro.

Signed-off-by: Finn Thain 


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 43/77] ncr5380: Standardize reselection handling

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Bring the two NCR5380_reselect() implementations into agreement.

Replace infinite loops in atari_NCR5380.c with timeouts, as per NCR5380.c.

Remove 'abort' flag in NCR5380.c as per atari_NCR5380.c -- if reselection
fails, there may be no MESSAGE IN phase so don't attempt data transfer.

During selection, don't interfere with the chip registers after a
reselection interrupt intervenes.

Clean up some trivial issues with code style, comments and printk.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |  115 
+++
  drivers/scsi/atari_NCR5380.c |   50 ++
  2 files changed, 93 insertions(+), 72 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 50/77] ncr5380: Change instance->host_lock to hostdata->lock

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

NCR5380.c presently uses the instance->host_lock spin lock. Convert this
to a new spin lock that protects the NCR5380_hostdata struct.

atari_NCR5380.c previously used local_irq_save/restore() rather than a
spin lock. Convert this to hostdata->lock in irq mode. For SMP platforms,
the interrupt handler now also acquires the spin lock.

This brings all locking in the two core drivers into agreement.

Adding this locking also means that a bunch of volatile qualifiers can be
removed from the members of the NCR5380_hostdata struct. This is done in
a subsequent patch.

Proper locking will allow the abort handler to locate a command being
aborted. This is presently impossible if the abort handler is invoked when
the command has been moved from a queue to a pointer on the stack. (If
eh_abort_handler can't determine whether a command has been completed
or is still being processed then it can't decide whether to return
success or failure.)

The hostdata spin lock is now held when calling NCR5380_select() and
NCR5380_information_transfer(). Where possible, the lock is dropped for
polling and PIO transfers.

Clean up the now-redundant SELECT_ENABLE_REG writes, that used to provide
limited mutual exclusion between information_transfer() and reselect().

Accessing hostdata->connected without data races means taking the lock;
cleanup these accesses.

The new spin lock falls away for m68k and other UP builds, so this should
have little impact there. In the SMP case the new lock should be
uncontested even when the SCSI bus is contested.

Signed-off-by: Finn Thain 


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 51/77] ncr5380: Remove command list debug code

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Some NCR5380 hosts offer a .show_info method to access the contents of
the various command list data structures from a procfs file. When NDEBUG
is set, the same information is sent to the console during EH.

The two core drivers, atari_NCR5380.c and NCR5380.c differ here. Because
it is just for debugging, the easiest way to fix the discrepancy is
simply remove this code.

The only remaining users of NCR5380_show_info() and NCR5380_write_info()
are drivers that define PSEUDO_DMA. The others have no use for the
.show_info method, so don't initialize it.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |   70 ++--
  drivers/scsi/arm/oak.c   |2
  drivers/scsi/atari_NCR5380.c |   94 
+--
  drivers/scsi/atari_scsi.c|2
  drivers/scsi/g_NCR5380.c |1
  drivers/scsi/sun3_scsi.c |2
  6 files changed, 9 insertions(+), 162 deletions(-)


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 58/77] ncr5380: Refactor command completion

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

Implement a 'complete_cmd' function to complete commands. This is needed
by the following patch; the new function provides a site for the logic
needed to correctly handle REQUEST SENSE commands.

Signed-off-by: Finn Thain 

---
  drivers/scsi/NCR5380.c   |   31 ++--
  drivers/scsi/atari_NCR5380.c |   46 
---
  2 files changed, 55 insertions(+), 22 deletions(-)

Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 57/77] ncr5380: Use standard list data structure

2015-12-21 Thread Hannes Reinecke

On 12/22/2015 02:18 AM, Finn Thain wrote:

The NCR5380 drivers have a home-spun linked list implementation for
scsi_cmnd structs that uses cmd->host_scribble as a 'next' pointer. Adopt
the standard list_head data structure and list operations instead. Remove
the eh_abort_handler rather than convert it. Doing the conversion would
only be churn because the existing EH handlers don't work and get replaced
in a subsequent patch.

Signed-off-by: Finn Thain 

---

Changed since v2:
- Fix NULL pointer dereference in NCR5380_reselect() when SUPPORT_TAGS is
   enabled in the atari_NCR5380.c core driver.

Well, using ->host_scribble allows for an easy check on the midlayer if 
a command has been properly released by the LLDD. But that's just a 
side-note.


Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 01/77] atari_scsi: Fix SCSI host ID setting

2015-12-21 Thread Finn Thain
The NVRAM location of this byte is 16, as documented in
http://toshyp.atari.org/en/004009.html

This was confirmed by Michael Schmitz, by setting the SCSI host ID
under EmuTOS and then checking the value in /proc/driver/nvram and
/dev/nvram under Linux.

Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

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

Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-12-22 12:14:49.0 
+1100
+++ linux/drivers/scsi/atari_scsi.c 2015-12-22 12:15:21.0 +1100
@@ -880,7 +880,7 @@ static int __init atari_scsi_probe(struc
} else {
/* Test if a host id is set in the NVRam */
if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-   unsigned char b = nvram_read_byte(14);
+   unsigned char b = nvram_read_byte(16);
 
/* Arbitration enabled? (for TOS)
 * If yes, use configured host ID


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 30/77] ncr5380: Add missing break after case MESSAGE_REJECT

2015-12-21 Thread Finn Thain
MESSAGE REJECT does not imply DISCONNECT: the target is about to enter
MESSAGE IN or MESSAGE OUT phase.

This bug fix comes from atari_NCR5380.c. Unfortunately it never made it
into the original NCR5380.c core driver.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |1 +
 1 file changed, 1 insertion(+)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:16.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:17.0 +1100
@@ -1990,6 +1990,7 @@ static void NCR5380_information_transfer
default:
break;
}
+   break;
case DISCONNECT:{
/* Accept message by clearing 
ACK */

NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 02/77] ncr5380: Remove redundant static variable initializers

2015-12-21 Thread Finn Thain
Signed-off-by: Finn Thain 
Reviewed-by: Hannes Reinecke 

---
 drivers/scsi/NCR5380.c   |2 +-
 drivers/scsi/dtc.c   |4 ++--
 drivers/scsi/g_NCR5380.c |4 ++--
 drivers/scsi/pas16.c |   10 +-
 drivers/scsi/sun3_scsi.c |8 
 drivers/scsi/t128.c  |4 ++--
 6 files changed, 16 insertions(+), 16 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:24.0 +1100
@@ -534,7 +534,7 @@ static void NCR5380_set_timer(struct NCR
 }
 
 
-static int probe_irq __initdata = 0;
+static int probe_irq __initdata;
 
 /**
  * probe_intr  -   helper for IRQ autoprobe
Index: linux/drivers/scsi/dtc.c
===
--- linux.orig/drivers/scsi/dtc.c   2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/dtc.c2015-12-22 12:15:24.0 +1100
@@ -150,7 +150,7 @@ static const struct signature {
 
 static int __init dtc_setup(char *str)
 {
-   static int commandline_current = 0;
+   static int commandline_current;
int i;
int ints[10];
 
@@ -188,7 +188,7 @@ __setup("dtc=", dtc_setup);
 
 static int __init dtc_detect(struct scsi_host_template * tpnt)
 {
-   static int current_override = 0, current_base = 0;
+   static int current_override, current_base;
struct Scsi_Host *instance;
unsigned int addr;
void __iomem *base;
Index: linux/drivers/scsi/g_NCR5380.c
===
--- linux.orig/drivers/scsi/g_NCR5380.c 2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/g_NCR5380.c  2015-12-22 12:15:24.0 +1100
@@ -121,7 +121,7 @@ static struct override {
 
 static void __init internal_setup(int board, char *str, int *ints)
 {
-   static int commandline_current = 0;
+   static int commandline_current;
switch (board) {
case BOARD_NCR5380:
if (ints[0] != 2 && ints[0] != 3) {
@@ -251,7 +251,7 @@ static int __init do_DTC3181E_setup(char
 
 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 {
-   static int current_override = 0;
+   static int current_override;
int count;
unsigned int *ports;
 #ifndef SCSI_G_NCR5380_MEM
Index: linux/drivers/scsi/pas16.c
===
--- linux.orig/drivers/scsi/pas16.c 2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/pas16.c  2015-12-22 12:15:24.0 +1100
@@ -87,8 +87,8 @@
 #include "NCR5380.h"
 
 
-static unsigned short pas16_addr = 0;
-static int pas16_irq = 0;
+static unsigned short pas16_addr;
+static int pas16_irq;
  
 
 static const int scsi_irq_translate[] =
@@ -305,7 +305,7 @@ static int __init
 
 static int __init pas16_setup(char *str)
 {
-static int commandline_current = 0;
+   static int commandline_current;
 int i;
 int ints[10];
 
@@ -344,8 +344,8 @@ __setup("pas16=", pas16_setup);
 
 static int __init pas16_detect(struct scsi_host_template *tpnt)
 {
-static int current_override = 0;
-static unsigned short current_base = 0;
+   static int current_override;
+   static unsigned short current_base;
 struct Scsi_Host *instance;
 unsigned short io_port;
 int  count;
Index: linux/drivers/scsi/sun3_scsi.c
===
--- linux.orig/drivers/scsi/sun3_scsi.c 2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/sun3_scsi.c  2015-12-22 12:15:24.0 +1100
@@ -100,10 +100,10 @@ static struct scsi_cmnd *sun3_dma_setup_
 static unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
 static struct sun3_udc_regs *udc_regs;
-static unsigned char *sun3_dma_orig_addr = NULL;
-static unsigned long sun3_dma_orig_count = 0;
-static int sun3_dma_active = 0;
-static unsigned long last_residual = 0;
+static unsigned char *sun3_dma_orig_addr;
+static unsigned long sun3_dma_orig_count;
+static int sun3_dma_active;
+static unsigned long last_residual;
 static struct Scsi_Host *default_instance;
 
 /*
Index: linux/drivers/scsi/t128.c
===
--- linux.orig/drivers/scsi/t128.c  2015-12-22 12:14:49.0 +1100
+++ linux/drivers/scsi/t128.c   2015-12-22 12:15:24.0 +1100
@@ -126,7 +126,7 @@ static struct signature {
 
 static int __init t128_setup(char *str)
 {
-static int commandline_current = 0;
+   static int commandline_current;
 int i;
 int ints[10];
 
@@ -165,7 +165,7 @@ __setup("t128=", t128_setup);
 
 static int __init t128_detect(struct scsi_host_template *tpnt)
 {
-static int current_override = 0, current_base = 0;
+   static int 

[PATCH v3 25/77] ncr5380: Rework disconnect versus poll logic

2015-12-21 Thread Finn Thain
The atari_NCR5380.c and NCR5380.c core drivers differ in their handling of
target disconnection. This is partly because atari_NCR5380.c had all of
the polling and sleeping removed to become entirely interrupt-driven, and
it is partly because of damage done to NCR5380.c after atari_NCR5380.c was
forked. See commit 37cd23b44929 ("Linux 2.1.105") in history/history.git.

The polling changes that were made in v2.1.105 are questionable at best:
if REQ is not already asserted when NCR5380_transfer_pio() is invoked, and
if the expected phase is DATA IN or DATA OUT, the function will schedule
main() to execute after USLEEP_SLEEP jiffies and then return. The problems
here are the expected REQ timing and the sleep interval*. Avoid this issue
by using NCR5380_poll_politely() instead of scheduling main().

The atari_NCR5380.c core driver requires the use of the chip interrupt and
always permits target disconnection. It sets the cmd->device->disconnect
flag when a device disconnects, but never tests this flag.

The NCR5380.c core driver permits disconnection only when
instance->irq != NO_IRQ. It sets the cmd->device->disconnect flag when
a device disconnects and it tests this flag in a couple of places:

1. During NCR5380_information_transfer(), following COMMAND OUT phase,
   if !cmd->device->disconnect, the initiator will take a guess as to
   whether or not the target will then choose to go to MESSAGE IN phase
   and disconnect. If the driver guesses "yes", it will schedule main()
   to execute after USLEEP_SLEEP jiffies and then return there.

   Unfortunately the driver may guess "yes" even after it has denied
   the target the disconnection privilege. When the target does not
   disconnect, the sleep can be beneficial, assuming the sleep interval
   is appropriate (mostly it is not*).

   And even if the driver guesses "yes" correctly, and the target would
   then disconnect, the driver still has to go through the MESSAGE IN
   phase in order to get to BUS FREE phase. The main loop can do nothing
   useful until BUS FREE, and sleeping just delays the phase transition.

2. If !cmd->device->disconnect and REQ is not already asserted when
   NCR5380_information_transfer() is invoked, the function polls for REQ
   for USLEEP_POLL jiffies. If REQ is not asserted, it then schedules
   main() to execute after USLEEP_SLEEP jiffies and returns.

   The idea is apparently to yeild the CPU while waiting for REQ.
   This is conditional upon !cmd->device->disconnect, but there seems
   to be no rhyme or reason for that. For example, the flag may be
   unset because disconnection privilege was denied because the driver
   has no IRQ. Or the flag may be unset because the device has never
   needed to disconnect before. Or if the flag is set, disconnection
   may have no relevance to the present bus phase.

Another deficiency of the existing algorithm is as follows. When the
driver has no IRQ, it prevents disconnection, and generally polls and
sleeps more than it would normally. Now, if the driver is going to poll
anyway, why not allow the target to disconnect? That way the driver can do
something useful with the bus instead of polling unproductively!

Avoid this pointless latency, complexity and guesswork by using
NCR5380_poll_politely() instead of scheduling main().

* For g_NCR5380, the time intervals for USLEEP_SLEEP and USLEEP_POLL are
  200 ms and 10 ms, respectively. They are 20 ms and 200 ms respectively
  for the other NCR5380 drivers. There doesn't seem to be any reason for
  this discrepancy. The timing seems to have no relation to the type of
  adapter. Bizarrely, the timing in g_NCR5380 seems to relate only to one
  particular type of target device. This patch attempts to solve the
  problem for all NCR5380 drivers and all target devices.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  137 ++-
 drivers/scsi/NCR5380.h   |   11 ---
 drivers/scsi/atari_NCR5380.c |   24 ++-
 drivers/scsi/g_NCR5380.c |4 -
 4 files changed, 15 insertions(+), 161 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:07.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:10.0 +1100
@@ -139,17 +139,7 @@
  * piece of hardware that requires you to sit in a loop polling for 
  * the REQ signal as long as you are connected.  Some devices are 
  * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect 
- * while doing long seek operations.
- * 
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like 
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- * 
- * Some tweaking of N and M needs to be done.  An algorithm based 
- * on "time to data" 

[PATCH v3 20/77] ncr5380: Introduce unbound workqueue

2015-12-21 Thread Finn Thain
Allocate a work queue that will permit busy waiting and sleeping. This
means NCR5380_init() can potentially fail, so add this error path.

Signed-off-by: Finn Thain 

---

In subsequent patches, the work function adopts this work queue so it
can sleep while polling, which allows the removal of some flawed and
complicated code in NCR5380_select() in NCR5380.c.

Changed since v1:
- Dropped WQ_CPU_INTENSIVE flag because Documentation/workqueue.txt says it
  "is meaningless for unbound wq".

---
 drivers/scsi/NCR5380.c   |   15 +++
 drivers/scsi/NCR5380.h   |1 +
 drivers/scsi/arm/cumana_1.c  |8 ++--
 drivers/scsi/arm/oak.c   |8 ++--
 drivers/scsi/atari_NCR5380.c |8 +++-
 drivers/scsi/atari_scsi.c|5 -
 drivers/scsi/dmx3191d.c  |   17 +++--
 drivers/scsi/dtc.c   |   11 +--
 drivers/scsi/g_NCR5380.c |   31 +++
 drivers/scsi/mac_scsi.c  |5 -
 drivers/scsi/pas16.c |   10 --
 drivers/scsi/sun3_scsi.c |5 -
 drivers/scsi/t128.c  |   13 ++---
 13 files changed, 96 insertions(+), 41 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:15:52.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:15:56.0 +1100
@@ -514,7 +514,7 @@ static int should_disconnect(unsigned ch
 static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long 
timeout)
 {
hostdata->time_expires = jiffies + timeout;
-   schedule_delayed_work(>coroutine, timeout);
+   queue_delayed_work(hostdata->work_q, >coroutine, timeout);
 }
 
 
@@ -791,7 +791,12 @@ static int NCR5380_init(struct Scsi_Host
hostdata->disconnected_queue = NULL;

INIT_DELAYED_WORK(>coroutine, NCR5380_main);
-   
+   hostdata->work_q = alloc_workqueue("ncr5380_%d",
+   WQ_UNBOUND | WQ_MEM_RECLAIM,
+   1, instance->host_no);
+   if (!hostdata->work_q)
+   return -ENOMEM;
+
/* The CHECK code seems to break the 53C400. Will check it later maybe 
*/
if (flags & FLAG_NCR53C400)
hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
@@ -872,6 +877,7 @@ static void NCR5380_exit(struct Scsi_Hos
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
 
cancel_delayed_work_sync(>coroutine);
+   destroy_workqueue(hostdata->work_q);
 }
 
 /**
@@ -932,7 +938,7 @@ static int NCR5380_queue_command_lck(str
 
/* Run the coroutine if it isn't already running. */
/* Kick off command processing */
-   schedule_delayed_work(>coroutine, 0);
+   queue_delayed_work(hostdata->work_q, >coroutine, 0);
return 0;
 }
 
@@ -1128,7 +1134,8 @@ static irqreturn_t NCR5380_intr(int dumm
}   /* if BASR_IRQ */
spin_unlock_irqrestore(instance->host_lock, flags);
if(!done)
-   schedule_delayed_work(>coroutine, 0);
+   queue_delayed_work(hostdata->work_q,
+  >coroutine, 0);
} while (!done);
return IRQ_HANDLED;
 }
Index: linux/drivers/scsi/NCR5380.h
===
--- linux.orig/drivers/scsi/NCR5380.h   2015-12-22 12:15:48.0 +1100
+++ linux/drivers/scsi/NCR5380.h2015-12-22 12:15:56.0 +1100
@@ -284,6 +284,7 @@ struct NCR5380_hostdata {
unsigned spin_max_r;
unsigned spin_max_w;
 #endif
+   struct workqueue_struct *work_q;
 };
 
 #ifdef __KERNEL__
Index: linux/drivers/scsi/arm/cumana_1.c
===
--- linux.orig/drivers/scsi/arm/cumana_1.c  2015-12-22 12:15:54.0 
+1100
+++ linux/drivers/scsi/arm/cumana_1.c   2015-12-22 12:15:56.0 +1100
@@ -238,7 +238,9 @@ static int cumanascsi1_probe(struct expa
 
host->irq = ec->irq;
 
-   NCR5380_init(host, 0);
+   ret = NCR5380_init(host, 0);
+   if (ret)
+   goto out_unmap;
 
NCR5380_maybe_reset_bus(host);
 
@@ -250,7 +252,7 @@ static int cumanascsi1_probe(struct expa
if (ret) {
printk("scsi%d: IRQ%d not free: %d\n",
host->host_no, host->irq, ret);
-   goto out_unmap;
+   goto out_exit;
}
 
ret = scsi_add_host(host, >dev);
@@ -262,6 +264,8 @@ static int cumanascsi1_probe(struct expa
 
  out_free_irq:
free_irq(host->irq, host);
+ out_exit:
+   NCR5380_exit(host);
  out_unmap:
iounmap(priv(host)->base);
iounmap(priv(host)->dma);
Index: linux/drivers/scsi/arm/oak.c
===
--- 

[PATCH v3 26/77] ncr5380: Fix NCR5380_transfer_pio() result

2015-12-21 Thread Finn Thain
According to the SCSI-2 draft revision 10L, atari_NCR5380.c is correct
when it says that the phase lines are valid up until ACK is negated
following the transmission of the last byte in MESSAGE IN phase. This is
true for all information transfer phases, from target to initiator.

Sample the phase bits in STATUS_REG so that NCR5380_transfer_pio() can
return the correct result. The return value is presently unused (perhaps
because of bugs like this) but this change at least fixes the caller's
phase variable, which is passed by reference.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   12 +---
 drivers/scsi/atari_NCR5380.c |   11 ++-
 2 files changed, 15 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:10.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:12.0 +1100
@@ -1393,8 +1393,10 @@ static int NCR5380_transfer_pio(struct S
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_ACK);
}
 
-   /* FIXME - if this fails bus reset ?? */
-   NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
+   if (NCR5380_poll_politely(instance,
+ STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+   break;
+
dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake 
complete\n", instance->host_no);
 
 /*
@@ -1421,7 +1423,11 @@ static int NCR5380_transfer_pio(struct S
*count = c;
*data = d;
tmp = NCR5380_read(STATUS_REG);
-   if (tmp & SR_REQ)
+   /* The phase read from the bus is valid if either REQ is (already)
+* asserted or if ACK hasn't been released yet. The latter applies if
+* we're in MSG IN, DATA IN or STATUS and all bytes have been received.
+*/
+   if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
*phase = tmp & PHASE_MASK;
else
*phase = PHASE_UNKNOWN;
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:10.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:12.0 +1100
@@ -1776,8 +1776,9 @@ static int NCR5380_transfer_pio(struct S
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
ICR_ASSERT_ACK);
}
 
-   while (NCR5380_read(STATUS_REG) & SR_REQ)
-   ;
+   if (NCR5380_poll_politely(instance,
+ STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+   break;
 
dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake 
complete\n", HOSTNO);
 
@@ -1806,10 +1807,10 @@ static int NCR5380_transfer_pio(struct S
*data = d;
tmp = NCR5380_read(STATUS_REG);
/* The phase read from the bus is valid if either REQ is (already)
-* asserted or if ACK hasn't been released yet. The latter is the case 
if
-* we're in MSGIN and all wanted bytes have been received.
+* asserted or if ACK hasn't been released yet. The latter applies if
+* we're in MSG IN, DATA IN or STATUS and all bytes have been received.
 */
-   if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0))
+   if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
*phase = tmp & PHASE_MASK;
else
*phase = PHASE_UNKNOWN;


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 69/77] ncr5380: Merge changes from atari_NCR5380.c

2015-12-21 Thread Finn Thain
In the past, NCR5380.c was overlooked by those working on atari_NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from atari_NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c |  155 +++--
 1 file changed, 87 insertions(+), 68 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:19.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:23.0 +1100
@@ -174,7 +174,7 @@ static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
 /**
- * initialize_SCp  -   init the scsi pointer field
+ * initialize_SCp - init the scsi pointer field
  * @cmd: command block to set up
  *
  * Set up the internal fields in the SCSI command.
@@ -264,19 +264,6 @@ static inline int NCR5380_poll_politely(
reg, bit, val, wait);
 }
 
-static struct {
-   unsigned char value;
-   const char *name;
-} phases[] __maybe_unused = {
-   {PHASE_DATAOUT, "DATAOUT"},
-   {PHASE_DATAIN, "DATAIN"},
-   {PHASE_CMDOUT, "CMDOUT"},
-   {PHASE_STATIN, "STATIN"},
-   {PHASE_MSGOUT, "MSGOUT"},
-   {PHASE_MSGIN, "MSGIN"},
-   {PHASE_UNKNOWN, "UNKNOWN"}
-};
-
 #if NDEBUG
 static struct {
unsigned char mask;
@@ -311,6 +298,7 @@ mrs[] = {
{MR_TARGET, "MODE TARGET"},
{MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
{MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
+   {MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
{MR_MONITOR_BSY, "MODE MONITOR BSY"},
{MR_DMA_MODE, "MODE DMA"},
{MR_ARBITRATE, "MODE ARBITRATION"},
@@ -318,8 +306,8 @@ mrs[] = {
 };
 
 /**
- * NCR5380_print   -   print scsi bus signals
- * @instance:  adapter state to dump
+ * NCR5380_print - print scsi bus signals
+ * @instance: adapter state to dump
  *
  * Print the SCSI bus signals for debugging purposes
  */
@@ -353,9 +341,21 @@ static void NCR5380_print(struct Scsi_Ho
printk("\n");
 }
 
+static struct {
+   unsigned char value;
+   const char *name;
+} phases[] = {
+   {PHASE_DATAOUT, "DATAOUT"},
+   {PHASE_DATAIN, "DATAIN"},
+   {PHASE_CMDOUT, "CMDOUT"},
+   {PHASE_STATIN, "STATIN"},
+   {PHASE_MSGOUT, "MSGOUT"},
+   {PHASE_MSGIN, "MSGIN"},
+   {PHASE_UNKNOWN, "UNKNOWN"}
+};
 
 /**
- * NCR5380_print_phase -   show SCSI phase
+ * NCR5380_print_phase - show SCSI phase
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
@@ -370,7 +370,9 @@ static void NCR5380_print_phase(struct S
if (!(status & SR_REQ))
shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase 
unknown.\n");
else {
-   for (i = 0; (phases[i].value != PHASE_UNKNOWN) && 
(phases[i].value != (status & PHASE_MASK)); ++i);
+   for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
+(phases[i].value != (status & PHASE_MASK)); ++i)
+   ;
shost_printk(KERN_DEBUG, instance, "phase %s\n", 
phases[i].name);
}
 }
@@ -511,7 +513,7 @@ static int __maybe_unused NCR5380_write_
 }
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-   struct Scsi_Host *instance)
+struct Scsi_Host *instance)
 {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
@@ -522,7 +524,7 @@ static int __maybe_unused NCR5380_show_i
 #endif
 
 /**
- * NCR5380_init-   initialise an NCR5380
+ * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
  * @flags: control flags
  *
@@ -530,7 +532,7 @@ static int __maybe_unused NCR5380_show_i
  * with flags OR'd into the initial flags value.
  *
  * Notes : I assume that the host, hostno, and id bits have been
- * set correctly.  I don't care about the irq and other fields.
+ * set correctly. I don't care about the irq and other fields.
  *
  * Returns 0 for success
  */
@@ -541,10 +543,9 @@ static int NCR5380_init(struct Scsi_Host
int i;
unsigned long deadline;
 
-   if(in_interrupt())
-   printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-
+   hostdata->host = instance;
hostdata->id_mask = 1 << instance->this_id;
+   hostdata->id_higher_mask = 0;
for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
if (i > hostdata->id_mask)
hostdata->id_higher_mask |= i;
@@ -569,8 +570,6 @@ static int NCR5380_init(struct Scsi_Host
if (!hostdata->work_q)
return -ENOMEM;
 
-   hostdata->host = 

[PATCH v3 70/77] atari_NCR5380: Merge changes from NCR5380.c

2015-12-21 Thread Finn Thain
In the past, atari_NCR5380.c was overlooked by those working on NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain 

---
 drivers/scsi/atari_NCR5380.c |  108 +--
 1 file changed, 64 insertions(+), 44 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:17:19.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:17:24.0 +1100
@@ -443,22 +443,39 @@ static struct {
unsigned char mask;
const char *name;
 } signals[] = {
-   { SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" },
-   { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD,  "CD" }, { SR_IO, "IO" },
-   { SR_SEL, "SEL" }, {0, NULL}
-}, basrs[] = {
-   {BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL}
-}, icrs[] = {
-   {ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"},
-   {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"},
-   {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"},
+   {SR_DBP, "PARITY"},
+   {SR_RST, "RST"},
+   {SR_BSY, "BSY"},
+   {SR_REQ, "REQ"},
+   {SR_MSG, "MSG"},
+   {SR_CD, "CD"},
+   {SR_IO, "IO"},
+   {SR_SEL, "SEL"},
{0, NULL}
-}, mrs[] = {
-   {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"},
-   {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR,
-   "MODE PARITY INTR"}, {MR_ENABLE_EOP_INTR,"MODE EOP INTR"},
+},
+basrs[] = {
+   {BASR_ATN, "ATN"},
+   {BASR_ACK, "ACK"},
+   {0, NULL}
+},
+icrs[] = {
+   {ICR_ASSERT_RST, "ASSERT RST"},
+   {ICR_ASSERT_ACK, "ASSERT ACK"},
+   {ICR_ASSERT_BSY, "ASSERT BSY"},
+   {ICR_ASSERT_SEL, "ASSERT SEL"},
+   {ICR_ASSERT_ATN, "ASSERT ATN"},
+   {ICR_ASSERT_DATA, "ASSERT DATA"},
+   {0, NULL}
+},
+mrs[] = {
+   {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
+   {MR_TARGET, "MODE TARGET"},
+   {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
+   {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
+   {MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
{MR_MONITOR_BSY, "MODE MONITOR BSY"},
-   {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"},
+   {MR_DMA_MODE, "MODE DMA"},
+   {MR_ARBITRATE, "MODE ARBITRATION"},
{0, NULL}
 };
 
@@ -502,8 +519,12 @@ static struct {
unsigned char value;
const char *name;
 } phases[] = {
-   {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, 
"CMDOUT"},
-   {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, 
"MSGIN"},
+   {PHASE_DATAOUT, "DATAOUT"},
+   {PHASE_DATAIN, "DATAIN"},
+   {PHASE_CMDOUT, "CMDOUT"},
+   {PHASE_STATIN, "STATIN"},
+   {PHASE_MSGOUT, "MSGOUT"},
+   {PHASE_MSGIN, "MSGIN"},
{PHASE_UNKNOWN, "UNKNOWN"}
 };
 
@@ -529,7 +550,6 @@ static void NCR5380_print_phase(struct S
shost_printk(KERN_DEBUG, instance, "phase %s\n", 
phases[i].name);
}
 }
-
 #endif
 
 /**
@@ -1488,9 +1508,9 @@ static int NCR5380_transfer_pio(struct S
unsigned char *phase, int *count,
unsigned char **data)
 {
-   register unsigned char p = *phase, tmp;
-   register int c = *count;
-   register unsigned char *d = *data;
+   unsigned char p = *phase, tmp;
+   int c = *count;
+   unsigned char *d = *data;
 
/*
 * The NCR5380 chip will only drive the SCSI bus when the
@@ -1557,17 +1577,17 @@ static int NCR5380_transfer_pio(struct S
 
dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake 
complete\n");
 
-   /*
-* We have several special cases to consider during REQ/ACK 
handshaking :
-* 1.  We were in MSGOUT phase, and we are on the last byte of 
the
-* message.  ATN must be dropped as ACK is dropped.
-*
-* 2.  We are in a MSGIN phase, and we are on the last byte of 
the
-* message.  We must exit with ACK asserted, so that the calling
-* code may raise ATN before dropping ACK to reject the message.
-*
-* 3.  ACK and ATN are clear and the target may proceed as 
normal.
-*/
+/*
+ * We have several special cases to consider during REQ/ACK handshaking :
+ * 1.  We were in MSGOUT phase, and we are on the last byte of the
+ * message.  ATN must be dropped as ACK is dropped.
+ *
+ * 2.  We are in a MSGIN phase, and we are on the last byte of the
+ * message.  We must exit with ACK asserted, so 

[PATCH v3 68/77] ncr5380: Fix whitespace issues using regexp

2015-12-21 Thread Finn Thain
This patch is just the result of two substitutions. The first removes any
tabs and spaces at the end of the line. The second replaces runs of
tabs and spaces at the beginning of comment lines with a single space.

perl -i -pe 's,[\t ]+$,,; s,^(\t*[/ ]\*)[ \t]+,$1 ,' 
drivers/scsi/{atari_,}NCR5380.c 

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |  550 +--
 drivers/scsi/atari_NCR5380.c |  110 
 2 files changed, 330 insertions(+), 330 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:17:18.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:17:19.0 +1100
@@ -1,17 +1,17 @@
-/* 
+/*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *  to implement 5380 SCSI drivers under Linux with a non-trantor
- *  architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *  Note that these routines also work with NR53c400 family chips.
+ * Note that these routines also work with NR53c400 family chips.
  *
  * Copyright 1993, Drew Eckhardt
- *  Visionary Computing 
- *  (Unix and Linux consulting and custom programming)
- *  d...@colorado.edu
- *  +1 (303) 666-5836
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * d...@colorado.edu
+ * +1 (303) 666-5836
  *
- * For more information, please consult 
+ * For more information, please consult
  *
  * NCR 5380 Family
  * SCSI Protocol Controller
@@ -30,17 +30,17 @@
  */
 
 /*
- * Further development / testing that should be done : 
+ * Further development / testing that should be done :
  * 1.  Cleanup the NCR5380_transfer_dma function and DMA operation complete
- * code so that everything does the same thing that's done at the 
- * end of a pseudo-DMA read operation.
+ * code so that everything does the same thing that's done at the
+ * end of a pseudo-DMA read operation.
  *
  * 2.  Fix REAL_DMA (interrupt driven, polled works fine) -
- * basically, transfer size needs to be reduced by one 
- * and the last byte read as is done with PSEUDO_DMA.
- * 
- * 4.  Test SCSI-II tagged queueing (I have no devices which support 
- *  tagged queueing)
+ * basically, transfer size needs to be reduced by one
+ * and the last byte read as is done with PSEUDO_DMA.
+ *
+ * 4.  Test SCSI-II tagged queueing (I have no devices which support
+ * tagged queueing)
  */
 
 #ifndef notyet
@@ -56,27 +56,27 @@
 /*
  * Design
  *
- * This is a generic 5380 driver.  To use it on a different platform, 
+ * This is a generic 5380 driver.  To use it on a different platform,
  * one simply writes appropriate system specific macros (ie, data
- * transfer - some PC's will use the I/O bus, 68K's must use 
+ * transfer - some PC's will use the I/O bus, 68K's must use
  * memory mapped) and drops this file in their 'C' wrapper.
  *
- * As far as command queueing, two queues are maintained for 
+ * As far as command queueing, two queues are maintained for
  * each 5380 in the system - commands that haven't been issued yet,
- * and commands that are currently executing.  This means that an 
- * unlimited number of commands may be queued, letting 
- * more commands propagate from the higher driver levels giving higher 
- * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported, 
- * allowing multiple commands to propagate all the way to a SCSI-II device 
+ * and commands that are currently executing.  This means that an
+ * unlimited number of commands may be queued, letting
+ * more commands propagate from the higher driver levels giving higher
+ * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported,
+ * allowing multiple commands to propagate all the way to a SCSI-II device
  * while a command is already executing.
  *
  *
- * Issues specific to the NCR5380 : 
+ * Issues specific to the NCR5380 :
  *
- * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead 
- * piece of hardware that requires you to sit in a loop polling for 
- * the REQ signal as long as you are connected.  Some devices are 
- * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect 
+ * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead
+ * piece of hardware that requires you to sit in a loop polling for
+ * the REQ signal as long as you are connected.  Some devices are
+ * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
  * while doing long seek operations. [...] These
  * broken devices are the exception rather than the rule and I'd rather
  * spend my time optimizing for the normal case.
@@ -87,23 +87,23 @@
  * which is 

[PATCH v3 28/77] ncr5380: Drop DEF_SCSI_QCMD macro

2015-12-21 Thread Finn Thain
Remove the DEF_SCSI_QCMD macro (already removed from atari_NCR5380.c). The
lock provided by DEF_SCSI_QCMD is only needed for queue data structures.

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   30 +++---
 drivers/scsi/atari_NCR5380.c |2 +-
 2 files changed, 16 insertions(+), 16 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:14.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:15.0 +1100
@@ -808,22 +808,21 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
- * NCR5380_queue_command   -   queue a command
- * @cmd: SCSI command
- * @done: completion handler
+ * NCR5380_queue_command - queue a command
+ * @instance: the relevant SCSI adapter
+ * @cmd: SCSI command
  *
- *  cmd is added to the per instance issue_queue, with minor 
- *  twiddling done to the host specific fields of cmd.  If the 
- *  main coroutine is not running, it is restarted.
- *
- * Locks: host lock taken by caller
+ * cmd is added to the per-instance issue queue, with minor
+ * twiddling done to the host specific fields of cmd.  If the
+ * main coroutine is not running, it is restarted.
  */
 
-static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd, void (*done) 
(struct scsi_cmnd *))
+static int NCR5380_queue_command(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
 {
-   struct Scsi_Host *instance = cmd->device->host;
-   struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
instance->hostdata;
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
struct scsi_cmnd *tmp;
+   unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
switch (cmd->cmnd[0]) {
@@ -831,7 +830,7 @@ static int NCR5380_queue_command_lck(str
case WRITE_10:
printk("scsi%d : WRITE attempted with NO_WRITE debugging flag 
set\n", instance->host_no);
cmd->result = (DID_ERROR << 16);
-   done(cmd);
+   cmd->scsi_done(cmd);
return 0;
}
 #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
@@ -842,9 +841,10 @@ static int NCR5380_queue_command_lck(str
 */
 
cmd->host_scribble = NULL;
-   cmd->scsi_done = done;
cmd->result = 0;
 
+   spin_lock_irqsave(instance->host_lock, flags);
+
/* 
 * Insert the cmd into the issue queue. Note that REQUEST SENSE 
 * commands are added to the head of the queue since any command will
@@ -861,6 +861,8 @@ static int NCR5380_queue_command_lck(str
LIST(cmd, tmp);
tmp->host_scribble = (unsigned char *) cmd;
}
+   spin_unlock_irqrestore(instance->host_lock, flags);
+
dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", 
instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
/* Run the coroutine if it isn't already running. */
@@ -869,8 +871,6 @@ static int NCR5380_queue_command_lck(str
return 0;
 }
 
-static DEF_SCSI_QCMD(NCR5380_queue_command)
-
 /**
  * NCR5380_main-   NCR state machines
  *
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:12.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:15.0 +1100
@@ -930,7 +930,7 @@ static void NCR5380_exit(struct Scsi_Hos
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
  *
- * cmd is added to the per instance issue_queue, with minor
+ * cmd is added to the per-instance issue queue, with minor
  * twiddling done to the host specific fields of cmd.  If the
  * main coroutine is not running, it is restarted.
  */


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 24/77] ncr5380: Implement NCR5380_dma_xfer_len and remove LIMIT_TRANSFERSIZE macro

2015-12-21 Thread Finn Thain
Follow the example of the atari_NCR5380.c core driver and adopt the
NCR5380_dma_xfer_len() hook. Implement NCR5380_dma_xfer_len() for dtc.c
and g_NCR5380.c to take care of the limitations of these cards. Keep the
default for drivers using PSEUDO_DMA.

Eliminate the unused macro LIMIT_TRANSFERSIZE. 

Signed-off-by: Finn Thain 

---
 drivers/scsi/NCR5380.c   |   32 +---
 drivers/scsi/arm/cumana_1.c  |3 +++
 drivers/scsi/arm/oak.c   |2 ++
 drivers/scsi/atari_NCR5380.c |8 +---
 drivers/scsi/dtc.c   |   14 ++
 drivers/scsi/dtc.h   |3 +++
 drivers/scsi/g_NCR5380.c |   15 +++
 drivers/scsi/g_NCR5380.h |3 +++
 drivers/scsi/mac_scsi.c  |1 +
 drivers/scsi/pas16.h |2 ++
 drivers/scsi/t128.h  |2 ++
 11 files changed, 55 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-22 12:16:04.0 +1100
+++ linux/drivers/scsi/NCR5380.c2015-12-22 12:16:07.0 +1100
@@ -201,11 +201,6 @@
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
  *  override-configure an IRQ.
  *
- * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
- *  bytes at a time.  Since interrupts are disabled by default during
- *  these transfers, we might need this to give reasonable interrupt
- *  service time if the transfer size gets too large.
- *
  * LINKED - if defined, linked commands are supported.
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
@@ -2000,29 +1995,12 @@ static void NCR5380_information_transfer
 */
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
-   /* KLL
-* PSEUDO_DMA is defined here. If this is the 
g_NCR5380
-* driver then it will always be defined, so the
-* FLAG_NO_PSEUDO_DMA is used to inhibit PDMA 
in the base
-* NCR5380 case.  I think this is a fairly 
clean solution.
-* We supplement these 2 if's with the flag.
-*/
-#ifdef NCR5380_dma_xfer_len
-   if (!cmd->device->borken && !(hostdata->flags & 
FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 
0) {
-#else
-   transfersize = cmd->transfersize;
+   transfersize = 0;
+   if (!cmd->device->borken &&
+   !(hostdata->flags & FLAG_NO_PSEUDO_DMA))
+   transfersize = 
NCR5380_dma_xfer_len(instance, cmd, phase);
 
-#ifdef LIMIT_TRANSFERSIZE  /* If we have problems with interrupt service */
-   if (transfersize > 512)
-   transfersize = 512;
-#endif /* LIMIT_TRANSFERSIZE */
-
-   if (!cmd->device->borken && transfersize && 
!(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && 
!(cmd->SCp.this_residual % transfersize)) {
-   /* Limit transfers to 32K, for xx400 & 
xx406
-* pseudoDMA that transfers in 128 
bytes blocks. */
-   if (transfersize > 32 * 1024)
-   transfersize = 32 * 1024;
-#endif
+   if (transfersize) {
len = transfersize;
if (NCR5380_transfer_dma(instance, 
, , (unsigned char **) >SCp.ptr)) {
/*
Index: linux/drivers/scsi/atari_NCR5380.c
===
--- linux.orig/drivers/scsi/atari_NCR5380.c 2015-12-22 12:16:04.0 
+1100
+++ linux/drivers/scsi/atari_NCR5380.c  2015-12-22 12:16:07.0 +1100
@@ -2170,11 +2170,13 @@ static void NCR5380_information_transfer
 */
 
 #if defined(REAL_DMA)
-   if (
 #if !defined(CONFIG_SUN3)
-   !cmd->device->borken &&
+   transfersize = 0;
+   if (!cmd->device->borken)
 #endif
-   (transfersize = 
NCR5380_dma_xfer_len(instance, cmd, phase)) >= DMA_MIN_SIZE) {
+   transfersize = 
NCR5380_dma_xfer_len(instance, cmd, phase);
+
+   if (transfersize >= DMA_MIN_SIZE) {
len = transfersize;
  

  1   2   >