linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] Persistent naming of scsi devices
@ 2002-04-08 15:18 sullivan
  2002-04-08 15:04 ` Christoph Hellwig
                   ` (2 more replies)
  0 siblings, 3 replies; 297+ messages in thread
From: sullivan @ 2002-04-08 15:18 UTC (permalink / raw)
  To: linux-scsi

I have been working on a prototype to allow the persistent naming of scsi devices across boots. The prototype attempts to address the namespace slippage that occurs when names are assigned based on discovery order or topology, and a hardware configuration change occurs. It does this by assigning names based on the characteristics of the device.

The prototype and more detailed info can be found at:
http://oss.software.ibm.com/devreg/

The prototype utilizes 3 components:
1. driverfs to collect and publish the characteristics of the device
2. devfs to generate insertion and removal events
3. devfsd library to handle the events, parse driverfs, and apply the naming logic.

I am also currently working on a non devfs version that uses /sbin/hotplug as the event generation mechanism.

I would welcome any thoughts, comments, or suggestions.

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-08 16:11 Matt_Domsch
  0 siblings, 0 replies; 297+ messages in thread
From: Matt_Domsch @ 2002-04-08 16:11 UTC (permalink / raw)
  To: sullivan, linux-scsi

> I have been working on a prototype to allow the persistent 
> naming of scsi devices across boots. The prototype attempts 
> to address the namespace slippage that occurs when names are 
> assigned based on discovery order or topology, and a hardware 
> configuration change occurs. It does this by assigning names 
> based on the characteristics of the device.

> I think we should rather get people
> to actually use the UUID= option to mount..

Agreed.  Andreas' swap partition patches are needed here too.

The only other case this is tricky is at clean-disk install time, before any
UUIDs are available, when you've got disks on multiple controllers.  Here,
the BIOS and Linux have no way to communicate which device they each think
is the boot device.  Some BIOSs (like on Adaptec 39160 add-in cards, and
7890/7899 embedded controllers on Dell servers) provide BIOS Enhanced Disk
Device Services 3.0 (EDD 3.0), which provides an extension to BIOS int13
AX=48 which specifies, for BIOS's idea of device 80, 81, ..., the PCI
bus/dev/fn and type (SCSI/IDE,...) Not all BIOSs yet provide such. :-(  But,
having that, Linux could then compare its similar mapping, and get right
without manual intervention what disk is the boot disk.

-Matt
--
Matt Domsch
Sr. Software Engineer
Dell Linux Solutions www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com
#1 US Linux Server provider for 2001!

^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: [RFC] Persistent naming of scsi devices
@ 2002-04-08 19:18 Martin Peschke3
  2002-04-08 20:45 ` Matthew Jacob
  2002-04-10  1:16 ` Rick Stevens
  0 siblings, 2 replies; 297+ messages in thread
From: Martin Peschke3 @ 2002-04-08 19:18 UTC (permalink / raw)
  To: James Bottomley
  Cc: mjacob, Oliver Neukum, Christoph Hellwig, sullivan, linux-scsi



> mjacob@feral.com said:
> > Then let's use WWPN/WWNS and/or drive serial #'s to do UUIDs for
> > devices.
>
> That's what the persistent binding proposal that started all this uses.
> However, these strings are incredibly long at best and (in spite of what
the
> SCSI spec says) sometimes include non-printing characters, so you don't
> necessarily want to be passing them on the command line.
>
> James

That's true of course for Fibre Channel WWNs (64 bit).
Such identifiers might be shorter (or longer)
depending on the considered interface.
What could be used for good old parallel attachments?

I would suggest to circumvent problems with non-printing
characters by means of hexadecimal notation
(e.g. 0x5007890000a11753 representing a WWN).


Mit freundlichen Grüßen / with kind regards

Martin Peschke

IBM Deutschland Entwicklung GmbH
Linux for eServer Development
Phone: +49-(0)7031-16-2349



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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: [RFC] Persistent naming of scsi devices
@ 2002-04-08 22:05 Martin Peschke3
  2002-04-08 22:17 ` Matthew Jacob
  0 siblings, 1 reply; 297+ messages in thread
From: Martin Peschke3 @ 2002-04-08 22:05 UTC (permalink / raw)
  To: mjacob
  Cc: James Bottomley, Oliver Neukum, Christoph Hellwig, sullivan,
	linux-scsi

> It's more than just a WWN- it really has to be
> the pair of WWNN/WWPN (node && port name) as you
> can have, e.g., a dual ported disk with the same WWNN but
> different WWPNs.

Ok, I thought of WWPN and that it would be sufficient to identify the
target side of a link, isn't it?
Do you really need a pair of WWNN/WWPN, i.e. identical WWPNs might
exist considering different WWNNs?


Mit freundlichen Grüßen / with kind regards

Martin Peschke

IBM Deutschland Entwicklung GmbH
Linux for eServer Development
Phone: +49-(0)7031-16-2349


Matthew Jacob <mjacob@feral.com>@vger.kernel.org on 04/08/2002 10:45:33 PM

Please respond to mjacob@feral.com

Sent by:    linux-scsi-owner@vger.kernel.org


To:    Martin Peschke3/Germany/IBM@IBMDE
cc:    James Bottomley <James.Bottomley@steeleye.com>, Oliver Neukum
       <oliver@neukum.org>, Christoph Hellwig <hch@infradead.org>, sullivan
       <sullivan@austin.ibm.com>, linux-scsi@vger.kernel.org
Subject:    Re: [RFC] Persistent naming of scsi devices




It's more than just a WWN- it really has to be the pair of WWNN/WWPN (node
&&
port name) as you can have, e.g., a dual ported disk with the same WWNN but
different WWPNs.

On Mon, 8 Apr 2002, Martin Peschke3 wrote:

>
>
> > mjacob@feral.com said:
> > > Then let's use WWPN/WWNS and/or drive serial #'s to do UUIDs for
> > > devices.
> >
> > That's what the persistent binding proposal that started all this uses.
> > However, these strings are incredibly long at best and (in spite of
what
> the
> > SCSI spec says) sometimes include non-printing characters, so you don't
> > necessarily want to be passing them on the command line.
> >
> > James
>
> That's true of course for Fibre Channel WWNs (64 bit).
> Such identifiers might be shorter (or longer)
> depending on the considered interface.
> What could be used for good old parallel attachments?
>
> I would suggest to circumvent problems with non-printing
> characters by means of hexadecimal notation
> (e.g. 0x5007890000a11753 representing a WWN).
>
>
> Mit freundlichen Grüßen / with kind regards
>
> Martin Peschke
>
> IBM Deutschland Entwicklung GmbH
> Linux for eServer Development
> Phone: +49-(0)7031-16-2349
>
>
>
>

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



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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: [RFC] Persistent naming of scsi devices
@ 2002-04-10  1:40 Bryan Henderson
  0 siblings, 0 replies; 297+ messages in thread
From: Bryan Henderson @ 2002-04-10  1:40 UTC (permalink / raw)
  To: Rick Stevens; +Cc: linux-scsi

>E.g. "/dev/dsk/c0t1d2s3" is controller 0 (first SCSI controller seen on
>the bus), target ID 1, LUN 2, partition (slice) 3.  Simple, unambiguous
>and repeatable.

For many purposes, you're right, and for that reason devfs already does 
this.  However, in some cases these are not repeatable.  A volume that is 
LUN 5 today could be LUN 7 tomorrow.  This is true in heavy-duty disk 
storage subsystems that let you create and destroy logical units on the 
fly, using the physical medium as a resource pool.  And what is LUN 5 for 
me could be LUN 7 for you at the same time, if we're both wired into the 
same storage subsystem.


^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-10 14:28 berthiaume_wayne
  0 siblings, 0 replies; 297+ messages in thread
From: berthiaume_wayne @ 2002-04-10 14:28 UTC (permalink / raw)
  To: rstevens; +Cc: linux-scsi

	Actually, it would be easier to control if it uses its actual PCI
slot number, for example c2 for the second slot, as opposed to c2 for the
second SCSI controller. This would be easier to implement and would be
"persistent" as long as the controller is not moved. Doing it in the manner
you suggest would not provide persistence but revert to the order of
discovery we already have with a different naming convention. Doesn't seem
like a wise alternative. The intention of the CTDL nomenclature is to
provide precise device targeting without the BS mapping to some arbitrarily
named device table. In DG/AViiON, more precisely DG/UX, it was CTDL based
but then mapped to a device mneumonic in the devtable. Devices were named in
the system config file by their long name (CTDL) and linked in the devtable
to its short name, for example /dev/pdsk/sd0 for the buffered SCSI disk and
/dev/rpdsk/sd0 for the raw SCSI disk. We used different SCSI controllers but
this didn't present a problem because, they were placed in the kernel config
file. If the Ciprico was in slot 0 and in the kernel's spec file, it's long
name was entered into the devtable and linked at boot to the short name
/dev/pdsk/sd0. Conversely, if the Adaptec was in slot 0 and configured into
the kernel spec file, its long name would be entered into the devtable and
linked to the /dev/pdsk/sd0 short name.
Wayne
EMC Corp
Centera Engineering
4400 Computer Drive
M/S F213
Westboro,  MA    01580

email:       Berthiaume_Wayne@emc.com

"One man can make a difference, and every man should try."  - JFK


-----Original Message-----
From: Rick Stevens [mailto:rstevens@vitalstream.com]
Sent: Tuesday, April 09, 2002 9:17 PM
To: linux-scsi@vger.kernel.org
Subject: Re: [RFC] Persistent naming of scsi devices


Martin Peschke3 wrote:

<much stuff snipped>

I'm going to wade in here.  Based on my experiences on many other
Unixish systems, wouldn't it be simply better to number the things
based on controller position, SCSI ID, LUN and partition?  This
has been called "CTL" format in various documents, and many systems
use this method such as Sun, DG AvIIons, DEC, HP and a host of others.

E.g. "/dev/dsk/c0t1d2s3" is controller 0 (first SCSI controller seen on
the bus), target ID 1, LUN 2, partition (slice) 3.  Simple, unambiguous
and repeatable.

I understand that other devices may be seen on the PCI if you add or
remove cards.  Under this scheme, controller 0 is the first (lowest
slot number) unit found.  The next one would be controller 1.  Even
if you were to stuff, say, a video card in there, these would _still_
be the first SCSI cards found.  The only time a change would occur
is if a SCSI card was installed in a lower slot number or between
other SCSI controllers (and only then if the original cards were
left in) or if the ORDER of the cards was changed in the bus.

As I said, other people smarter than I seem to think it makes sense.
Why not Linux?  It's silly to smush things together just to satisfy a
bizzare craving to have a list of devices with no "holes" in it.
Besides "fsck"ing or "mkfs"ing drives, how often do you refer to them
by their names in "/dev", anyway?

This would also work for tape drives.  However, they're rooted at
/dev/stape rather than /dev/dsk.

At boot, you could create more mnemonic names as symbolic links to the
CTL names if you wish (as is done with /dev/cdrom and such), but if
you absolutely want to talk to the SAME DEVICE, you use the CTL name.

Just adding my $0.02.  We now return you to your regularly scheduled
arguments.

----------------------------------------------------------------------
- Rick Stevens, SSE, VitalStream, Inc.      rstevens@vitalstream.com -
- 949-743-2010 (Voice)                    http://www.vitalstream.com -
-                                                                    -
-          su -; find / -name someone -exec touch \{\} \;            -
-                          - The UNIX way of touching someone        -
----------------------------------------------------------------------

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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-10 14:36 berthiaume_wayne
  2002-04-10 16:02 ` Matthew Jacob
  0 siblings, 1 reply; 297+ messages in thread
From: berthiaume_wayne @ 2002-04-10 14:36 UTC (permalink / raw)
  To: hbryan; +Cc: linux-scsi

	This is true with the design of today's virtual LUNs on the storage
arrays. However, I believe that if you are sharing a VLUN on the array the
same WWNN/WWPN is assigned to it. Though it may be represented to you as
VLUN 1 in your virtual storage system and VLUN 6 in mine I thought the same
WWNN/WWPN was assigned to it.

-----Original Message-----
From: Bryan Henderson [mailto:hbryan@us.ibm.com]
Sent: Tuesday, April 09, 2002 9:40 PM
To: Rick Stevens
Cc: linux-scsi@vger.kernel.org
Subject: Re: [RFC] Persistent naming of scsi devices


>E.g. "/dev/dsk/c0t1d2s3" is controller 0 (first SCSI controller seen on
>the bus), target ID 1, LUN 2, partition (slice) 3.  Simple, unambiguous
>and repeatable.

For many purposes, you're right, and for that reason devfs already does 
this.  However, in some cases these are not repeatable.  A volume that is 
LUN 5 today could be LUN 7 tomorrow.  This is true in heavy-duty disk 
storage subsystems that let you create and destroy logical units on the 
fly, using the physical medium as a resource pool.  And what is LUN 5 for 
me could be LUN 7 for you at the same time, if we're both wired into the 
same storage subsystem.

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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-10 15:28 Bryan Henderson
  0 siblings, 0 replies; 297+ messages in thread
From: Bryan Henderson @ 2002-04-10 15:28 UTC (permalink / raw)
  To: berthiaume_wayne; +Cc: linux-scsi


>I believe that if you are sharing a VLUN on the array the
>same WWNN/WWPN is assigned to it. Though it may be represented to you as
>VLUN 1 in your virtual storage system and VLUN 6 in mine I thought the
same
>WWNN/WWPN was assigned to it.

Yes, every system I've seen does that and it seems to be the intent (for
whatever that's worth) of the fibre channel architects.  But how is that
relevant?  We're talking about uniquely identifying a logical unit (which
is what would appear in Linux as a device).

I don't know what a VLUN is, so maybe I'm just lost.  Isn't that redundant?
Virtual and logical are the same thing.

Leave the WWPN (worldwide port number) out of it, by the way.  That doesn't
help identify devices, just ports that can be used to reach them.



^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: [RFC] Persistent naming of scsi devices
@ 2002-04-10 15:52 Martin Peschke3
  2002-04-10 19:33 ` Matthew Jacob
  0 siblings, 1 reply; 297+ messages in thread
From: Martin Peschke3 @ 2002-04-10 15:52 UTC (permalink / raw)
  To: mjacob
  Cc: James Bottomley, Oliver Neukum, Christoph Hellwig, sullivan,
	linux-scsi

Matt,

> > > It's more than just a WWN- it really has to be
> > > the pair of WWNN/WWPN (node && port name) as you
> > > can have, e.g., a dual ported disk with the same WWNN but
> > > different WWPNs.
> >
> > Ok, I thought of WWPN and that it would be sufficient to identify the
> > target side of a link, isn't it? Do you really need a pair of
WWNN/WWPN,
> > i.e. identical WWPNs might exist considering different WWNNs?
>
> If the numbering is NAA=2 (2 in the top nibble), you can always derive
the
> WWNN from the WWPN. But that's only true for NAA=2.
>
> In *practice*, WWPN might be enough,  but if we're doing things that
formally
> and fully ID a device, and considering that iSCSI identifiers are 255
bytes or
> better, two 64 bit ids for Fibre Channel devices is not unreasonable to
allow
> for.
>
> -matt

If there are cases which require WWNN+WWPN to identify a
FC port then a you would need this pair to query a FC ports
D_ID. I wonder why this is not reflected in the FC name server
specification, FC-GS-3, (see GID_PN for example).


Mit freundlichen Grüßen / with kind regards

Martin Peschke

IBM Deutschland Entwicklung GmbH
Linux for eServer Development
Phone: +49-(0)7031-16-2349


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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-10 16:44 berthiaume_wayne
  0 siblings, 0 replies; 297+ messages in thread
From: berthiaume_wayne @ 2002-04-10 16:44 UTC (permalink / raw)
  To: hbryan; +Cc: linux-scsi

	VLUN = virtual LUN   

	This would be the number assigned by the storage system. A storage
system can be broken up into multiple virtual storage systems each unique to
the owner. The real trick is when to virtual storage systems share the same
LUN. Depending on the order of entry into the virtual storage array on a
CLARiiON at the time it is being configured it could be a LUN 1 to your
virtual storage and LUN 6 on mine.

-----Original Message-----
From: Bryan Henderson [mailto:hbryan@us.ibm.com]
Sent: Wednesday, April 10, 2002 11:28 AM
To: berthiaume_wayne@emc.com
Cc: linux-scsi@vger.kernel.org
Subject: RE: [RFC] Persistent naming of scsi devices



>I believe that if you are sharing a VLUN on the array the
>same WWNN/WWPN is assigned to it. Though it may be represented to you as
>VLUN 1 in your virtual storage system and VLUN 6 in mine I thought the
same
>WWNN/WWPN was assigned to it.

Yes, every system I've seen does that and it seems to be the intent (for
whatever that's worth) of the fibre channel architects.  But how is that
relevant?  We're talking about uniquely identifying a logical unit (which
is what would appear in Linux as a device).

I don't know what a VLUN is, so maybe I'm just lost.  Isn't that redundant?
Virtual and logical are the same thing.

Leave the WWPN (worldwide port number) out of it, by the way.  That doesn't
help identify devices, just ports that can be used to reach them.


^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-10 19:02 Martin Peschke3
  0 siblings, 0 replies; 297+ messages in thread
From: Martin Peschke3 @ 2002-04-10 19:02 UTC (permalink / raw)
  To: berthiaume_wayne; +Cc: rstevens, linux-scsi


What's about non-PCI SCSI adapters?

Another idea regarding a topology oriented naming scheme:

replace     /dev/scsi/host<index>/...
by          /dev/scsi/<hba driver name>/<unique id>/...

Both <hba driver name> and <unique id> are available for each
HBA in the mid layers data today.
This proposal assumes that a particular HBA is driven by
not more than one HBA driver at the same time. Besides,
<unique id> (provided by HBA driver) should be persistent
in the scope of a particular HBA driver. You might use PCI
slot or any other architecture dependent characteristic.


Mit freundlichen Grüßen / with kind regards

Martin Peschke

IBM Deutschland Entwicklung GmbH
Linux for eServer Development
Phone: +49-(0)7031-16-2349


berthiaume_wayne@emc.com@vger.kernel.org on 04/10/2002 04:28:33 PM

Please respond to berthiaume_wayne@emc.com

Sent by:    linux-scsi-owner@vger.kernel.org


To:    rstevens@vitalstream.com
cc:    linux-scsi@vger.kernel.org
Subject:    RE: [RFC] Persistent naming of scsi devices



 Actually, it would be easier to control if it uses its actual PCI
slot number, for example c2 for the second slot, as opposed to c2 for the
second SCSI controller. This would be easier to implement and would be
"persistent" as long as the controller is not moved. Doing it in the manner
you suggest would not provide persistence but revert to the order of
discovery we already have with a different naming convention. Doesn't seem
like a wise alternative. The intention of the CTDL nomenclature is to
provide precise device targeting without the BS mapping to some arbitrarily
named device table. In DG/AViiON, more precisely DG/UX, it was CTDL based
but then mapped to a device mneumonic in the devtable. Devices were named
in
the system config file by their long name (CTDL) and linked in the devtable
to its short name, for example /dev/pdsk/sd0 for the buffered SCSI disk and
/dev/rpdsk/sd0 for the raw SCSI disk. We used different SCSI controllers
but
this didn't present a problem because, they were placed in the kernel
config
file. If the Ciprico was in slot 0 and in the kernel's spec file, it's long
name was entered into the devtable and linked at boot to the short name
/dev/pdsk/sd0. Conversely, if the Adaptec was in slot 0 and configured into
the kernel spec file, its long name would be entered into the devtable and
linked to the /dev/pdsk/sd0 short name.
Wayne
EMC Corp
Centera Engineering
4400 Computer Drive
M/S F213
Westboro,  MA    01580

email:       Berthiaume_Wayne@emc.com

"One man can make a difference, and every man should try."  - JFK


-----Original Message-----
From: Rick Stevens [mailto:rstevens@vitalstream.com]
Sent: Tuesday, April 09, 2002 9:17 PM
To: linux-scsi@vger.kernel.org
Subject: Re: [RFC] Persistent naming of scsi devices


Martin Peschke3 wrote:

<much stuff snipped>

I'm going to wade in here.  Based on my experiences on many other
Unixish systems, wouldn't it be simply better to number the things
based on controller position, SCSI ID, LUN and partition?  This
has been called "CTL" format in various documents, and many systems
use this method such as Sun, DG AvIIons, DEC, HP and a host of others.

E.g. "/dev/dsk/c0t1d2s3" is controller 0 (first SCSI controller seen on
the bus), target ID 1, LUN 2, partition (slice) 3.  Simple, unambiguous
and repeatable.

I understand that other devices may be seen on the PCI if you add or
remove cards.  Under this scheme, controller 0 is the first (lowest
slot number) unit found.  The next one would be controller 1.  Even
if you were to stuff, say, a video card in there, these would _still_
be the first SCSI cards found.  The only time a change would occur
is if a SCSI card was installed in a lower slot number or between
other SCSI controllers (and only then if the original cards were
left in) or if the ORDER of the cards was changed in the bus.

As I said, other people smarter than I seem to think it makes sense.
Why not Linux?  It's silly to smush things together just to satisfy a
bizzare craving to have a list of devices with no "holes" in it.
Besides "fsck"ing or "mkfs"ing drives, how often do you refer to them
by their names in "/dev", anyway?

This would also work for tape drives.  However, they're rooted at
/dev/stape rather than /dev/dsk.

At boot, you could create more mnemonic names as symbolic links to the
CTL names if you wish (as is done with /dev/cdrom and such), but if
you absolutely want to talk to the SAME DEVICE, you use the CTL name.

Just adding my $0.02.  We now return you to your regularly scheduled
arguments.

----------------------------------------------------------------------
- Rick Stevens, SSE, VitalStream, Inc.      rstevens@vitalstream.com -
- 949-743-2010 (Voice)                    http://www.vitalstream.com -
-                                                                    -
-          su -; find / -name someone -exec touch \{\} \;            -
-                          - The UNIX way of touching someone        -
----------------------------------------------------------------------

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



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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-10 20:24 berthiaume_wayne
  0 siblings, 0 replies; 297+ messages in thread
From: berthiaume_wayne @ 2002-04-10 20:24 UTC (permalink / raw)
  To: MPESCHKE; +Cc: rstevens, linux-scsi

	True, there is a hole in the PCI slot logic - onboard SCSI chips for
instance. Using /dev/scsi/<hba driver name>/<unique id>/... does have it
merits as it would lend a quick physical identification, if one can remember
the driver's name for a particular HBA. =;^)

-----Original Message-----
From: Martin Peschke3 [mailto:MPESCHKE@de.ibm.com]
Sent: Wednesday, April 10, 2002 3:03 PM
To: berthiaume_wayne@emc.com
Cc: rstevens@vitalstream.com; linux-scsi@vger.kernel.org
Subject: RE: [RFC] Persistent naming of scsi devices



What's about non-PCI SCSI adapters?

Another idea regarding a topology oriented naming scheme:

replace     /dev/scsi/host<index>/...
by          /dev/scsi/<hba driver name>/<unique id>/...

Both <hba driver name> and <unique id> are available for each
HBA in the mid layers data today.
This proposal assumes that a particular HBA is driven by
not more than one HBA driver at the same time. Besides,
<unique id> (provided by HBA driver) should be persistent
in the scope of a particular HBA driver. You might use PCI
slot or any other architecture dependent characteristic.


Mit freundlichen Grüßen / with kind regards

Martin Peschke

IBM Deutschland Entwicklung GmbH
Linux for eServer Development
Phone: +49-(0)7031-16-2349


berthiaume_wayne@emc.com@vger.kernel.org on 04/10/2002 04:28:33 PM

Please respond to berthiaume_wayne@emc.com

Sent by:    linux-scsi-owner@vger.kernel.org


To:    rstevens@vitalstream.com
cc:    linux-scsi@vger.kernel.org
Subject:    RE: [RFC] Persistent naming of scsi devices



 Actually, it would be easier to control if it uses its actual PCI
slot number, for example c2 for the second slot, as opposed to c2 for the
second SCSI controller. This would be easier to implement and would be
"persistent" as long as the controller is not moved. Doing it in the manner
you suggest would not provide persistence but revert to the order of
discovery we already have with a different naming convention. Doesn't seem
like a wise alternative. The intention of the CTDL nomenclature is to
provide precise device targeting without the BS mapping to some arbitrarily
named device table. In DG/AViiON, more precisely DG/UX, it was CTDL based
but then mapped to a device mneumonic in the devtable. Devices were named
in
the system config file by their long name (CTDL) and linked in the devtable
to its short name, for example /dev/pdsk/sd0 for the buffered SCSI disk and
/dev/rpdsk/sd0 for the raw SCSI disk. We used different SCSI controllers
but
this didn't present a problem because, they were placed in the kernel
config
file. If the Ciprico was in slot 0 and in the kernel's spec file, it's long
name was entered into the devtable and linked at boot to the short name
/dev/pdsk/sd0. Conversely, if the Adaptec was in slot 0 and configured into
the kernel spec file, its long name would be entered into the devtable and
linked to the /dev/pdsk/sd0 short name.
Wayne
EMC Corp
Centera Engineering
4400 Computer Drive
M/S F213
Westboro,  MA    01580

email:       Berthiaume_Wayne@emc.com

"One man can make a difference, and every man should try."  - JFK


-----Original Message-----
From: Rick Stevens [mailto:rstevens@vitalstream.com]
Sent: Tuesday, April 09, 2002 9:17 PM
To: linux-scsi@vger.kernel.org
Subject: Re: [RFC] Persistent naming of scsi devices


Martin Peschke3 wrote:

<much stuff snipped>

I'm going to wade in here.  Based on my experiences on many other
Unixish systems, wouldn't it be simply better to number the things
based on controller position, SCSI ID, LUN and partition?  This
has been called "CTL" format in various documents, and many systems
use this method such as Sun, DG AvIIons, DEC, HP and a host of others.

E.g. "/dev/dsk/c0t1d2s3" is controller 0 (first SCSI controller seen on
the bus), target ID 1, LUN 2, partition (slice) 3.  Simple, unambiguous
and repeatable.

I understand that other devices may be seen on the PCI if you add or
remove cards.  Under this scheme, controller 0 is the first (lowest
slot number) unit found.  The next one would be controller 1.  Even
if you were to stuff, say, a video card in there, these would _still_
be the first SCSI cards found.  The only time a change would occur
is if a SCSI card was installed in a lower slot number or between
other SCSI controllers (and only then if the original cards were
left in) or if the ORDER of the cards was changed in the bus.

As I said, other people smarter than I seem to think it makes sense.
Why not Linux?  It's silly to smush things together just to satisfy a
bizzare craving to have a list of devices with no "holes" in it.
Besides "fsck"ing or "mkfs"ing drives, how often do you refer to them
by their names in "/dev", anyway?

This would also work for tape drives.  However, they're rooted at
/dev/stape rather than /dev/dsk.

At boot, you could create more mnemonic names as symbolic links to the
CTL names if you wish (as is done with /dev/cdrom and such), but if
you absolutely want to talk to the SAME DEVICE, you use the CTL name.

Just adding my $0.02.  We now return you to your regularly scheduled
arguments.

----------------------------------------------------------------------
- Rick Stevens, SSE, VitalStream, Inc.      rstevens@vitalstream.com -
- 949-743-2010 (Voice)                    http://www.vitalstream.com -
-                                                                    -
-          su -; find / -name someone -exec touch \{\} \;            -
-                          - The UNIX way of touching someone        -
----------------------------------------------------------------------

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


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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-11 16:01 Bryan Henderson
  0 siblings, 0 replies; 297+ messages in thread
From: Bryan Henderson @ 2002-04-11 16:01 UTC (permalink / raw)
  To: berthiaume_wayne; +Cc: linux-scsi

>                VLUN = virtual LUN 
>
>This would be the number assigned by the storage system. A storage
>system can be broken up into multiple virtual storage systems each unique 
to
>the owner. The real trick is when to virtual storage systems share the 
same
>LUN.

This VLUN sounds like what SCSI/FCP defines as a LUN.  What you're calling 
a LUN is apparently something that's not defined in SCSI.  I'm guessing a 
LUN here identifies a volume, and the same volume is connected to multiple 
SCSI logical units, one in each virtual storage subsystem.  I'm also 
assuming that a virtual storage subsystem is a target device/node in SCSI 
terms.

That raises the question:  What do you get if you INQUIRE as to the 
logical unit serial number of two SCSI logical units, in different virtual 
storage subsystems, associated with the same volume?  Is it the same 
serial number?

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-12 13:15 berthiaume_wayne
  0 siblings, 0 replies; 297+ messages in thread
From: berthiaume_wayne @ 2002-04-12 13:15 UTC (permalink / raw)
  To: hbryan; +Cc: linux-scsi

	The CLARiiON returns pages 00h, 80h, and 83h. Page 80h will contain
the array's serial number. Bytes 4 thru 23 of page 83h contain the
Identifier Descriptor 0 data which carries the LUN's WWN and bytes 24 thru
43 contain the Identifier Descriptor 1 data which carries the LUN and VLU
numbers. The LUN/VLU come from the VLUT (Virtual LUN Table). This is how you
are able to map your virtual LUN in your storage group to the physical LUN
in the array. The physical LUN itself is not a physical disk in the physical
array but created at the time you bind disks or portions of disks into LUN.
For example, I may bind five disks into a RAID 5 group and portion them up
into 10 LUNs. Then if I install and use the AccessLogix software on the
array I can break up the array into virtual arrays called Storage Groups to
be used by multiple hosts. Storage Groups can be shared or individually
owned and, for the clever array administrator, you can design individual
storage groups which contain private and shared LUNs. All this is only
possible because we utilize the WWN of the array. The LUNs themselves use a
concatenation of the array's WWN to form the WWN for each individual LUN.
The WWN for the attached HBA is used to identify the unique storage group.
Thus persistence is maintained in the array. Now the trick will be to get
the same for Linux. =;^)

-----Original Message-----
From: Bryan Henderson [mailto:hbryan@us.ibm.com]
Sent: Thursday, April 11, 2002 12:01 PM
To: berthiaume_wayne@emc.com
Cc: linux-scsi@vger.kernel.org
Subject: RE: [RFC] Persistent naming of scsi devices


>                VLUN = virtual LUN 
>
>This would be the number assigned by the storage system. A storage
>system can be broken up into multiple virtual storage systems each unique 
to
>the owner. The real trick is when to virtual storage systems share the 
same
>LUN.

This VLUN sounds like what SCSI/FCP defines as a LUN.  What you're calling 
a LUN is apparently something that's not defined in SCSI.  I'm guessing a 
LUN here identifies a volume, and the same volume is connected to multiple 
SCSI logical units, one in each virtual storage subsystem.  I'm also 
assuming that a virtual storage subsystem is a target device/node in SCSI 
terms.

That raises the question:  What do you get if you INQUIRE as to the 
logical unit serial number of two SCSI logical units, in different virtual 
storage subsystems, associated with the same volume?  Is it the same 
serial number?

^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-12 17:18 Bryan Henderson
  0 siblings, 0 replies; 297+ messages in thread
From: Bryan Henderson @ 2002-04-12 17:18 UTC (permalink / raw)
  To: berthiaume_wayne; +Cc: linux-scsi


That clarifies things a bit.  Clariion uses an unfortunate terminology; we
have to keep that in mind in these naming discussions because, for example,
when we talk a about making a device file name out of host/bus/target/lun,
we're talking about a Clariion VLUN, not a Clariion LUN.  The Clariion LUN
is what I believe most others would call a "volume."  Or maybe a virtual
disk.

>The physical LUN itself is not a physical disk in the physical
>array but created at the time you bind disks or portions of disks into
LUN.

Don't you feel funny saying "physical LUN" (physical logical unit number)?
:-) Is it physical or logical?  And is it a number or a storage medium?



^ permalink raw reply	[flat|nested] 297+ messages in thread
* RE: [RFC] Persistent naming of scsi devices
@ 2002-04-12 18:03 berthiaume_wayne
  0 siblings, 0 replies; 297+ messages in thread
From: berthiaume_wayne @ 2002-04-12 18:03 UTC (permalink / raw)
  To: hbryan; +Cc: linux-scsi

	I guess I hail back from when a LUN, or as I ahd always perceived
it, was a whole device and not a portion of one or several (if they were
bound in a RAID group.) =%^)

-----Original Message-----
From: Bryan Henderson [mailto:hbryan@us.ibm.com]
Sent: Friday, April 12, 2002 1:19 PM
To: berthiaume_wayne@emc.com
Cc: linux-scsi@vger.kernel.org
Subject: RE: [RFC] Persistent naming of scsi devices



That clarifies things a bit.  Clariion uses an unfortunate terminology; we
have to keep that in mind in these naming discussions because, for example,
when we talk a about making a device file name out of host/bus/target/lun,
we're talking about a Clariion VLUN, not a Clariion LUN.  The Clariion LUN
is what I believe most others would call a "volume."  Or maybe a virtual
disk.

>The physical LUN itself is not a physical disk in the physical
>array but created at the time you bind disks or portions of disks into
LUN.

Don't you feel funny saying "physical LUN" (physical logical unit number)?
:-) Is it physical or logical?  And is it a number or a storage medium?


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

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [RFC] Persistent naming of scsi devices
@ 2002-06-05 20:13 sullivan
  2002-06-06  1:08 ` Douglas Gilbert
  0 siblings, 1 reply; 297+ messages in thread
From: sullivan @ 2002-06-05 20:13 UTC (permalink / raw)
  To: linux-scsi; +Cc: mochel

Thanks for your postings to the original RFC submitted under this subject. Based on your feedback two utilities are now available at http://oss.software.ibm.com/devreg/
a. scsiname utility
	- Makes sg calls to collect device info used to make naming decisions
	- Hooked into the hotplug interface using Doug Gilbert's scsimon patch
	- Targeted specifically to scsi devices
	- Implemented completely in userspace

b. devnaming utility
	- Utilizes Patrick Mochel's driverfs fs to collect device info
	- Can easily be extended to support other device types (non scsi)
	- Includes a kernel patch to create/publish device info in driverfs
	- Hooked into hotplug interface using scsimon patch

Why two utilities? I see scsiname providing an immediate fix for providing a persistent set of /dev scsi names across boots. The devnaming utility is more long term in that it anticipates that driverfs will evolve into providing the device information necessary, removing the need for interfacing through sg. The config and hotplug portions of the utilities are consistent and should (hopefully) provide a smooth migration path.

I'd appreciate feedback from anyone that has the interest and the time to take a further look.




^ permalink raw reply	[flat|nested] 297+ messages in thread
* Proposed changes to generic blk tag for use in SCSI (1/3)
@ 2002-06-11  2:46 James Bottomley
  2002-06-11  5:50 ` Jens Axboe
  2002-06-13 21:01 ` Doug Ledford
  0 siblings, 2 replies; 297+ messages in thread
From: James Bottomley @ 2002-06-11  2:46 UTC (permalink / raw)
  To: axboe, linux-scsi; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 845 bytes --]

The attached is what I needed in the generic block layer to get the SCSI 
subsystem using it for Tag Command Queueing.

The changes are basically

1) I need a function to find the tagged request given the queue and the tag, 
which I've added as a function in the block layer

2) The SCSI queue will stall if it gets an untagged request in the stream, so 
once tagged queueing is enabled, all commands (including SPECIALS) must be 
tagged.  I altered the check in blk_queue_start_tag to permit this.

This is part of a set of three patches which provide a sample implementation 
of a SCSI driver using the generic TCQ code.

There are several shortcomings of the prototype, most notably it doesn't have 
tag starvation detection and processing.  However, I think I can re-introduce 
this as part of the error handler functions.

James Bottomley


[-- Attachment #2: blk-tag-2.5.21.diff --]
[-- Type: text/plain , Size: 2554 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.585   -> 1.586  
#	drivers/block/ll_rw_blk.c	1.67    -> 1.68   
#	include/linux/blkdev.h	1.44    -> 1.45   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/06/10	jejb@mulgrave.(none)	1.586
# [BLK LAYER]
# 
# add find tag function, adjust criteria for tagging commands.
# --------------------------------------------
#
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Mon Jun 10 22:29:38 2002
+++ b/drivers/block/ll_rw_blk.c	Mon Jun 10 22:29:38 2002
@@ -304,6 +304,27 @@
 }
 
 /**
+ * blk_queue_find_tag - find a request by its tag and queue
+ *
+ * @q:	 The request queue for the device
+ * @tag: The tag of the request
+ *
+ * Notes:
+ *    Should be used when a device returns a tag and you want to match
+ *    it with a request.
+ *
+ *    no locks need be held.
+ **/
+struct request *blk_queue_find_tag(request_queue_t *q, int tag)
+{
+	struct blk_queue_tag *bqt = q->queue_tags;
+
+	if(unlikely(bqt == NULL || bqt->max_depth < tag))
+		return NULL;
+
+	return bqt->tag_index[tag];
+}
+/**
  * blk_queue_free_tags - release tag maintenance info
  * @q:  the request queue for the device
  *
@@ -448,7 +469,7 @@
 	unsigned long *map = bqt->tag_map;
 	int tag = 0;
 
-	if (unlikely(!(rq->flags & REQ_CMD)))
+	if (unlikely((rq->flags & REQ_QUEUED)))
 		return 1;
 
 	for (map = bqt->tag_map; *map == -1UL; map++) {
@@ -1945,6 +1966,7 @@
 EXPORT_SYMBOL(ll_10byte_cmd_build);
 EXPORT_SYMBOL(blk_queue_prep_rq);
 
+EXPORT_SYMBOL(blk_queue_find_tag);
 EXPORT_SYMBOL(blk_queue_init_tags);
 EXPORT_SYMBOL(blk_queue_free_tags);
 EXPORT_SYMBOL(blk_queue_start_tag);
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Mon Jun 10 22:29:38 2002
+++ b/include/linux/blkdev.h	Mon Jun 10 22:29:38 2002
@@ -339,6 +339,7 @@
 #define blk_queue_tag_queue(q)		((q)->queue_tags->busy < (q)->queue_tags->max_depth)
 #define blk_rq_tagged(rq)		((rq)->flags & REQ_QUEUED)
 extern int blk_queue_start_tag(request_queue_t *, struct request *);
+extern struct request *blk_queue_find_tag(request_queue_t *, int);
 extern void blk_queue_end_tag(request_queue_t *, struct request *);
 extern int blk_queue_init_tags(request_queue_t *, int);
 extern void blk_queue_free_tags(request_queue_t *);

^ permalink raw reply	[flat|nested] 297+ messages in thread
[parent not found: <200206132126.g5DLQiQ24889@localhost.localdomain>]
* When must the io_request_lock be held?
@ 2002-08-05 23:53 Jamie Wellnitz
  2002-08-06 17:58 ` Mukul Kotwani
  2002-08-07 14:48 ` Doug Ledford
  0 siblings, 2 replies; 297+ messages in thread
From: Jamie Wellnitz @ 2002-08-05 23:53 UTC (permalink / raw)
  To: linux-scsi

When does a low-level driver have to hold the io_request_lock?  I know
that a driver should take the lock when it calls a SCSI command's done
function.  Also, when the driver's queuecommand is entered, it already
holds this lock.

I've seen some drivers that drop the lock (via either spin_unlock or
spin_unlock_irq) inside their queuecommand.  What are the rules for
dropping (and reacquiring) the lock here?

Thanks,
Jamie Wellnitz

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [PATCH] 2.5.31 scsi_error.c cleanup
@ 2002-08-12 23:38 Mike Anderson
  2002-08-22 14:05 ` James Bottomley
  0 siblings, 1 reply; 297+ messages in thread
From: Mike Anderson @ 2002-08-12 23:38 UTC (permalink / raw)
  To: linux-scsi

I have created a scsi_error cleanup patch.

I would appreciate any feedback and testing.

The patch simplifies scsi_unjam_host and associated functions.

I did not change any of the current error policy. I would like to do
that in the future.

I have tested the patch on the following configurations with successful
recovery:

UML:
	Driver: scsi_debug Version: 1.59
	Error Hdlr Policy:
		- Request sense if no auto sense.
		- Abort on timed out command

2.5.31:
	Driver: aic7xxx 6.2.4
	Error Hdlr Policy:
		- Abort on timed out command
		- Attempt BDR
		- Send Bus Reset.

I also ran against qlogicisp, ips, and qla drivers but error injection
did not generate any meaningful results.

Complete patch against 2.5.31 is at:

http://www-124.ibm.com/storageio/gen-io/patch-scsi_error-2.5.31-1.gz

-Mike

-- 
Michael Anderson
andmike@us.ibm.com


^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: [RFC]: 64 bit LUN/Tags, dummy device in host_queue, host_lock <-> LLDD reentrancy
@ 2002-08-26 16:29 Aron Zeh
  2002-08-26 16:48 ` James Bottomley
  0 siblings, 1 reply; 297+ messages in thread
From: Aron Zeh @ 2002-08-26 16:29 UTC (permalink / raw)
  To: James Bottomley; +Cc: Luben Tuikov, linux-scsi


> ARZEH@de.ibm.com said:
> > To me all of the proposed changes look good. The one above I'd be
> > interested in particularly. It would help sorting out a lot of woes we
> > had with writing a fibre-channel HBA driver. For fibre-channel LUNs
> > and port IDs (WWPN) are 64-bit and depending on configuration, high
> > values can be (and in our case are) common.
>
> Actually, I'd like to see us moving towards adopting the capabilities of
> driverfs for this.
>
> PUN is to all intents and purposes now an abstraction in the FC realm.
LUNs
> too, as long as they retain the grouping abstraction with PUNs.  The mid
layer
> really doesn't need to know what these are (there are a few pieces of
code
> that populate the LUN field for SCSI-1 devices that would need rework).
All
> the mid layer really needs is the Scsi_Device structure that describes an

> individual LUN (and some knowledge of LUN and PUN grouping for reset
action
> prediction).  It doesn't need to know or care about the current PUN and
LUN
> numbers.
>
> If FC drivers move straight to using driverfs, you can populate the
driverfs
> names with whatever is meaningful to you for PUN (WWN, portid etch) and
LUN
> and thus avoid this problem (and also the mapping code most have to take
these
> to and from the PUN/LUN numbers).  Since driverfs is a tree, the PUN/LUN
> division is done in a directory (and could, theoretically be done on more
than
> just a two level split).
>
> James

James, there are some things that I don't fully understand, yet.

Does the use of driverfs-names mean that the HBA driver somehow comes into
the discovery-loop for devices (e.g. scan_scsis somehow interacts with the
HBA driver to determine which driverfs entry to create.)?
Shouldn't there be some sort of rule for LUN (or unit) naming within at
least the same hardware class? That is for: parallel, iSCSI, FC, etc.
Will the SCSI stack automatically try to discover all devices behind the
HBA (e.g, on the FC SAN)? Or will there be an interface to restrict the
range, etc?
Lastly, how will you keep track of LUNs in the SCSI stack? Will the current
LUN field disappear in favour of a generic character string?

Cheers,
Aron






^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: aic7xxx sets CDR offline, how to reset?
@ 2002-09-03 14:35 James Bottomley
  2002-09-03 18:23 ` Doug Ledford
  0 siblings, 1 reply; 297+ messages in thread
From: James Bottomley @ 2002-09-03 14:35 UTC (permalink / raw)
  To: Justin T. Gibbs, Doug Ledford; +Cc: linux-kernel, linux-scsi

> Doug Ledford writes:
> 
>  > took the device off line.  So, in short, the mid layer isn't waiting
> long   > enough, or when it gets sense indicated not ready it needs to
> implement a   > waiting queue with a timeout to try rekicking things a
> few times and don't   > actually mark the device off line until a longer
> period of time has   > elasped without the device coming back.
> 
> There is a kernel config CONFIG_AIC7XXX_RESET_DELAY_MS (default 15s).
> Would increasing it help?

Justin Gibbs writes:
> This currently only effects the initial bus reset delay.  If the
> driver holds off commands after subsequent bus resets, it can cause
> undeserved timeouts on the commands it has intentionally deferred.
> The mid-layer has a 5 second delay after bus resets, but I haven't
> verified that this is honored correctly during error recovery.

I'm planning a major re-write of this area in the error handler.  The way I 
think it should go is:

1) Quiesce host (set in_recovery flag)
2) Suspend active timers on this host
3) Proceed down the error correction track (eliminate abort and go down 
device, bus and host resets and finally set the device offline).
5) On each error recovery wait out a recovery timer for the device to become 
active before talking to it again.  Send all affected commands back to the 
block layer to await reissue (note: it would now be illegal for commands to 
lie to the mid layer and say they've done the reset when they haven't).
6) issue a TUR using a command allocated to the eh for that purpose.  Process 
the return code (in particular, if the device says NOT READY, wait some more). 
 Only if the TUR definitively fails proceed up the recovery chain all the way 
to taking the device offline.

I also plan to expose the suspend and resume timers API in some form for FC 
drivers to use.

James

^ permalink raw reply	[flat|nested] 297+ messages in thread
[parent not found: <200209091458.g89Evv806056@localhost.localdomain>]
* SCSI woes (followup)
@ 2002-09-24 11:35 Russell King
  2002-09-24 13:46 ` James Bottomley
  0 siblings, 1 reply; 297+ messages in thread
From: Russell King @ 2002-09-24 11:35 UTC (permalink / raw)
  To: linux-scsi, James Bottomley

In my previous mail, I said I thought scsi_allocate_device() was the cause
of the lockup while trying to attach devices to drivers.  This doesn't
seem to be the case.

Instead, we have something interesting going on:

1. We submit a test unit ready command for the disk device.  This command
   is at the head, and we call scsi_request_fn()
2. the scsi_request_fn() realises that the device was reset, and performs
   a scsi_ioctl to lock the door.
3. the ioctl queues up another request on the tail of the request queue
   to lock the door, and calls scsi_request_fn()
4. scsi_request_fn() processes the test unit ready command at the head of
   the queue, and hands this off to the driver.  The driver is now busy.
5. scsi_request_fn() returns, and waits for our door lock request to
   complete.
6. the test unit ready command completes.  We pass completion notification
   through scsi_done, the bottom half handler, scsi_finish_command,
   the scsi command's done function (which is the scsi requests sr_done
   function.)  At no point to we kick the queue to go and execute that
   door lock request.

So, we are left with one invocation of scsi_request_fn() spinning in the
scsi ioctl code waiting for a command that can never ever complete.

I'm getting the impression that the door lock handling code is misplaced,
and is probably the cause of these problems.  I'm going to try disabling
that code, and reverting my previous change to scsi_restart_operations().

Help!

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html


^ permalink raw reply	[flat|nested] 297+ messages in thread
* [PATCH] first cut at fixing unable to requeue with no outstanding commands
@ 2002-09-30 21:06 James Bottomley
  2002-09-30 23:28 ` Mike Anderson
  0 siblings, 1 reply; 297+ messages in thread
From: James Bottomley @ 2002-09-30 21:06 UTC (permalink / raw)
  To: linux-scsi

[-- Attachment #1: Type: text/plain, Size: 1137 bytes --]

The attached represents an attempt to break the scsi mid-layer of the 
assumption that any device can queue at least one command.

What essentially happens if the host rejects a command with no other 
outstanding commands, it does a very crude countdown (basically counts the 
number of cycles through the scsi request function) until the device gets 
enabled again when the count reaches zero.  I think the iteration in the 
request function is better than a fixed timer because it makes the system more 
responsive to I/O pressure (and also, it's easier to code).

I've tested this by making a SCSI driver artificially reject commands with 
none outstanding (and run it on my root device).  A value of seven seems to 
cause a delay of between half and five seconds before the host starts up again 
(depending on the I/O load).

If this approach looks acceptable, I plan the following enhancements

1. Make device_busy count down in the same fashion
2. give ->queuecommand() a two value return (one for blocking the entire host 
and another for just blocking the device).
3. Make the countdown tuneable from the host template.

James



[-- Attachment #2: tmp.diff --]
[-- Type: text/plain , Size: 2512 bytes --]

===== hosts.c 1.9 vs edited =====
--- 1.9/drivers/scsi/hosts.c	Tue Jun 11 15:43:08 2002
+++ edited/hosts.c	Mon Sep 30 15:29:56 2002
@@ -210,7 +210,7 @@
     retval->eh_notify   = NULL;    /* Who we notify when we exit. */
 
 
-    retval->host_blocked = FALSE;
+    retval->host_blocked = 0;
     retval->host_self_blocked = FALSE;
 
 #ifdef DEBUG
===== hosts.h 1.12 vs edited =====
--- 1.12/drivers/scsi/hosts.h	Sun Jul 21 03:55:49 2002
+++ edited/hosts.h	Mon Sep 30 15:25:53 2002
@@ -395,11 +395,6 @@
     unsigned use_blk_tcq:1;
 
     /*
-     * Host has rejected a command because it was busy.
-     */
-    unsigned host_blocked:1;
-
-    /*
      * Host has requested that no further requests come through for the
      * time being.
      */
@@ -417,6 +412,19 @@
      */
     unsigned some_device_starved:1;
    
+    /*
+     * Host has rejected a command because it was busy.
+     */
+    unsigned int host_blocked;
+
+    /*
+     * Initial value for the blocking.  If the queue is empty, host_blocked
+     * counts down in the request_fn until it restarts host operations as
+     * zero is reached.  
+     *
+     * FIXME: This should probably be a value in the template */
+    #define SCSI_START_HOST_BLOCKED	7
+
     void (*select_queue_depths)(struct Scsi_Host *, Scsi_Device *);
 
     /*
===== scsi.c 1.36 vs edited =====
--- 1.36/drivers/scsi/scsi.c	Fri Sep 20 00:40:42 2002
+++ edited/scsi.c	Mon Sep 30 15:26:41 2002
@@ -643,7 +643,7 @@
 				return 0;
 			}
 		}
-		host->host_blocked = TRUE;
+		host->host_blocked = SCSI_START_HOST_BLOCKED;
 	} else {
 		if (cmd->device->device_busy == 0) {
 			if (scsi_retry_command(cmd) == 0) {
@@ -1443,7 +1443,7 @@
          * for both the queue full condition on a device, and for a
          * host full condition on the host.
          */
-        host->host_blocked = FALSE;
+        host->host_blocked = 0;
         device->device_blocked = FALSE;
 
 	/*
===== scsi_lib.c 1.30 vs edited =====
--- 1.30/drivers/scsi/scsi_lib.c	Wed Sep 18 11:36:10 2002
+++ edited/scsi_lib.c	Mon Sep 30 15:33:00 2002
@@ -754,6 +754,16 @@
 		if (SHpnt->in_recovery || blk_queue_plugged(q))
 			return;
 
+		if(SHpnt->host_busy == 0 && SHpnt->host_blocked) {
+			/* unblock after host_blocked iterates to zero */
+			if(--SHpnt->host_blocked == 0) {
+				printk("scsi%d unblocking host at zero depth\n", SHpnt->host_no);
+			} else {
+				blk_plug_device(q);
+				break;
+			}
+		}
+				
 		/*
 		 * If the device cannot accept another request, then quit.
 		 */

^ permalink raw reply	[flat|nested] 297+ messages in thread
* Re: [PATCH] scsi host cleanup 3/3 (driver changes)
@ 2002-10-10 15:01 Stephen Cameron
  2002-10-10 16:46 ` Mike Anderson
  0 siblings, 1 reply; 297+ messages in thread
From: Stephen Cameron @ 2002-10-10 15:01 UTC (permalink / raw)
  To: andmike; +Cc: linux-scsi

Mike Anderson wrote:

> If you read my previous post on this patch I indicated that few of the
> driver changes I was only able to compile test ( block/cciss_scsi.c,
> scsi/53c700.c, scsi/pcmcia/*, scsi/wd33c93.c). The changes to the
> drivers are to remove the old interfaces and possibly extra NULL inits
> of struct members. These changes will need to be ok'd by there
> respective maintainers.

I tried out these patches with 2.5.40 and the cciss driver.
Looks ok to me.

When I did "echo engage scsi > /proc/driver/cciss/cciss0" to 
make the cciss driver register with the scsi subsystem, I got
what you see below.  However, I also got the same thing when 
trying 2.5.40 without the patches, so I don't think the patches
are the problem.

When I tried 2.5.41 without the patches, the problem below was
gone.

And, despite all this, it always appeared to work anyway. 
My tape drive appeared, and I could always do i/o to it.

-- steve

dmesg output follows:

cciss0: No device changes detected.
scsi0 : cciss0
  Vendor: COMPAQ    Model: SDT-10000         Rev: 1.14
  Type:   Sequential-Access                  ANSI SCSI revision: 02
Debug: sleeping function called from illegal context at slab.c:1374
ce275de0 c01195e6 c0320bc0 c0326282 0000055e c1287080 c013c15f c0326282 
       0000055e c1336324 c1330c00 00000000 ce275e4c 00000286 00000286 cfc32974 
       cf37e000 00000000 cfffb080 d0800000 00001000 ce274000 00001000 c013a199 
Call Trace:
 [<c01195e6>]__might_sleep+0x56/0x5d
 [<c013c15f>]kmalloc+0x4f/0x330
 [<c013a199>]get_vm_area+0x29/0x140
 [<c013a4fb>]__vmalloc+0x3b/0x120
 [<c013a5f6>]vmalloc+0x16/0x20
 [<c029837e>]sg_init+0xbe/0x160
 [<c0288280>]scsi_register_host+0x130/0x200
 [<c025a5b6>]cciss_engage_scsi+0x136/0x150
 [<c025a8da>]cciss_proc_write+0x8a/0xb0
 [<c015ca9f>]open_namei+0x37f/0x4e0
 [<c013bcf2>]free_block+0x192/0x2c0
 [<c017bf21>]proc_file_write+0x31/0x40
 [<c014d316>]vfs_write+0xb6/0x180
 [<c014c94f>]filp_close+0x10f/0x120
 [<c014c94f>]filp_close+0x10f/0x120
 [<c014d44a>]sys_write+0x2a/0x40
 [<c01078af>]syscall_call+0x7/0xb

bad: scheduling while atomic!
ce275ce8 c0116b9d c0320a20 c03c0590 ce275d0c c01170a1 c12b5800 00000000 
       ce274000 ce275dd4 ce275dd8 ce275d68 c011749a 00000000 cfcb1080 c0117080 
       00000000 00000000 c0117196 c03c0588 00000003 00000001 cfcb1080 c0117080 
Call Trace:
 [<c0116b9d>]schedule+0x3d/0x4c0
 [<c01170a1>]default_wake_function+0x21/0x40
 [<c011749a>]wait_for_completion+0x12a/0x1e0
 [<c0117080>]default_wake_function+0x0/0x40
 [<c0117196>]__wake_up+0x66/0xb0
 [<c0117080>]default_wake_function+0x0/0x40
 [<c012d5a1>]call_usermodehelper+0x101/0x110
 [<c012d470>]__call_usermodehelper+0x0/0x30
 [<c013bcf2>]free_block+0x192/0x2c0
 [<c012d470>]__call_usermodehelper+0x0/0x30
 [<c021ed84>]dev_hotplug+0x1a4/0x230
 [<c021edd7>]dev_hotplug+0x1f7/0x230
 [<c021babd>]device_attach+0x2d/0x40
 [<c021be84>]device_register+0x194/0x270
 [<c029874f>]sg_attach+0x2cf/0x380
 [<c02882ca>]scsi_register_host+0x17a/0x200
 [<c025a5b6>]cciss_engage_scsi+0x136/0x150
 [<c025a8da>]cciss_proc_write+0x8a/0xb0
 [<c015ca9f>]open_namei+0x37f/0x4e0
 [<c013bcf2>]free_block+0x192/0x2c0
 [<c017bf21>]proc_file_write+0x31/0x40
 [<c014d316>]vfs_write+0xb6/0x180
 [<c014c94f>]filp_close+0x10f/0x120
 [<c014c94f>]filp_close+0x10f/0x120
 [<c014d44a>]sys_write+0x2a/0x40
 [<c01078af>]syscall_call+0x7/0xb

Attached scsi tape st0 at scsi0, channel 0, id 0, lun 0
st0: try direct i/o: yes, max page reachable by HBA 65532

^ permalink raw reply	[flat|nested] 297+ messages in thread
[parent not found: <patmans@us.ibm.com>]
* [patch 2.5] ips queue depths
@ 2002-10-15 18:55 Jeffery, David
  2002-10-15 19:30 ` Dave Hansen
  2002-10-15 19:47 ` Doug Ledford
  0 siblings, 2 replies; 297+ messages in thread
From: Jeffery, David @ 2002-10-15 18:55 UTC (permalink / raw)
  To: 'Dave Hansen'; +Cc: 'linux-scsi@vger.kernel.org'

[-- Attachment #1: Type: text/plain, Size: 379 bytes --]

Dave,

Here's a patch that should restore the queue depths to what they were before
the
queue depths change was merged in.  Hopefully this well restore your lost
performance.  If I don't hear or find anything bad about it, it will be
going
to Linus shortly.

And thanks goes to Mike Anderson for his initial version.  That made writing
this patch all the easier.

David Jeffery


[-- Attachment #2: ips2.5.42.patch --]
[-- Type: application/octet-stream, Size: 673 bytes --]

--- linux-2.5.42/drivers/scsi/ips.c	Tue Oct 15 14:34:16 2002
+++ linux-2.5.42_new/drivers/scsi/ips.c	Tue Oct 15 14:24:13 2002
@@ -1877,12 +1877,16 @@
 {
    ips_ha_t    *ha;
    int          min;
+   int          depth;
 
    ha = IPS_HA(SDptr->host);
    min = ha->max_cmds / 4;
-   if (min < 8)
-      min = ha->max_cmds - 1;
-   scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
+   if((SDptr->type == TYPE_DISK) && ha->enq->ucLogDriveCount){
+      depth = (ha->max_cmds - 1) / ha->enq->ucLogDriveCount;
+      depth = max(min, depth);
+   } else
+      depth = 2;
+   scsi_adjust_queue_depth(SDptr, MSG_SIMPLE_TAG, depth);
    return 0;
 }
 

^ permalink raw reply	[flat|nested] 297+ messages in thread
[parent not found: <dledford@redhat.com>]
* [PATCH] get rid of ->finish method for highlevel drivers
@ 2002-10-21 19:34 Christoph Hellwig
  2002-10-21 23:58 ` James Bottomley
  2002-10-22  7:30 ` Mike Anderson
  0 siblings, 2 replies; 297+ messages in thread
From: Christoph Hellwig @ 2002-10-21 19:34 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi

the ->finish method is a relicat from the old day were we never had
hotplugging and allowed the driver to do fixups after all busses
had been scanned.  Nowdays only sd and sr actually implement it,
and both only defer actions to there that should actually happen in
->attach.  Change both drivers to move that code into ->attach,
clenaup the Templates to use C99 initializers and get rid of the
methods.

This also cleans up some very crude race-avoidable code in those
drivers, btw..


diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- linux-2.5.44-uc0/drivers/scsi/hosts.c	Mon Oct 21 17:18:03 2002
+++ linux/drivers/scsi/hosts.c	Mon Oct 21 20:46:14 2002
@@ -573,14 +573,6 @@ int scsi_register_host(Scsi_Host_Templat
 					}
 				}
 		}
-
-		/* This does any final handling that is required. */
-		for (sdev_tp = scsi_devicelist; sdev_tp;
-		     sdev_tp = sdev_tp->next) {
-			if (sdev_tp->finish && sdev_tp->nr_dev) {
-				(*sdev_tp->finish) ();
-			}
-		}
 	}
 
 	return 0;
diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
--- linux-2.5.44-uc0/drivers/scsi/hosts.h	Mon Oct 21 17:18:19 2002
+++ linux/drivers/scsi/hosts.h	Mon Oct 21 20:43:56 2002
@@ -583,7 +583,6 @@ struct Scsi_Device_Template
     int (*detect)(Scsi_Device *); /* Returns 1 if we can attach this device */
     int (*init)(void);		  /* Sizes arrays based upon number of devices
 		   *  detected */
-    void (*finish)(void);	  /* Perform initialization after attachment */
     int (*attach)(Scsi_Device *); /* Attach devices to arrays */
     void (*detach)(Scsi_Device *);
     int (*init_command)(Scsi_Cmnd *);     /* Used by new queueing code. 
diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux-2.5.44-uc0/drivers/scsi/scsi.c	Mon Oct 21 17:19:01 2002
+++ linux/drivers/scsi/scsi.c	Mon Oct 21 20:44:58 2002
@@ -2034,18 +2039,14 @@ int scsi_register_device(struct Scsi_Dev
 		}
 	}
 
-	/*
-	 * This does any final handling that is required.
-	 */
-	if (tpnt->finish && tpnt->nr_dev)
-		(*tpnt->finish) ();
 	MOD_INC_USE_COUNT;
 
 	if (out_of_space) {
 		scsi_unregister_device(tpnt);	/* easiest way to clean up?? */
 		return 1;
-	} else
-		return 0;
+	}
+
+	return 0;
 }
 
 int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- linux-2.5.44-uc0/drivers/scsi/scsi_scan.c	Mon Oct 21 17:20:04 2002
+++ linux/drivers/scsi/scsi_scan.c	Mon Oct 21 20:47:21 2002
@@ -2012,11 +2012,6 @@ static void scsi_scan_selected_lun(struc
 						       __FUNCTION__);
 				}
 			}
-
-		for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
-			if (sdt->finish && sdt->nr_dev)
-				(*sdt->finish) ();
-
 	}
 }
 
diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux-2.5.44-uc0/drivers/scsi/sd.c	Mon Oct 21 17:20:02 2002
+++ linux/drivers/scsi/sd.c	Mon Oct 21 20:52:13 2002
@@ -92,7 +92,6 @@ static int sd_revalidate(struct gendisk 
 static void sd_init_onedisk(Scsi_Disk * sdkp, struct gendisk *disk);
 
 static int sd_init(void);
-static void sd_finish(void);
 static int sd_attach(Scsi_Device *);
 static int sd_detect(Scsi_Device *);
 static void sd_detach(Scsi_Device *);
@@ -103,23 +102,19 @@ static int sd_notifier(struct notifier_b
 static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0}; 
 
 static struct Scsi_Device_Template sd_template = {
-	module:THIS_MODULE,
-	name:"disk",
-	tag:"sd",
-	scsi_type:TYPE_DISK,
-	major:SCSI_DISK0_MAJOR,
-        /*
-         * Secondary range of majors that this driver handles.
-         */
-	min_major:SCSI_DISK1_MAJOR,
-	max_major:SCSI_DISK7_MAJOR,
-	blk:1,
-	detect:sd_detect,
-	init:sd_init,
-	finish:sd_finish,
-	attach:sd_attach,
-	detach:sd_detach,
-	init_command:sd_init_command,
+	.module		= THIS_MODULE,
+	.name		= "disk",
+	.tag		= "sd",
+	.scsi_type	= TYPE_DISK,
+	.major		= SCSI_DISK0_MAJOR,
+	.min_major	= SCSI_DISK1_MAJOR,
+	.max_major	= SCSI_DISK7_MAJOR,
+	.blk		= 1,
+	.detect		= sd_detect,
+	.init		= sd_init,
+	.attach		= sd_attach,
+	.detach		= sd_detach,
+	.init_command	= sd_init_command,
 };
 
 static void sd_rw_intr(Scsi_Cmnd * SCpnt);
@@ -1291,38 +1286,6 @@ cleanup_mem:
 }
 
 /**
- *	sd_finish - called during driver initialization, after all
- *	the sd_attach() calls are finished.
- *
- *	Note: this function is invoked from the scsi mid-level.
- *	This function is not called after driver initialization has completed.
- *	Specifically later device attachments invoke sd_attach() but not
- *	this function.
- **/
-static void sd_finish()
-{
-	int k;
-	Scsi_Disk * sdkp;
-
-	SCSI_LOG_HLQUEUE(3, printk("sd_finish: \n"));
-
-	for (k = 0; k < sd_template.dev_max; ++k) {
-		sdkp = sd_get_sdisk(k);
-		if (sdkp && (0 == sdkp->capacity) && sdkp->device) {
-			sd_init_onedisk(sdkp, sd_disks[k]);
-			if (sdkp->has_been_registered)
-				continue;
-			set_capacity(sd_disks[k], sdkp->capacity);
-			sd_disks[k]->private_data = sdkp;
-			sd_disks[k]->queue = &sdkp->device->request_queue;
-			add_disk(sd_disks[k]);
-			sdkp->has_been_registered = 1;
-		}
-	}
-	return;
-}
-
-/**
  *	sd_detect - called at the start of driver initialization, once 
  *	for each scsi device (not just disks) present.
  *
@@ -1358,13 +1321,12 @@ static int sd_detect(Scsi_Device * sdp)
  **/
 static int sd_attach(Scsi_Device * sdp)
 {
-	Scsi_Disk *sdkp;
+	Scsi_Disk *sdkp = NULL;	/* shut up lame gcc warning */
 	int dsk_nr;
 	unsigned long iflags;
 	struct gendisk *gd;
 
-	if ((NULL == sdp) ||
-	    ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD)))
+	if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
 		return 0;
 
 	gd = alloc_disk(16);
@@ -1373,15 +1335,16 @@ static int sd_attach(Scsi_Device * sdp)
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", 
 			 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
+
 	if (sd_template.nr_dev >= sd_template.dev_max) {
-		sdp->attached--;
 		printk(KERN_ERR "sd_init: no more room for device\n");
-		put_disk(gd);
-		return 1;
+		goto out;
 	}
 
-/* Assume sd_attach is not re-entrant (for time being) */
-/* Also think about sd_attach() and sd_detach() running coincidentally. */
+	/*
+	 * Assume sd_attach is not re-entrant (for time being)
+	 * Also think about sd_attach() and sd_detach() running coincidentally.
+	 */
 	write_lock_irqsave(&sd_dsk_arr_lock, iflags);
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) {
 		sdkp = sd_dsk_arr[dsk_nr];
@@ -1393,15 +1356,15 @@ static int sd_attach(Scsi_Device * sdp)
 	}
 	write_unlock_irqrestore(&sd_dsk_arr_lock, iflags);
 
-	if (dsk_nr >= sd_template.dev_max) {
-		/* panic("scsi_devices corrupt (sd)");  overkill */
+	if (!sdkp || dsk_nr >= sd_template.dev_max) {
 		printk(KERN_ERR "sd_init: sd_dsk_arr corrupted\n");
-		put_disk(gd);
-		return 1;
+		goto out;
 	}
 
+	sd_init_onedisk(sdkp, gd);
 	sd_template.nr_dev++;
-        gd->de = sdp->de;
+
+	gd->de = sdp->de;
 	gd->major = SD_MAJOR(dsk_nr>>4);
 	gd->first_minor = (dsk_nr & 15)<<4;
 	gd->fops = &sd_fops;
@@ -1409,14 +1372,26 @@ static int sd_attach(Scsi_Device * sdp)
 		sprintf(gd->disk_name, "sd%c%c",'a'+dsk_nr/26-1,'a'+dsk_nr%26);
 	else
 		sprintf(gd->disk_name, "sd%c",'a'+dsk_nr%26);
-        gd->flags = sdp->removable ? GENHD_FL_REMOVABLE : 0;
-        gd->driverfs_dev = &sdp->sdev_driverfs_dev;
-        gd->flags |= GENHD_FL_DRIVERFS | GENHD_FL_DEVFS;
+	gd->flags = sdp->removable ? GENHD_FL_REMOVABLE : 0;
+	gd->driverfs_dev = &sdp->sdev_driverfs_dev;
+	gd->flags |= GENHD_FL_DRIVERFS | GENHD_FL_DEVFS;
+	gd->private_data = sdkp;
+	gd->queue = &sdkp->device->request_queue;
+
+	set_capacity(gd, sdkp->capacity);
+	add_disk(gd);
+
 	sd_disks[dsk_nr] = gd;
+
 	printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
 	       "id %d, lun %d\n", sdp->removable ? "removable " : "",
 	       gd->disk_name, sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
 	return 0;
+
+out:
+	sdp->attached--;
+	put_disk(gd);
+	return 1;
 }
 
 static int sd_revalidate(struct gendisk *disk)
@@ -1472,10 +1447,7 @@ static void sd_detach(Scsi_Device * sdp)
 	sdkp->capacity = 0;
 	/* sdkp->detaching = 1; */
 
-	if (sdkp->has_been_registered) {
-		sdkp->has_been_registered = 0;
-		del_gendisk(sd_disks[dsk_nr]);
-	}
+	del_gendisk(sd_disks[dsk_nr]);
 	sdp->attached--;
 	sd_template.dev_noticed--;
 	sd_template.nr_dev--;
diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/sd.h linux/drivers/scsi/sd.h
--- linux-2.5.44-uc0/drivers/scsi/sd.h	Mon Oct 21 17:19:51 2002
+++ linux/drivers/scsi/sd.h	Mon Oct 21 20:34:15 2002
@@ -25,7 +25,6 @@ typedef struct scsi_disk {
 	Scsi_Device *device;
 	unsigned char media_present;
 	unsigned char write_prot;
-	unsigned has_been_registered:1;
 	unsigned WCE:1;         /* state of disk WCE bit */
 	unsigned RCD:1;         /* state of disk RCD bit */
 } Scsi_Disk;
diff -uNr -Xdontdiff -p linux-2.5.44-uc0/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux-2.5.44-uc0/drivers/scsi/sr.c	Mon Oct 21 17:18:14 2002
+++ linux/drivers/scsi/sr.c	Mon Oct 21 20:57:29 2002
@@ -63,27 +63,24 @@ MODULE_PARM(xa_test, "i");	/* see sr_ioc
 #define SR_TIMEOUT	(30 * HZ)
 
 static int sr_init(void);
-static void sr_finish(void);
 static int sr_attach(Scsi_Device *);
 static int sr_detect(Scsi_Device *);
 static void sr_detach(Scsi_Device *);
 
 static int sr_init_command(Scsi_Cmnd *);
 
-static struct Scsi_Device_Template sr_template =
-{
-	module:THIS_MODULE,
-	name:"cdrom",
-	tag:"sr",
-	scsi_type:TYPE_ROM,
-	major:SCSI_CDROM_MAJOR,
-	blk:1,
-	detect:sr_detect,
-	init:sr_init,
-	finish:sr_finish,
-	attach:sr_attach,
-	detach:sr_detach,
-	init_command:sr_init_command
+static struct Scsi_Device_Template sr_template = {
+	.module		= THIS_MODULE,
+	.name		= "cdrom",
+	.tag		= "sr",
+	.scsi_type	= TYPE_ROM,
+	.major		= SCSI_CDROM_MAJOR,
+	.blk		= 1,
+	.detect		= sr_detect,
+	.init		= sr_init,
+	.attach		= sr_attach,
+	.detach		= sr_detach,
+	.init_command	= sr_init_command
 };
 
 static Scsi_CD *scsi_CDs;
@@ -91,6 +88,7 @@ static Scsi_CD *scsi_CDs;
 static int sr_open(struct cdrom_device_info *, int);
 static void get_sectorsize(Scsi_CD *);
 static void get_capabilities(Scsi_CD *);
+static int sr_init_one(Scsi_CD *, int);
 
 static int sr_media_change(struct cdrom_device_info *, int);
 static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
@@ -473,10 +471,9 @@ static int sr_attach(Scsi_Device * SDp)
 	if (SDp->type != TYPE_ROM && SDp->type != TYPE_WORM)
 		return 1;
 
-	if (sr_template.nr_dev >= sr_template.dev_max) {
-		SDp->attached--;
-		return 1;
-	}
+	if (sr_template.nr_dev >= sr_template.dev_max)
+		goto fail;
+
 	for (cpnt = scsi_CDs, i = 0; i < sr_template.dev_max; i++, cpnt++)
 		if (!cpnt->device)
 			break;
@@ -484,6 +481,8 @@ static int sr_attach(Scsi_Device * SDp)
 	if (i >= sr_template.dev_max)
 		panic("scsi_devices corrupt (sr)");
 
+	if (sr_init_one(cpnt, i))
+		goto fail;
 
 	scsi_CDs[i].device = SDp;
 
@@ -494,6 +493,10 @@ static int sr_attach(Scsi_Device * SDp)
 	printk("Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n",
 	       scsi_CDs[i].cdi.name, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
 	return 0;
+
+fail:
+	SDp->attached--;
+	return 1;
 }
 
 
@@ -744,64 +747,56 @@ cleanup_dev:
 	return 1;
 }
 
-void sr_finish()
+static int sr_init_one(Scsi_CD *cd, int first_minor)
 {
-	int i;
+	struct gendisk *disk;
 
-	for (i = 0; i < sr_template.nr_dev; ++i) {
-		struct gendisk *disk;
-		Scsi_CD *cd = &scsi_CDs[i];
-		/* If we have already seen this, then skip it.  Comes up
-		 * with loadable modules. */
-		if (cd->disk)
-			continue;
-		disk = alloc_disk(1);
-		if (!disk)
-			continue;
-		if (cd->disk) {
-			put_disk(disk);
-			continue;
-		}
-		disk->major = MAJOR_NR;
-		disk->first_minor = i;
-		strcpy(disk->disk_name, cd->cdi.name);
-		disk->fops = &sr_bdops;
-		disk->flags = GENHD_FL_CD;
-		cd->disk = disk;
-		cd->capacity = 0x1fffff;
-		cd->device->sector_size = 2048;/* A guess, just in case */
-		cd->needs_sector_size = 1;
-		cd->device->changed = 1;	/* force recheck CD type */
+	disk = alloc_disk(1);
+	if (!disk)
+		return -ENOMEM;
+
+	disk->major = MAJOR_NR;
+	disk->first_minor = first_minor;
+	strcpy(disk->disk_name, cd->cdi.name);
+	disk->fops = &sr_bdops;
+	disk->flags = GENHD_FL_CD;
+	cd->disk = disk;
+	cd->capacity = 0x1fffff;
+	cd->device->sector_size = 2048;/* A guess, just in case */
+	cd->needs_sector_size = 1;
+	cd->device->changed = 1;	/* force recheck CD type */
 #if 0
-		/* seems better to leave this for later */
-		get_sectorsize(cd);
-		printk("Scd sectorsize = %d bytes.\n", cd->sector_size);
+	/* seems better to leave this for later */
+	get_sectorsize(cd);
+	printk("Scd sectorsize = %d bytes.\n", cd->sector_size);
 #endif
-		cd->use = 1;
+	cd->use = 1;
 
-		cd->device->ten = 1;
-		cd->device->remap = 1;
-		cd->readcd_known = 0;
-		cd->readcd_cdda = 0;
-
-		cd->cdi.ops = &sr_dops;
-		cd->cdi.handle = cd;
-		cd->cdi.mask = 0;
-		cd->cdi.capacity = 1;
-		/*
-		 *	FIXME: someone needs to handle a get_capabilities
-		 *	failure properly ??
-		 */
-		get_capabilities(cd);
-		sr_vendor_init(cd);
-		disk->de = cd->device->de;
-		disk->driverfs_dev = &cd->device->sdev_driverfs_dev;
-		register_cdrom(&cd->cdi);
-		set_capacity(disk, cd->capacity);
-		disk->private_data = cd;
-		disk->queue = &cd->device->request_queue;
-		add_disk(disk);
-	}
+	cd->device->ten = 1;
+	cd->device->remap = 1;
+	cd->readcd_known = 0;
+	cd->readcd_cdda = 0;
+
+	cd->cdi.ops = &sr_dops;
+	cd->cdi.handle = cd;
+	cd->cdi.mask = 0;
+	cd->cdi.capacity = 1;
+
+	/*
+	 *	FIXME: someone needs to handle a get_capabilities
+	 *	failure properly ??
+	 */
+	get_capabilities(cd);
+	sr_vendor_init(cd);
+	disk->de = cd->device->de;
+	disk->driverfs_dev = &cd->device->sdev_driverfs_dev;
+	register_cdrom(&cd->cdi);
+	set_capacity(disk, cd->capacity);
+	disk->private_data = cd;
+	disk->queue = &cd->device->request_queue;
+	add_disk(disk);
+
+	return 0;
 }
 
 static void sr_detach(Scsi_Device * SDp)

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [PATCH] fix 2.5 scsi queue depth setting
@ 2002-11-06  4:24 Patrick Mansfield
  2002-11-06  4:35 ` Patrick Mansfield
                   ` (3 more replies)
  0 siblings, 4 replies; 297+ messages in thread
From: Patrick Mansfield @ 2002-11-06  4:24 UTC (permalink / raw)
  To: James Bottomley, Christoph Hellwig, linux-scsi

This patch fixes queue depth setting of scsi devices.

This is done by pairing shost->slave_attach() calls with
a scsi_build_commandblocks in the new scsi_slave_attach.

This is a patch aginst linux-scsi.bkbits.net/scsi-for-linus-2.5 after 
applying the last posted hch version of the "Eliminate scsi_host_tmpl_list"
patch, it still applies with offset to the current scsi-for-linus-2.5.

It also:

Will properly call shost->slave_attach after a scsi_unregister_device()
followed by a scsi_register_device() - as could happen if you were able to
rmmod all upper level drivers and then insmod any of them back (only
possible when not booted on scsi).

Checks for scsi_build_commandblocks() allocation failures.

Sets queue depth even if shost->slave_attach() does not call
scsi_adjust_queue_depth.

Removes the use of revoke (no drivers are setting it, it was only
call via the proc scsi remove-single-device interface).

There are at least two problems with sysfs and scsi (one in sysfs, one in
scsi, I'll try and post more soon ...) so I could not completey test rmmod
of an adapter or upper level driver without leading to an oops or shutdown
hang.

 hosts.c              |    5 --
 hosts.h              |    6 --
 osst.c               |    9 ++-
 scsi.c               |  118 +++++++++++++++++++++++++++++++--------------------
 scsi.h               |    2 
 scsi_mid_low_api.txt |   24 ----------
 scsi_scan.c          |    9 ---
 sd.c                 |   10 +++-
 sg.c                 |   10 ++--
 sr.c                 |    7 ++-
 st.c                 |   11 +++-
 11 files changed, 106 insertions(+), 105 deletions(-)

===== drivers/scsi/hosts.c 1.23 vs edited =====
--- 1.23/drivers/scsi/hosts.c	Tue Nov  5 17:13:42 2002
+++ edited/drivers/scsi/hosts.c	Tue Nov  5 17:18:22 2002
@@ -249,10 +249,6 @@
 			       sdev->attached);
 			return 1;
 		}
-
-		if (shost->hostt->slave_detach)
-			(*shost->hostt->slave_detach) (sdev);
-
 		devfs_unregister(sdev->de);
 		device_unregister(&sdev->sdev_driverfs_dev);
 	}
@@ -261,7 +257,6 @@
 
 	for (sdev = shost->host_queue; sdev;
 	     sdev = shost->host_queue) {
-		scsi_release_commandblocks(sdev);
 		blk_cleanup_queue(&sdev->request_queue);
 		/* Next free up the Scsi_Device structures for this host */
 		shost->host_queue = sdev->next;
===== drivers/scsi/hosts.h 1.32 vs edited =====
--- 1.32/drivers/scsi/hosts.h	Tue Nov  5 17:13:42 2002
+++ edited/drivers/scsi/hosts.h	Tue Nov  5 19:40:42 2002
@@ -93,12 +93,6 @@
      */
     int (* detect)(struct SHT *);
 
-    /*
-     * This function is only used by one driver and will be going away
-     * once it switches over to using the slave_detach() function instead.
-     */
-    int (*revoke)(Scsi_Device *);
-
     /* Used with loadable modules to unload the host structures.  Note:
      * there is a default action built into the modules code which may
      * be sufficient for most host adapters.  Thus you may not have to supply
===== drivers/scsi/osst.c 1.24 vs edited =====
--- 1.24/drivers/scsi/osst.c	Mon Nov  4 20:00:30 2002
+++ edited/drivers/scsi/osst.c	Tue Nov  5 17:26:53 2002
@@ -5421,10 +5421,12 @@
 		return 1;
 
 	if (osst_nr_dev >= osst_dev_max) {
-		 SDp->attached--;
 		 put_disk(disk);
 		 return 1;
 	}
+
+	if (scsi_slave_attach(SDp))
+		return 1;
 	
 	/* find a free minor number */
 	for (i=0; os_scsi_tapes[i] && i<osst_dev_max; i++);
@@ -5433,9 +5435,10 @@
 	/* allocate a OS_Scsi_Tape for this device */
 	tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
 	if (tpnt == NULL) {
-		 SDp->attached--;
 		 printk(KERN_WARNING "osst :W: Can't allocate device descriptor.\n");
 		 put_disk(disk);
+
+		 scsi_slave_detach(SDp);
 		 return 1;
 	}
 	memset(tpnt, 0, sizeof(OS_Scsi_Tape));
@@ -5648,7 +5651,7 @@
 		put_disk(tpnt->disk);
 		kfree(tpnt);
 		os_scsi_tapes[i] = NULL;
-		SDp->attached--;
+		scsi_slave_detach(SDp);
 		osst_nr_dev--;
 		osst_dev_noticed--;
 		return;
===== drivers/scsi/scsi.c 1.55 vs edited =====
--- 1.55/drivers/scsi/scsi.c	Tue Nov  5 17:13:42 2002
+++ edited/drivers/scsi/scsi.c	Tue Nov  5 20:05:10 2002
@@ -1664,10 +1664,6 @@
 			break;
 	}
 	spin_unlock_irqrestore(&device_request_lock, flags);
-	if(SDpnt->current_queue_depth == 0)
-	{
-		scsi_build_commandblocks(SDpnt);
-	}
 }
 
 #ifdef CONFIG_PROC_FS
@@ -1932,16 +1928,7 @@
 		scsi_detach_device(scd);
 
 		if (scd->attached == 0) {
-			/*
-			 * Nobody is using this device any more.
-			 * Free all of the command structures.
-			 */
-                        if (HBA_ptr->hostt->revoke)
-                                HBA_ptr->hostt->revoke(scd);
-			if (HBA_ptr->hostt->slave_detach)
-				(*HBA_ptr->hostt->slave_detach) (scd);
 			devfs_unregister (scd->de);
-			scsi_release_commandblocks(scd);
 
 			/* Now we can remove the device structure */
 			if (scd->next != NULL)
@@ -1976,7 +1963,7 @@
 	down_read(&scsi_devicelist_mutex);
 	for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
 		if (sdt->detect)
-			sdev->attached += (*sdt->detect)(sdev);
+			(*sdt->detect)(sdev);
 	up_read(&scsi_devicelist_mutex);
 }
 
@@ -1984,18 +1971,16 @@
 {
 	struct Scsi_Device_Template *sdt;
 
-	scsi_build_commandblocks(sdev);
-	if (sdev->current_queue_depth == 0)
-		goto fail;
-
 	down_read(&scsi_devicelist_mutex);
 	for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
 		if (sdt->attach)
+			/*
+			 * XXX check result when the upper level attach
+			 * return values are fixed, and on failure goto
+			 * fail.
+			 */
 			(*sdt->attach) (sdev);
 	up_read(&scsi_devicelist_mutex);
-
-	if (!sdev->attached)
-		scsi_release_commandblocks(sdev);
 	return 0;
 
 fail:
@@ -2017,6 +2002,66 @@
 }
 
 /*
+ * Function:	scsi_slave_attach()
+ *
+ * Purpose:	Called from the upper level driver attach to handle common
+ * 		attach code.
+ *
+ * Arguments:	sdev - scsi_device to attach
+ *
+ * Returns:	1 on error, 0 on succes
+ *
+ * Lock Status:	Protected via scsi_devicelist_mutex.
+ */
+int scsi_slave_attach(struct scsi_device *sdev)
+{
+	if (sdev->attached++ == 0) {
+		/*
+		 * No one was attached.
+		 */
+		if ((sdev->host->hostt->slave_attach != NULL) &&
+		    (sdev->host->hostt->slave_attach(sdev) != 0)) {
+			printk(KERN_INFO "scsi: failed low level driver"
+			       " attach, some SCSI device might not be"
+			       " configured\n");
+			return 1;
+		}
+		if ((sdev->new_queue_depth == 0) &&
+		    (sdev->host->cmd_per_lun != 0))
+			scsi_adjust_queue_depth(sdev, 0,
+						sdev->host->cmd_per_lun);
+		scsi_build_commandblocks(sdev);
+		if (sdev->current_queue_depth == 0) {
+			printk(KERN_ERR "scsi: Allocation failure during"
+			       " attach, some SCSI devices might not be"
+			       " configured\n");
+			if (sdev->host->hostt->slave_detach != NULL)
+				sdev->host->hostt->slave_detach(sdev);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Function:	scsi_slave_detach()
+ *
+ * Purpose:	Called from the upper level driver attach to handle common
+ * 		detach code.
+ *
+ * Arguments:	sdev - struct scsi_device to detach
+ *
+ * Lock Status:	Protected via scsi_devicelist_mutex.
+ */
+void scsi_slave_detach(struct scsi_device *sdev)
+{
+	if (--sdev->attached == 0) {
+		if (sdev->host->hostt->slave_detach != NULL)
+			sdev->host->hostt->slave_detach(sdev);
+		scsi_release_commandblocks(sdev);
+	}
+}
+/*
  * This entry point should be called by a loadable module if it is trying
  * add a high level scsi driver to the system.
  */
@@ -2053,7 +2098,7 @@
 		for (SDpnt = shpnt->host_queue; SDpnt;
 		     SDpnt = SDpnt->next) {
 			if (tpnt->detect)
-				SDpnt->attached += (*tpnt->detect) (SDpnt);
+				(*tpnt->detect) (SDpnt);
 		}
 	}
 
@@ -2064,22 +2109,14 @@
 	     shpnt = scsi_host_get_next(shpnt)) {
 		for (SDpnt = shpnt->host_queue; SDpnt;
 		     SDpnt = SDpnt->next) {
-			scsi_build_commandblocks(SDpnt);
-			if (SDpnt->current_queue_depth == 0) {
-				out_of_space = 1;
-				continue;
-			}
 			if (tpnt->attach)
+				/*
+				 * XXX check result when the upper level
+				 * attach return values are fixed, and
+				 * stop attaching on failure.
+				 */
 				(*tpnt->attach) (SDpnt);
 
-			/*
-			 * If this driver attached to the device, and don't have any
-			 * command blocks for this device, allocate some.
-			 */
-			if (SDpnt->attached)
-				SDpnt->online = TRUE;
-			else
-				scsi_release_commandblocks(SDpnt);
 		}
 	}
 
@@ -2119,17 +2156,6 @@
 		     SDpnt = SDpnt->next) {
 			if (tpnt->detach)
 				(*tpnt->detach) (SDpnt);
-			if (SDpnt->attached == 0) {
-				SDpnt->online = FALSE;
-
-				/*
-				 * Nobody is using this device any more.  Free all of the
-				 * command structures.
-				 */
-				if (shpnt->hostt->slave_detach)
-					(*shpnt->hostt->slave_detach) (SDpnt);
-				scsi_release_commandblocks(SDpnt);
-			}
 		}
 	}
 	/*
===== drivers/scsi/scsi.h 1.33 vs edited =====
--- 1.33/drivers/scsi/scsi.h	Mon Nov  4 09:04:51 2002
+++ edited/drivers/scsi/scsi.h	Tue Nov  5 17:26:24 2002
@@ -466,6 +466,8 @@
 extern void scsi_release_commandblocks(Scsi_Device * SDpnt);
 extern void scsi_build_commandblocks(Scsi_Device * SDpnt);
 extern void scsi_adjust_queue_depth(Scsi_Device *, int, int);
+extern int scsi_slave_attach(struct scsi_device *sdev);
+extern void scsi_slave_detach(struct scsi_device *sdev);
 extern void scsi_done(Scsi_Cmnd * SCpnt);
 extern void scsi_finish_command(Scsi_Cmnd *);
 extern int scsi_retry_command(Scsi_Cmnd *);
===== drivers/scsi/scsi_mid_low_api.txt 1.4 vs edited =====
--- 1.4/drivers/scsi/scsi_mid_low_api.txt	Thu Oct 24 17:29:22 2002
+++ edited/drivers/scsi/scsi_mid_low_api.txt	Tue Nov  5 19:41:34 2002
@@ -352,33 +352,11 @@
  *      Locks: lock_kernel() active on entry and expected to be active
  *      on return.
  *
- *      Notes: Invoked from mid level's scsi_unregister_host(). When a
- *      host is being unregistered the mid level does not bother to
- *      call revoke() on the devices it controls.
+ *      Notes: Invoked from mid level's scsi_unregister_host().
  *      This function should call scsi_unregister(shp) [found in hosts.c]
  *      prior to returning.
  **/
     int release(struct Scsi_Host * shp);
-
-
-/**
- *      revoke - indicate disinterest in a scsi device
- *      @sdp: host template for this driver.
- *
- *      Return value ignored.
- *
- *      Required: no
- *
- *      Locks: none held
- *
- *      Notes: Called when "scsi remove-single-device <h> <b> <t> <l>"
- *      is written to /proc/scsi/scsi to indicate the device is no longer 
- *      required. It is called after the upper level drivers have detached 
- *      this device and before the device name  (e.g. /dev/sdc) is 
- *      unregistered and the resources associated with it are freed.
- **/
-    int revoke(Scsi_device * sdp);
-
 
 /**
  *      select_queue_depths - calculate allowable number of scsi commands
===== drivers/scsi/scsi_scan.c 1.32 vs edited =====
--- 1.32/drivers/scsi/scsi_scan.c	Sun Nov  3 10:48:33 2002
+++ edited/drivers/scsi/scsi_scan.c	Tue Nov  5 17:27:24 2002
@@ -1480,15 +1480,6 @@
 
 	scsi_detect_device(sdev);
 
-	if (sdev->host->hostt->slave_attach != NULL) {
-		if (sdev->host->hostt->slave_attach(sdev) != 0) {
-			printk(KERN_INFO "%s: scsi_add_lun: failed low level driver attach, setting device offline", devname);
-			sdev->online = FALSE;
-		}
-	} else if(sdev->host->cmd_per_lun) {
-		scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
-	}
-
 	if (sdevnew != NULL)
 		*sdevnew = sdev;
 
===== drivers/scsi/sd.c 1.88 vs edited =====
--- 1.88/drivers/scsi/sd.c	Mon Nov  4 20:08:01 2002
+++ edited/drivers/scsi/sd.c	Tue Nov  5 17:29:12 2002
@@ -1212,9 +1212,12 @@
 	SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", 
 			 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
 
+	if (scsi_slave_attach(sdp))
+		goto out;
+
 	sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL);
 	if (!sdkp)
-		goto out;
+		goto out_detach;
 
 	gd = alloc_disk(16);
 	if (!gd)
@@ -1263,8 +1266,9 @@
 
 out_free:
 	kfree(sdkp);
+out_detach:
+	scsi_slave_detach(sdp);
 out:
-	sdp->attached--;
 	return 1;
 }
 
@@ -1312,7 +1316,7 @@
 
 	sd_devlist_remove(sdkp);
 	del_gendisk(sdkp->disk);
-	sdp->attached--;
+	scsi_slave_detach(sdp);
 	sd_nr_dev--;
 	put_disk(sdkp->disk);
 	kfree(sdkp);
===== drivers/scsi/sg.c 1.37 vs edited =====
--- 1.37/drivers/scsi/sg.c	Tue Nov  5 13:22:20 2002
+++ edited/drivers/scsi/sg.c	Tue Nov  5 17:30:41 2002
@@ -1396,6 +1396,8 @@
 
 	if (!disk)
 		return 1;
+	if (scsi_slave_attach(scsidp))
+		return 1;
 	write_lock_irqsave(&sg_dev_arr_lock, iflags);
 	if (sg_nr_dev >= sg_dev_max) {	/* try to resize */
 		Sg_device **tmp_da;
@@ -1405,10 +1407,10 @@
 		tmp_da = (Sg_device **)vmalloc(
 				tmp_dev_max * sizeof(Sg_device *));
 		if (NULL == tmp_da) {
-			scsidp->attached--;
 			printk(KERN_ERR
 			       "sg_attach: device array cannot be resized\n");
 			put_disk(disk);
+			scsi_slave_detach(scsidp);
 			return 1;
 		}
 		write_lock_irqsave(&sg_dev_arr_lock, iflags);
@@ -1425,7 +1427,6 @@
 		if (!sg_dev_arr[k])
 			break;
 	if (k > SG_MAX_DEVS_MASK) {
-		scsidp->attached--;
 		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
 		printk(KERN_WARNING
 		       "Unable to attach sg device <%d, %d, %d, %d>"
@@ -1435,6 +1436,7 @@
 		if (NULL != sdp)
 			vfree((char *) sdp);
 		put_disk(disk);
+		scsi_slave_detach(scsidp);
 		return 1;
 	}
 	if (k < sg_dev_max) {
@@ -1448,10 +1450,10 @@
 	} else
 		sdp = NULL;
 	if (NULL == sdp) {
-		scsidp->attached--;
 		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
 		printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n");
 		put_disk(disk);
+		scsi_slave_detach(scsidp);
 		return 1;
 	}
 
@@ -1559,7 +1561,7 @@
 			SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));
 			sg_dev_arr[k] = NULL;
 		}
-		scsidp->attached--;
+		scsi_slave_detach(scsidp);
 		sg_nr_dev--;
 		sg_dev_noticed--;	/* from <dan@lectra.fr> */
 		break;
===== drivers/scsi/sr.c 1.63 vs edited =====
--- 1.63/drivers/scsi/sr.c	Mon Nov  4 20:08:08 2002
+++ edited/drivers/scsi/sr.c	Tue Nov  5 17:37:40 2002
@@ -506,6 +506,9 @@
 	if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
 		return 1;
 
+	if (scsi_slave_attach(sdev))
+		return 1;
+
 	cd = kmalloc(sizeof(*cd), GFP_KERNEL);
 	if (!cd)
 		goto fail;
@@ -574,7 +577,7 @@
 fail_free:
 	kfree(cd);
 fail:
-	sdev->attached--;
+	scsi_slave_detach(sdev);
 	return 1;
 }
 
@@ -807,7 +810,7 @@
 	put_disk(cd->disk);
 	unregister_cdrom(&cd->cdi);
 
-	SDp->attached--;
+	scsi_slave_detach(SDp);
 	sr_nr_dev--;
 
 	kfree(cd);
===== drivers/scsi/st.c 1.39 vs edited =====
--- 1.39/drivers/scsi/st.c	Mon Nov  4 20:04:52 2002
+++ edited/drivers/scsi/st.c	Tue Nov  5 17:36:00 2002
@@ -3667,6 +3667,9 @@
 		return 1;
 	}
 
+	if (scsi_slave_attach(SDp))
+		return 1;
+
 	i = SDp->host->sg_tablesize;
 	if (st_max_sg_segs < i)
 		i = st_max_sg_segs;
@@ -3692,11 +3695,11 @@
 		if (tmp_dev_max > ST_MAX_TAPES)
 			tmp_dev_max = ST_MAX_TAPES;
 		if (tmp_dev_max <= st_nr_dev) {
-			SDp->attached--;
 			write_unlock(&st_dev_arr_lock);
 			printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
 			       ST_MAX_TAPES);
 			put_disk(disk);
+			scsi_slave_detach(SDp);
 			return 1;
 		}
 
@@ -3707,10 +3710,10 @@
 				kfree(tmp_da);
 			if (tmp_ba != NULL)
 				kfree(tmp_ba);
-			SDp->attached--;
 			write_unlock(&st_dev_arr_lock);
 			printk(KERN_ERR "st: Can't extend device array.\n");
 			put_disk(disk);
+			scsi_slave_detach(SDp);
 			return 1;
 		}
 
@@ -3733,10 +3736,10 @@
 
 	tpnt = kmalloc(sizeof(Scsi_Tape), GFP_ATOMIC);
 	if (tpnt == NULL) {
-		SDp->attached--;
 		write_unlock(&st_dev_arr_lock);
 		printk(KERN_ERR "st: Can't allocate device descriptor.\n");
 		put_disk(disk);
+		scsi_slave_detach(SDp);
 		return 1;
 	}
 	memset(tpnt, 0, sizeof(Scsi_Tape));
@@ -3906,7 +3909,7 @@
 				tpnt->de_n[mode] = NULL;
 			}
 			scsi_tapes[i] = 0;
-			SDp->attached--;
+			scsi_slave_detach(SDp);
 			st_nr_dev--;
 			write_unlock(&st_dev_arr_lock);
 

-- Patrick Mansfield

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [PATCH] add request prep functions to SCSI
@ 2002-11-06 22:18 J.E.J. Bottomley
  2002-11-06 23:16 ` Doug Ledford
  2002-11-07 21:45 ` Mike Anderson
  0 siblings, 2 replies; 297+ messages in thread
From: J.E.J. Bottomley @ 2002-11-06 22:18 UTC (permalink / raw)
  To: linux-scsi

[-- Attachment #1: Type: text/plain, Size: 711 bytes --]

This patch adds request prep functions to the mid-layer.  At the moment, its a single request prep function for all of SCSI.  I've altered the logic in scsi_request_fn so that we now do early preparation (this should improve throughput slightly in the untagged case with only a single command block).

The prep function also cannot drop the queue lock, so the calling assumptions for scsi_init_io and the upper layer driver init_commands have changed to be that the lock is now held and they cannot drop it.  I think this means that we have no callers of scsi_init_io that aren't atomic, so perhaps I can just take the if out.

I've hammered this in my usual set up, but other testers would be welcome.

James


[-- Attachment #2: tmp.diff --]
[-- Type: text/plain , Size: 11011 bytes --]

===== drivers/scsi/scsi.c 1.56 vs edited =====
--- 1.56/drivers/scsi/scsi.c	Wed Nov  6 15:12:50 2002
+++ edited/drivers/scsi/scsi.c	Wed Nov  6 15:30:27 2002
@@ -226,6 +226,8 @@
 
 	if (!SHpnt->use_clustering)
 		clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+
+        blk_queue_prep_rq(q, scsi_prep_fn);
 }
 
 #ifdef MODULE
===== drivers/scsi/scsi.h 1.34 vs edited =====
--- 1.34/drivers/scsi/scsi.h	Tue Nov  5 11:26:24 2002
+++ edited/drivers/scsi/scsi.h	Wed Nov  6 15:30:28 2002
@@ -455,6 +455,7 @@
 extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
 			       int block_sectors);
 extern void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt);
+extern int scsi_prep_fn(struct request_queue *q, struct request *req);
 extern void scsi_request_fn(request_queue_t * q);
 extern int scsi_starvation_completion(Scsi_Device * SDpnt);
 
===== drivers/scsi/scsi_lib.c 1.44 vs edited =====
--- 1.44/drivers/scsi/scsi_lib.c	Fri Nov  1 06:28:12 2002
+++ edited/drivers/scsi/scsi_lib.c	Wed Nov  6 16:11:13 2002
@@ -102,6 +102,13 @@
 {
 	request_queue_t *q = &SRpnt->sr_device->request_queue;
 
+	/* This is used to insert SRpnt specials.  Because users of
+	 * this function are apt to reuse requests with no modification,
+	 * we have to sanitise the request flags here
+	 */
+
+	SRpnt->sr_request->flags &= ~REQ_DONTPREP;
+
 	blk_insert_request(q, SRpnt->sr_request, at_head, SRpnt);
 	return 0;
 }
@@ -240,6 +247,12 @@
 		SCpnt->request->special = (void *) SCpnt;
 		if(blk_rq_tagged(SCpnt->request))
 			blk_queue_end_tag(q, SCpnt->request);
+		/* set REQ_SPECIAL - we have a command
+		 * clear REQ_DONTPREP - we assume the sg table has been 
+		 *	nuked so we need to set it up again.
+		 */
+		SCpnt->request->flags |= REQ_SPECIAL;
+		SCpnt->request->flags &= ~REQ_DONTPREP;
 		__elv_add_request(q, SCpnt->request, 0, 0);
 	}
 
@@ -741,7 +754,7 @@
 	SCpnt->use_sg = req->nr_phys_segments;
 
 	gfp_mask = GFP_NOIO;
-	if (in_interrupt()) {
+	if (likely(in_atomic())) {
 		gfp_mask &= ~__GFP_WAIT;
 		gfp_mask |= __GFP_HIGH;
 	}
@@ -788,6 +801,116 @@
 	return 0;
 }
 
+int scsi_prep_fn(struct request_queue *q, struct request *req)
+{
+	struct Scsi_Device_Template *STpnt;
+	Scsi_Cmnd *SCpnt;
+	Scsi_Device *SDpnt;
+
+	SDpnt = (Scsi_Device *) q->queuedata;
+	BUG_ON(!SDpnt);
+
+	/*
+	 * Find the actual device driver associated with this command.
+	 * The SPECIAL requests are things like character device or
+	 * ioctls, which did not originate from ll_rw_blk.  Note that
+	 * the special field is also used to indicate the SCpnt for
+	 * the remainder of a partially fulfilled request that can 
+	 * come up when there is a medium error.  We have to treat
+	 * these two cases differently.  We differentiate by looking
+	 * at request->cmd, as this tells us the real story.
+	 */
+	if (req->flags & REQ_SPECIAL) {
+		Scsi_Request *SRpnt;
+
+		STpnt = NULL;
+		SCpnt = (Scsi_Cmnd *) req->special;
+		SRpnt = (Scsi_Request *) req->special;
+		
+		if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) {
+			SCpnt = scsi_allocate_device(SRpnt->sr_device, 
+						     FALSE, FALSE);
+			if (!SCpnt)
+				return BLKPREP_DEFER;
+			scsi_init_cmd_from_req(SCpnt, SRpnt);
+		}
+		
+	} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+		/*
+		 * Now try and find a command block that we can use.
+		 */
+		if (req->special) {
+				SCpnt = (Scsi_Cmnd *) req->special;
+		} else {
+			SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE);
+		}
+		/*
+		 * if command allocation failure, wait a bit
+		 */
+		if (unlikely(!SCpnt))
+			return BLKPREP_DEFER;
+		
+		/* pull a tag out of the request if we have one */
+		SCpnt->tag = req->tag;
+	} else {
+		blk_dump_rq_flags(req, "SCSI bad req");
+		return BLKPREP_KILL;
+	}
+	
+	/* note the overloading of req->special.  When the tag
+	 * is active it always means SCpnt.  If the tag goes
+	 * back for re-queueing, it may be reset */
+	req->special = SCpnt;
+	SCpnt->request = req;
+	
+	/*
+	 * FIXME: drop the lock here because the functions below
+	 * expect to be called without the queue lock held.  Also,
+	 * previously, we dequeued the request before dropping the
+	 * lock.  We hope REQ_STARTED prevents anything untoward from
+	 * happening now.
+	 */
+
+	if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+		/*
+		 * This will do a couple of things:
+		 *  1) Fill in the actual SCSI command.
+		 *  2) Fill in any other upper-level specific fields
+		 * (timeout).
+		 *
+		 * If this returns 0, it means that the request failed
+		 * (reading past end of disk, reading offline device,
+		 * etc).   This won't actually talk to the device, but
+		 * some kinds of consistency checking may cause the	
+		 * request to be rejected immediately.
+		 */
+		STpnt = scsi_get_request_dev(req);
+		BUG_ON(!STpnt);
+
+		/* 
+		 * This sets up the scatter-gather table (allocating if
+		 * required).
+		 */
+		if (!scsi_init_io(SCpnt)) {
+			/* Mark it as special --- We already have an
+			 * allocated command associated with it */
+			req->flags |= REQ_SPECIAL;
+			return BLKPREP_DEFER;
+		}
+		
+		/*
+		 * Initialize the actual SCSI command for this request.
+		 */
+		if (!STpnt->init_command(SCpnt)) {
+			scsi_release_buffers(SCpnt);
+			return BLKPREP_KILL;
+		}
+	}
+	/* The request is now prepped, no need to come back here */
+	req->flags |= REQ_DONTPREP;
+	return BLKPREP_OK;
+}
+
 /*
  * Function:    scsi_request_fn()
  *
@@ -811,10 +934,8 @@
 {
 	struct request *req;
 	Scsi_Cmnd *SCpnt;
-	Scsi_Request *SRpnt;
 	Scsi_Device *SDpnt;
 	struct Scsi_Host *SHpnt;
-	struct Scsi_Device_Template *STpnt;
 
 	ASSERT_LOCK(q->queue_lock, 1);
 
@@ -837,6 +958,14 @@
 		if (SHpnt->in_recovery || blk_queue_plugged(q))
 			return;
 
+		/*
+		 * get next queueable request.  We do this early to make sure
+		 * that the request is fully prepared even if we cannot 
+		 * accept it.  If there is no request, we'll detect this
+		 * lower down.
+		 */
+		req = elv_next_request(q);
+
 		if(SHpnt->host_busy == 0 && SHpnt->host_blocked) {
 			/* unblock after host_blocked iterates to zero */
 			if(--SHpnt->host_blocked == 0) {
@@ -888,141 +1017,40 @@
 		if (blk_queue_empty(q))
 			break;
 
-		/*
-		 * get next queueable request.
-		 */
-		req = elv_next_request(q);
-
-		/*
-		 * Find the actual device driver associated with this command.
-		 * The SPECIAL requests are things like character device or
-		 * ioctls, which did not originate from ll_rw_blk.  Note that
-		 * the special field is also used to indicate the SCpnt for
-		 * the remainder of a partially fulfilled request that can 
-		 * come up when there is a medium error.  We have to treat
-		 * these two cases differently.  We differentiate by looking
-		 * at request->cmd, as this tells us the real story.
-		 */
-		if (req->flags & REQ_SPECIAL) {
-			STpnt = NULL;
-			SCpnt = (Scsi_Cmnd *) req->special;
-			SRpnt = (Scsi_Request *) req->special;
-
-			if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) {
-				SCpnt = scsi_allocate_device(SRpnt->sr_device, 
-							     FALSE, FALSE);
-				if (!SCpnt)
-					break;
-				scsi_init_cmd_from_req(SCpnt, SRpnt);
-			}
-
-		} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
-			SRpnt = NULL;
-			STpnt = scsi_get_request_dev(req);
-			if (!STpnt) {
-				panic("Unable to find device associated with request");
-			}
-			/*
-			 * Now try and find a command block that we can use.
-			 */
-			if (req->special) {
-				SCpnt = (Scsi_Cmnd *) req->special;
-			} else {
-				SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE);
-			}
-			/*
-			 * If so, we are ready to do something.  Bump the count
-			 * while the queue is locked and then break out of the
-			 * loop. Otherwise loop around and try another request.
-			 */
-			if (!SCpnt)
-				break;
-
-			/* pull a tag out of the request if we have one */
-			SCpnt->tag = req->tag;
-		} else {
-			blk_dump_rq_flags(req, "SCSI bad req");
+		if(!req) {
+			/* can happen if the prep fails 
+			 * FIXME: elv_next_request() should be plugging the
+			 * queue */
+			blk_plug_device(q);
 			break;
 		}
 
-		/*
-		 * Now bump the usage count for both the host and the
-		 * device.
+		SCpnt = (struct scsi_cmnd *)req->special;
+
+		/* Should be impossible for a correctly prepared request
+		 * please mail the stack trace to linux-scsi@vger.kernel.org
 		 */
-		SHpnt->host_busy++;
-		SDpnt->device_busy++;
+		BUG_ON(!SCpnt);
 
 		/*
 		 * Finally, before we release the lock, we copy the
 		 * request to the command block, and remove the
-		 * request from the request list.   Note that we always
+		 * request from the request list.  Note that we always
 		 * operate on the queue head - there is absolutely no
-		 * reason to search the list, because all of the commands
-		 * in this queue are for the same device.
+		 * reason to search the list, because all of the
+		 * commands in this queue are for the same device.
 		 */
 		if(!(blk_queue_tagged(q) && (blk_queue_start_tag(q, req) == 0)))
 			blkdev_dequeue_request(req);
-
-		/* note the overloading of req->special.  When the tag
-		 * is active it always means SCpnt.  If the tag goes
-		 * back for re-queueing, it may be reset */
-		req->special = SCpnt;
-		SCpnt->request = req;
-
+	
 		/*
-		 * Now it is finally safe to release the lock.  We are
-		 * not going to noodle the request list until this
-		 * request has been queued and we loop back to queue
-		 * another.  
+		 * Now bump the usage count for both the host and the
+		 * device.
 		 */
-		req = NULL;
+		SHpnt->host_busy++;
+		SDpnt->device_busy++;
 		spin_unlock_irq(q->queue_lock);
 
-		if (!(SCpnt->request->flags & REQ_DONTPREP)
-		    && (SCpnt->request->flags & (REQ_CMD | REQ_BLOCK_PC))) {
-			/*
-			 * This will do a couple of things:
-			 *  1) Fill in the actual SCSI command.
-			 *  2) Fill in any other upper-level specific fields
-			 * (timeout).
-			 *
-			 * If this returns 0, it means that the request failed
-			 * (reading past end of disk, reading offline device,
-			 * etc).   This won't actually talk to the device, but
-			 * some kinds of consistency checking may cause the	
-			 * request to be rejected immediately.
-			 */
-			if (STpnt == NULL)
-				STpnt = scsi_get_request_dev(SCpnt->request);
-
-			/* 
-			 * This sets up the scatter-gather table (allocating if
-			 * required).
-			 */
-			if (!scsi_init_io(SCpnt)) {
-				scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_DEVICE_BUSY);
-				spin_lock_irq(q->queue_lock);
-				break;
-			}
-
-			/*
-			 * Initialize the actual SCSI command for this request.
-			 */
-			if (!STpnt->init_command(SCpnt)) {
-				scsi_release_buffers(SCpnt);
-				SCpnt = __scsi_end_request(SCpnt, 0, 
-							   SCpnt->request->nr_sectors, 0, 0);
-				if( SCpnt != NULL )
-				{
-					panic("Should not have leftover blocks\n");
-				}
-				spin_lock_irq(q->queue_lock);
-				SHpnt->host_busy--;
-				SDpnt->device_busy--;
-				continue;
-			}
-		}
-		SCpnt->request->flags |= REQ_DONTPREP;
 		/*
 		 * Finally, initialize any error handling parameters, and set up
 		 * the timers for timeouts.

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [RFC][PATCH] move dma_mask into struct device
@ 2002-11-15 20:34 J.E.J. Bottomley
  2002-11-16  0:19 ` Mike Anderson
  2002-11-16 20:33 ` Patrick Mansfield
  0 siblings, 2 replies; 297+ messages in thread
From: J.E.J. Bottomley @ 2002-11-15 20:34 UTC (permalink / raw)
  To: linux-kernel, linux-scsi; +Cc: grundler, willy

[-- Attachment #1: Type: text/plain, Size: 1216 bytes --]

Attached is a patch which moves dma_mask into struct device and cleans up the 
scsi mid-layer to use it (instead of using struct pci_dev).  The advantage to 
doing this is probably most apparent on non-pci bus architectures where 
currently you have to construct a fake pci_dev just so you can get the bounce 
buffers to work correctly.

The patch tries to perturb the minimum amount of code, so dma_mask in struct 
device is simply a pointer to the one in pci_dev.  However, it will make it 
easy for me now to add generic device to MCA without having to go the fake pci 
route.

This patch completely removes knowledge of pci devices from the SCSI mid-layer.

I have compiled and tested this, but obviously, since I have an MCA machine, 
it's not of much value to the pci code changes, so if someone with a PCI 
machine could check those out, I'd be grateful.

The main problem SCSI has with this is the scsi_ioctl_get_pci which is used to 
get the pci slot name.  Although, this can be fixed up afterwards with Matthew 
Wilcox's name change patch.

I'd like to see this as the beginning of a move away from bus specific code to 
using generic device code (where possible).  Comments and feedback welcome.

James


[-- Attachment #2: tmp.diff --]
[-- Type: text/plain , Size: 3432 bytes --]

===== drivers/pci/probe.c 1.17 vs edited =====
--- 1.17/drivers/pci/probe.c	Fri Nov  1 12:33:02 2002
+++ edited/drivers/pci/probe.c	Fri Nov 15 14:00:46 2002
@@ -449,6 +449,7 @@
 	/* now put in global tree */
 	strcpy(dev->dev.name,dev->name);
 	strcpy(dev->dev.bus_id,dev->slot_name);
+	dev->dev->dma_mask = &dev->dma_mask;
 
 	device_register(&dev->dev);
 	return dev;
===== drivers/scsi/hosts.h 1.36 vs edited =====
--- 1.36/drivers/scsi/hosts.h	Thu Nov 14 13:07:27 2002
+++ edited/drivers/scsi/hosts.h	Fri Nov 15 14:43:59 2002
@@ -468,10 +468,10 @@
     unsigned int max_host_blocked;
 
     /*
-     * For SCSI hosts which are PCI devices, set pci_dev so that
-     * we can do BIOS EDD 3.0 mappings
+     * This is a pointer to the generic device for this host (i.e. the
+     * device on the bus);
      */
-    struct pci_dev *pci_dev;
+    struct device *dev;
 
     /* 
      * Support for driverfs filesystem
@@ -521,11 +521,17 @@
 	shost->host_lock = lock;
 }
 
+static inline void scsi_set_device(struct Scsi_Host *shost,
+                                   struct device *dev)
+{
+        shost->dev = dev;
+        shost->host_driverfs_dev.parent = dev;
+}
+
 static inline void scsi_set_pci_device(struct Scsi_Host *shost,
                                        struct pci_dev *pdev)
 {
-	shost->pci_dev = pdev;
-	shost->host_driverfs_dev.parent=&pdev->dev;
+        scsi_set_device(shost, &pdev->dev);
 }
 
 
===== drivers/scsi/scsi_ioctl.c 1.12 vs edited =====
--- 1.12/drivers/scsi/scsi_ioctl.c	Thu Oct 17 13:52:39 2002
+++ edited/drivers/scsi/scsi_ioctl.c	Fri Nov 15 14:08:19 2002
@@ -396,9 +396,9 @@
 scsi_ioctl_get_pci(Scsi_Device * dev, void *arg)
 {
 
-        if (!dev->host->pci_dev) return -ENXIO;
-        return copy_to_user(arg, dev->host->pci_dev->slot_name,
-                            sizeof(dev->host->pci_dev->slot_name));
+        if (!dev->host->dev) return -ENXIO;
+        return copy_to_user(arg, dev->host->dev->name,
+                            sizeof(dev->host->dev->name));
 }
 
 
===== drivers/scsi/scsi_scan.c 1.35 vs edited =====
--- 1.35/drivers/scsi/scsi_scan.c	Thu Nov 14 12:34:35 2002
+++ edited/drivers/scsi/scsi_scan.c	Fri Nov 15 14:25:41 2002
@@ -436,8 +436,8 @@
 	u64 bounce_limit;
 
 	if (sh->highmem_io) {
-		if (sh->pci_dev && PCI_DMA_BUS_IS_PHYS) {
-			bounce_limit = sh->pci_dev->dma_mask;
+		if (sh->dev && sh->dev->dma_mask && PCI_DMA_BUS_IS_PHYS) {
+			bounce_limit = *sh->dev->dma_mask;
 		} else {
 			/*
 			 * Platforms with virtual-DMA translation
===== drivers/scsi/st.c 1.42 vs edited =====
--- 1.42/drivers/scsi/st.c	Mon Nov 11 03:32:34 2002
+++ edited/drivers/scsi/st.c	Fri Nov 15 14:25:58 2002
@@ -3786,8 +3786,8 @@
 			 * hardware have no practical limit.
 			 */
 			bounce_limit = BLK_BOUNCE_ANY;
-		else if (SDp->host->pci_dev)
-			bounce_limit = SDp->host->pci_dev->dma_mask;
+		else if (SDp->host->dev && SDp->host->dev->dma_mask)
+			bounce_limit = *SDp->host->dev->dma_mask;
 	} else if (SDp->host->unchecked_isa_dma)
 		bounce_limit = BLK_BOUNCE_ISA;
 	bounce_limit >>= PAGE_SHIFT;
===== include/linux/device.h 1.58 vs edited =====
--- 1.58/include/linux/device.h	Thu Oct 31 15:25:58 2002
+++ edited/include/linux/device.h	Fri Nov 15 13:52:55 2002
@@ -300,6 +300,7 @@
 					   being off. */
 
 	unsigned char *saved_state;	/* saved device state */
+	u64		*dma_mask;	/* dma mask (if dma'able device) */
 
 	void	(*release)(struct device * dev);
 };

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [PATCH] removel useless mod use count manipulation
@ 2002-11-16 19:40 Christoph Hellwig
  2002-11-17  2:59 ` Doug Ledford
  2002-11-17 12:40 ` Douglas Gilbert
  0 siblings, 2 replies; 297+ messages in thread
From: Christoph Hellwig @ 2002-11-16 19:40 UTC (permalink / raw)
  To: James.Bottomley; +Cc: linux-scsi

There's a bunch of useless mod usecount handling in scsi:

o MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in exported functions that
  are only used outside this module - a module that has exported
  symbols use by other modules can't be unloaded at all
o GET_USE_COUNT checks in scsi_unregister_device/scsi_unregister_host -
  the scsi layer shouldn't care about the mod use count of the modules
  implementing drivers, and as they are usually called from the mod
  unload handler the check is totally pointless (if it ever triggers
  the scsi midlayer could try to scramble at freed memory).  Also
  GET_USE_COUNT is disfunct with the new module loader
o lacking ->owner in megaraid's chardev leading to junk
o double-increment of the modules use count in upper layer drivers
  (chardev/bdev open already gets a reference on ->owner for us)

I also had a patch to get the increment on the host driver module
in upper layer ->open right, but as Rusty's new loader changed the
interface for that I'll submit that one once the new loader appears
in the scsi tree.

===== drivers/scsi/NCR53C9x.c 1.12 vs edited =====
--- 1.12/drivers/scsi/NCR53C9x.c	Wed Oct  9 12:20:19 2002
+++ edited/drivers/scsi/NCR53C9x.c	Sat Nov 16 19:16:14 2002
@@ -732,9 +732,6 @@
 	/* Reset the thing before we try anything... */
 	esp_bootup_reset(esp, eregs);
 
-#ifdef MODULE
-	MOD_INC_USE_COUNT;
-#endif
 	esps_in_use++;
 }
 
@@ -3638,7 +3635,6 @@
 void cleanup_module(void) {}
 void esp_release(void)
 {
-	MOD_DEC_USE_COUNT;
 	esps_in_use--;
 	esps_running = esps_in_use;
 }
===== drivers/scsi/hosts.c 1.27 vs edited =====
--- 1.27/drivers/scsi/hosts.c	Thu Nov 14 13:19:04 2002
+++ edited/drivers/scsi/hosts.c	Sat Nov 16 19:14:08 2002
@@ -220,12 +220,6 @@
 	struct scsi_cmnd *scmd;
 
 	/*
-	 * Current policy is all shosts go away on unregister.
-	 */
-	if (shost->hostt->module && GET_USE_COUNT(shost->hostt->module))
-		return 1;
-
-	/*
 	 * FIXME Do ref counting.  We force all of the devices offline to
 	 * help prevent race conditions where other hosts/processors could
 	 * try and get in and queue a command.
@@ -520,8 +514,6 @@
 
 	cur_cnt = scsi_hosts_registered;
 
-	MOD_INC_USE_COUNT;
-
 	/*
 	 * The detect routine must carefully spinunlock/spinlock if it
 	 * enables interrupts, since all interrupt handlers do spinlock as
@@ -604,8 +596,6 @@
 	if (pcount != scsi_hosts_registered)
 		printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered,
 		       (scsi_hosts_registered == 1) ? "" : "s");
-
-	MOD_DEC_USE_COUNT;
 
 	unlock_kernel();
 	return 0;
===== drivers/scsi/megaraid.c 1.27 vs edited =====
--- 1.27/drivers/scsi/megaraid.c	Thu Oct 31 23:59:07 2002
+++ edited/drivers/scsi/megaraid.c	Sat Nov 16 19:15:23 2002
@@ -760,9 +760,8 @@
 /* For controller re-ordering */ 
 
 static struct file_operations megadev_fops = {
-	ioctl:megadev_ioctl_entry,
-	open:megadev_open,
-	release:megadev_close,
+	.owner		= THIS_MODULE,
+	.ioctl		= megadev_ioctl_entry,
 };
 
 /*
@@ -4333,15 +4332,6 @@
 	}
 }
 
-/*
- * Routines for the character/ioctl interface to the driver
- */
-static int megadev_open (struct inode *inode, struct file *filep)
-{
-	MOD_INC_USE_COUNT;
-	return 0;		/* success */
-}
-
 static int megadev_ioctl_entry (struct inode *inode, struct file *filep,
 		     unsigned int cmd, unsigned long arg)
 {
@@ -4851,16 +4841,6 @@
 
 	return scb;
 }
-
-static int
-megadev_close (struct inode *inode, struct file *filep)
-{
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
-	return 0;
-}
-
 
 static int
 mega_support_ext_cdb(mega_host_config *this_hba)
===== drivers/scsi/osst.c 1.27 vs edited =====
--- 1.27/drivers/scsi/osst.c	Mon Nov 11 03:32:34 2002
+++ edited/drivers/scsi/osst.c	Sat Nov 16 19:20:34 2002
@@ -4176,8 +4176,6 @@
 
 	if (STp->device->host->hostt->module)
 		 __MOD_INC_USE_COUNT(STp->device->host->hostt->module);
-	if (osst_template.module)
-		 __MOD_INC_USE_COUNT(osst_template.module);
 	STp->device->access_count++;
 
 	if (mode != STp->current_mode) {
@@ -4520,8 +4518,6 @@
 
 	if (STp->device->host->hostt->module)
 	    __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
-	if (osst_template.module)
-	    __MOD_DEC_USE_COUNT(osst_template.module);
 
 	return retval;
 }
@@ -4651,8 +4647,6 @@
 
 	if (STp->device->host->hostt->module)
 		__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
-	if(osst_template.module)
-		__MOD_DEC_USE_COUNT(osst_template.module);
 
 	return result;
 }
===== drivers/scsi/scsi.c 1.61 vs edited =====
--- 1.61/drivers/scsi/scsi.c	Thu Nov 14 13:19:04 2002
+++ edited/drivers/scsi/scsi.c	Sat Nov 16 19:08:34 2002
@@ -2404,8 +2404,6 @@
 		}
 	}
 
-	MOD_INC_USE_COUNT;
-
 	if (out_of_space) {
 		scsi_unregister_device(tpnt);	/* easiest way to clean up?? */
 		return 1;
@@ -2422,12 +2420,6 @@
 	struct Scsi_Device_Template *prev_spnt;
 	
 	lock_kernel();
-	/*
-	 * If we are busy, this is not going to fly.
-	 */
-	if (GET_USE_COUNT(tpnt->module) != 0)
-		goto error_out;
-
 	driver_unregister(&tpnt->scsi_driverfs_driver);
 
 	/*
@@ -2458,16 +2450,12 @@
 		prev_spnt->next = spnt->next;
 	up_write(&scsi_devicelist_mutex);
 
-	MOD_DEC_USE_COUNT;
 	unlock_kernel();
 	/*
 	 * Final cleanup for the driver is done in the driver sources in the
 	 * cleanup function.
 	 */
 	return 0;
-error_out:
-	unlock_kernel();
-	return -1;
 }
 
 #ifdef CONFIG_PROC_FS
===== drivers/scsi/sd.c 1.91 vs edited =====
--- 1.91/drivers/scsi/sd.c	Sat Nov  9 18:48:20 2002
+++ edited/drivers/scsi/sd.c	Sat Nov 16 19:19:05 2002
@@ -453,8 +453,6 @@
 	 */
 	if (sdp->host->hostt->module)
 		__MOD_INC_USE_COUNT(sdp->host->hostt->module);
-	if (sd_template.module)
-		__MOD_INC_USE_COUNT(sd_template.module);
 	sdp->access_count++;
 
 	if (sdp->removable) {
@@ -498,8 +496,6 @@
 	sdp->access_count--;
 	if (sdp->host->hostt->module)
 		__MOD_DEC_USE_COUNT(sdp->host->hostt->module);
-	if (sd_template.module)
-		__MOD_DEC_USE_COUNT(sd_template.module);
 	return retval;	
 }
 
@@ -536,8 +532,6 @@
 	}
 	if (sdp->host->hostt->module)
 		__MOD_DEC_USE_COUNT(sdp->host->hostt->module);
-	if (sd_template.module)
-		__MOD_DEC_USE_COUNT(sd_template.module);
 
 	return 0;
 }
===== drivers/scsi/sg.c 1.39 vs edited =====
--- 1.39/drivers/scsi/sg.c	Wed Nov  6 21:06:38 2002
+++ edited/drivers/scsi/sg.c	Sat Nov 16 19:20:02 2002
@@ -1304,8 +1304,6 @@
 				if (sdp->device->host->hostt->module)
 					__MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
 			}
-			if (sg_template.module)
-				__MOD_DEC_USE_COUNT(sg_template.module);
 			sfp = NULL;
 		}
 	} else if (srp && srp->orphan) {
@@ -1529,8 +1527,6 @@
 				}
 				if (sfp->closed) {
 					sdp->device->access_count--;
-					if (sg_template.module)
-						__MOD_DEC_USE_COUNT(sg_template.module);
 					if (sdp->device->host->hostt->module)
 						__MOD_DEC_USE_COUNT(
 							sdp->device->host->
@@ -2522,8 +2518,6 @@
 		sfp->closed = 1;	/* flag dirty state on this fd */
 		sdp->device->access_count++;
 		/* MOD_INC's to inhibit unloading sg and associated adapter driver */
-		if (sg_template.module)
-			__MOD_INC_USE_COUNT(sg_template.module);
 		if (sdp->device->host->hostt->module)
 			__MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
 		SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
===== drivers/scsi/sr.c 1.65 vs edited =====
--- 1.65/drivers/scsi/sr.c	Wed Nov  6 21:04:59 2002
+++ edited/drivers/scsi/sr.c	Sat Nov 16 19:20:31 2002
@@ -130,8 +130,6 @@
 	cd->device->access_count--;
 	if (cd->device->host->hostt->module)
 		__MOD_DEC_USE_COUNT(cd->device->host->hostt->module);
-	if (sr_template.module)
-		__MOD_DEC_USE_COUNT(sr_template.module);
 }
 
 static struct cdrom_device_ops sr_dops = {
@@ -473,8 +471,6 @@
 	cd->device->access_count++;
 	if (cd->device->host->hostt->module)
 		__MOD_INC_USE_COUNT(cd->device->host->hostt->module);
-	if (sr_template.module)
-		__MOD_INC_USE_COUNT(sr_template.module);
 
 	/* If this device did not have media in the drive at boot time, then
 	 * we would have been unable to get the sector size.  Check to see if
===== drivers/scsi/wd33c93.c 1.5 vs edited =====
--- 1.5/drivers/scsi/wd33c93.c	Wed Oct 16 18:51:48 2002
+++ edited/drivers/scsi/wd33c93.c	Sat Nov 16 19:13:37 2002
@@ -1853,7 +1853,6 @@
    printk("\n");
    printk("           Version %s - %s, Compiled %s at %s\n",
                WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
-   MOD_INC_USE_COUNT;
 }
 
 
@@ -2031,7 +2030,6 @@
 #endif
 void wd33c93_release(void)
 {
-   MOD_DEC_USE_COUNT;
 }
 
 MODULE_LICENSE("GPL");

^ permalink raw reply	[flat|nested] 297+ messages in thread
* [PATCH] turn scsi_allocate_device into readable code
@ 2002-11-21 15:16 Christoph Hellwig
  2002-11-21 15:36 ` Doug Ledford
  0 siblings, 1 reply; 297+ messages in thread
From: Christoph Hellwig @ 2002-11-21 15:16 UTC (permalink / raw)
  To: James.Bottomley; +Cc: linux-scsi


--- 1.23/drivers/scsi/cpqfcTSinit.c	Fri Oct 25 03:13:39 2002
+++ edited/drivers/scsi/cpqfcTSinit.c	Thu Nov 21 15:51:32 2002
@@ -1604,7 +1604,7 @@
   scsi_cdb[0] = RELEASE;
 
   // allocate with wait = true, interruptible = false 
-  SCpnt = scsi_allocate_device(ScsiDev, 1, 0);
+  SCpnt = scsi_allocate_device(ScsiDev, 1);
   {
     CPQFC_DECLARE_COMPLETION(wait);
     
--- 1.15/drivers/scsi/gdth.c	Fri Nov  8 08:47:03 2002
+++ edited/drivers/scsi/gdth.c	Thu Nov 21 15:51:32 2002
@@ -4599,7 +4599,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
-    scp  = scsi_allocate_device(sdev, 1, FALSE);
+    scp  = scsi_allocate_device(sdev, 1);
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -4673,7 +4673,7 @@
         memset(cmnd, 0xff, MAX_COMMAND_SIZE);
 #if LINUX_VERSION_CODE >= 0x020322
         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
-        scp  = scsi_allocate_device(sdev, 1, FALSE);
+        scp  = scsi_allocate_device(sdev, 1);
         scp->cmd_len = 12;
         scp->use_sg = 0;
 #else
--- 1.6/drivers/scsi/gdth_proc.c	Sat Apr 13 19:42:56 2002
+++ edited/drivers/scsi/gdth_proc.c	Thu Nov 21 15:51:33 2002
@@ -48,7 +48,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
-    scp  = scsi_allocate_device(sdev, 1, FALSE);
+    scp  = scsi_allocate_device(sdev, 1);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
@@ -712,7 +712,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
-    scp  = scsi_allocate_device(sdev, 1, FALSE);
+    scp  = scsi_allocate_device(sdev, 1);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
--- 1.69/drivers/scsi/scsi.c	Mon Nov 18 17:14:23 2002
+++ edited/drivers/scsi/scsi.c	Thu Nov 21 15:51:33 2002
@@ -347,6 +347,41 @@
 }
 
 /*
+ * FIXME(eric) - this is not at all optimal.  Given that
+ * single lun devices are rare and usually slow
+ * (i.e. CD changers), this is good enough for now, but
+ * we may want to come back and optimize this later.
+ *
+ * Scan through all of the devices attached to this
+ * host, and see if any are active or not.  If so,
+ * we need to defer this command.
+ *
+ * We really need a busy counter per device.  This would
+ * allow us to more easily figure out whether we should
+ * do anything here or not.
+ */
+static int check_all_luns(struct Scsi_Host *shost, struct scsi_device *myself)
+{
+	struct scsi_device *sdev;
+
+	for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
+		/*
+		 * Only look for other devices on the same bus
+		 * with the same target ID.
+		 */
+		if (sdev->channel != myself->channel || sdev->id != myself->id)
+			continue;
+		if (sdev == myself)
+			continue;
+
+		if (atomic_read(&sdev->device_active))
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
  * Function:    scsi_allocate_device
  *
  * Purpose:     Allocate a command descriptor.
@@ -372,172 +407,87 @@
  *              This function is deprecated, and drivers should be
  *              rewritten to use Scsi_Request instead of Scsi_Cmnd.
  */
-
-Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait, 
-                                int interruptable)
+struct scsi_cmnd *scsi_allocate_device(struct scsi_device *sdev, int wait)
 {
- 	struct Scsi_Host *host;
-  	Scsi_Cmnd *SCpnt = NULL;
-	Scsi_Device *SDpnt;
+	DECLARE_WAITQUEUE(wq, current);
+	struct Scsi_Host *shost = sdev->host;
+	struct scsi_cmnd *scmnd;
 	unsigned long flags;
-  
-  	if (!device)
-  		panic("No device passed to scsi_allocate_device().\n");
-  
-  	host = device->host;
-  
+
 	spin_lock_irqsave(&device_request_lock, flags);
- 
-	while (1 == 1) {
-		SCpnt = NULL;
-		if (!device->device_blocked) {
-			if (device->single_lun) {
-				/*
-				 * FIXME(eric) - this is not at all optimal.  Given that
-				 * single lun devices are rare and usually slow
-				 * (i.e. CD changers), this is good enough for now, but
-				 * we may want to come back and optimize this later.
-				 *
-				 * Scan through all of the devices attached to this
-				 * host, and see if any are active or not.  If so,
-				 * we need to defer this command.
-				 *
-				 * We really need a busy counter per device.  This would
-				 * allow us to more easily figure out whether we should
-				 * do anything here or not.
-				 */
-				for (SDpnt = host->host_queue;
-				     SDpnt;
-				     SDpnt = SDpnt->next) {
-					/*
-					 * Only look for other devices on the same bus
-					 * with the same target ID.
-					 */
-					if (SDpnt->channel != device->channel
-					    || SDpnt->id != device->id
-					    || SDpnt == device) {
- 						continue;
-					}
-                                        if( atomic_read(&SDpnt->device_active) != 0)
-                                        {
-                                                break;
-                                        }
-				}
-				if (SDpnt) {
-					/*
-					 * Some other device in this cluster is busy.
-					 * If asked to wait, we need to wait, otherwise
-					 * return NULL.
-					 */
-					SCpnt = NULL;
-					goto busy;
-				}
-			}
-			/*
-			 * Now we can check for a free command block for this device.
-			 */
-			for (SCpnt = device->device_queue; SCpnt; SCpnt = SCpnt->next) {
-				if (SCpnt->request == NULL)
-					break;
-			}
-		}
+	while (1) {
+		if (sdev->device_blocked)
+			goto busy;
+		if (sdev->single_lun && check_all_luns(shost, sdev))
+			goto busy;
+
 		/*
-		 * If we couldn't find a free command block, and we have been
-		 * asked to wait, then do so.
+		 * Now we can check for a free command block for this device.
 		 */
-		if (SCpnt) {
-			break;
-		}
-      busy:
+		for (scmnd = sdev->device_queue; scmnd; scmnd = scmnd->next)
+			if (!scmnd->request)
+				goto found;
+
+busy:
+		if (!wait)
+			goto fail;
+
 		/*
-		 * If we have been asked to wait for a free block, then
-		 * wait here.
+		 * We need to wait for a free commandblock.  We need to
+		 * insert ourselves into the list before we release the
+		 * lock.  This way if a block were released the same
+		 * microsecond that we released the lock, the call
+		 * to schedule() wouldn't block (well, it might switch,
+		 * but the current task will still be schedulable.
 		 */
-		if (wait) {
-                        DECLARE_WAITQUEUE(wait, current);
-
-                        /*
-                         * We need to wait for a free commandblock.  We need to
-                         * insert ourselves into the list before we release the
-                         * lock.  This way if a block were released the same
-                         * microsecond that we released the lock, the call
-                         * to schedule() wouldn't block (well, it might switch,
-                         * but the current task will still be schedulable.
-                         */
-                        add_wait_queue(&device->scpnt_wait, &wait);
-                        if( interruptable ) {
-                                set_current_state(TASK_INTERRUPTIBLE);
-                        } else {
-                                set_current_state(TASK_UNINTERRUPTIBLE);
-                        }
-
-                        spin_unlock_irqrestore(&device_request_lock, flags);
-
-			/*
-			 * This should block until a device command block
-			 * becomes available.
-			 */
-                        schedule();
-
-			spin_lock_irqsave(&device_request_lock, flags);
-
-                        remove_wait_queue(&device->scpnt_wait, &wait);
-                        /*
-                         * FIXME - Isn't this redundant??  Someone
-                         * else will have forced the state back to running.
-                         */
-                        set_current_state(TASK_RUNNING);
-                        /*
-                         * In the event that a signal has arrived that we need
-                         * to consider, then simply return NULL.  Everyone
-                         * that calls us should be prepared for this
-                         * possibility, and pass the appropriate code back
-                         * to the user.
-                         */
-                        if( interruptable ) {
-                                if (signal_pending(current)) {
-                                        spin_unlock_irqrestore(&device_request_lock, flags);
-                                        return NULL;
-                                }
-                        }
-		} else {
-                        spin_unlock_irqrestore(&device_request_lock, flags);
-			return NULL;
-		}
-	}
-
-	SCpnt->request = NULL;
-	atomic_inc(&SCpnt->host->host_active);
-	atomic_inc(&SCpnt->device->device_active);
-
-	SCpnt->buffer  = NULL;
-	SCpnt->bufflen = 0;
-	SCpnt->request_buffer = NULL;
-	SCpnt->request_bufflen = 0;
-
-	SCpnt->use_sg = 0;	/* Reset the scatter-gather flag */
-	SCpnt->old_use_sg = 0;
-	SCpnt->transfersize = 0;	/* No default transfer size */
-	SCpnt->cmd_len = 0;
+		add_wait_queue(&sdev->scpnt_wait, &wq);
+		set_current_state(TASK_UNINTERRUPTIBLE);
 
-	SCpnt->sc_data_direction = SCSI_DATA_UNKNOWN;
-	SCpnt->sc_request = NULL;
-	SCpnt->sc_magic = SCSI_CMND_MAGIC;
-
-        SCpnt->result = 0;
-	SCpnt->underflow = 0;	/* Do not flag underflow conditions */
-	SCpnt->old_underflow = 0;
-	SCpnt->resid = 0;
-	SCpnt->state = SCSI_STATE_INITIALIZING;
-	SCpnt->owner = SCSI_OWNER_HIGHLEVEL;
+		spin_unlock_irqrestore(&device_request_lock, flags);
+		schedule();
+		spin_lock_irqsave(&device_request_lock, flags);
+
+		remove_wait_queue(&sdev->scpnt_wait, &wq);
+		set_current_state(TASK_RUNNING);
+	}
+
+found:
+	scmnd->request = NULL;
+	atomic_inc(&scmnd->host->host_active);
+	atomic_inc(&scmnd->device->device_active);
+
+	scmnd->buffer  = NULL;
+	scmnd->bufflen = 0;
+	scmnd->request_buffer = NULL;
+	scmnd->request_bufflen = 0;
+
+	scmnd->use_sg = 0;	/* Reset the scatter-gather flag */
+	scmnd->old_use_sg = 0;
+	scmnd->transfersize = 0;	/* No default transfer size */
+	scmnd->cmd_len = 0;
+
+	scmnd->sc_data_direction = SCSI_DATA_UNKNOWN;
+	scmnd->sc_request = NULL;
+	scmnd->sc_magic = SCSI_CMND_MAGIC;
+
+	scmnd->result = 0;
+	scmnd->underflow = 0;	/* Do not flag underflow conditions */
+	scmnd->old_underflow = 0;
+	scmnd->resid = 0;
+	scmnd->state = SCSI_STATE_INITIALIZING;
+	scmnd->owner = SCSI_OWNER_HIGHLEVEL;
 
 	spin_unlock_irqrestore(&device_request_lock, flags);
 
 	SCSI_LOG_MLQUEUE(5, printk("Activating command for device %d (%d)\n",
-				   SCpnt->target,
-				atomic_read(&SCpnt->host->host_active)));
+				scmnd->target,
+				atomic_read(&scmnd->host->host_active)));
+
+	return scmnd;
 
-	return SCpnt;
+fail:
+	spin_unlock_irqrestore(&device_request_lock, flags);
+	return NULL;
 }
 
 inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
--- 1.44/drivers/scsi/scsi.h	Sun Nov 17 22:44:35 2002
+++ edited/drivers/scsi/scsi.h	Thu Nov 21 15:51:33 2002
@@ -471,7 +471,7 @@
 extern void scsi_done(Scsi_Cmnd * SCpnt);
 extern void scsi_finish_command(Scsi_Cmnd *);
 extern int scsi_retry_command(Scsi_Cmnd *);
-extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int);
+extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int);
 extern void __scsi_release_command(Scsi_Cmnd *);
 extern void scsi_release_command(Scsi_Cmnd *);
 extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
--- 1.50/drivers/scsi/scsi_lib.c	Wed Nov 20 09:33:50 2002
+++ edited/drivers/scsi/scsi_lib.c	Thu Nov 21 15:52:29 2002
@@ -797,8 +797,7 @@
 		SRpnt = (Scsi_Request *) req->special;
 		
 		if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) {
-			SCpnt = scsi_allocate_device(SRpnt->sr_device, 
-						     FALSE, FALSE);
+			SCpnt = scsi_allocate_device(SRpnt->sr_device, 0);
 			if (!SCpnt)
 				return BLKPREP_DEFER;
 			scsi_init_cmd_from_req(SCpnt, SRpnt);
@@ -809,9 +808,9 @@
 		 * Now try and find a command block that we can use.
 		 */
 		if (req->special) {
-				SCpnt = (Scsi_Cmnd *) req->special;
+			SCpnt = (Scsi_Cmnd *) req->special;
 		} else {
-			SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE);
+			SCpnt = scsi_allocate_device(SDpnt, 0);
 		}
 		/*
 		 * if command allocation failure, wait a bit

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

end of thread, other threads:[~2002-12-21  1:27 UTC | newest]

Thread overview: 297+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-04-08 15:18 [RFC] Persistent naming of scsi devices sullivan
2002-04-08 15:04 ` Christoph Hellwig
2002-04-08 15:59   ` Matthew Jacob
2002-04-08 16:34   ` James Bottomley
2002-04-08 18:27     ` Patrick Mansfield
2002-04-08 19:17       ` James Bottomley
2002-04-09  0:22         ` Douglas Gilbert
2002-04-09 14:35           ` sullivan
2002-04-09 14:55         ` sullivan
2002-04-08 17:51   ` Oliver Neukum
2002-04-08 18:01     ` Christoph Hellwig
2002-04-08 18:18     ` Matthew Jacob
2002-04-08 18:28       ` James Bottomley
2002-04-08 18:34         ` Matthew Jacob
2002-04-08 19:07           ` James Bottomley
2002-04-08 20:41             ` Matthew Jacob
2002-04-08 18:45   ` Tigran Aivazian
2002-04-08 20:18 ` Eddie Williams
2002-04-09  0:48 ` Kurt Garloff
  -- strict thread matches above, loose matches on Subject: below --
2002-04-08 16:11 Matt_Domsch
2002-04-08 19:18 Martin Peschke3
2002-04-08 20:45 ` Matthew Jacob
2002-04-10  1:16 ` Rick Stevens
2002-04-10  2:01   ` Matthew Jacob
2002-04-10  2:17   ` Linus Torvalds
2002-04-10  3:37   ` Martin K. Petersen
2002-04-10 13:19     ` Theodore Tso
2002-04-10 14:04       ` Eddie Williams
2002-04-10 17:45         ` Mike Anderson
2002-04-08 22:05 Martin Peschke3
2002-04-08 22:17 ` Matthew Jacob
2002-04-10  1:40 Bryan Henderson
2002-04-10 14:28 berthiaume_wayne
2002-04-10 14:36 berthiaume_wayne
2002-04-10 16:02 ` Matthew Jacob
2002-04-10 15:28 Bryan Henderson
2002-04-10 15:52 Martin Peschke3
2002-04-10 19:33 ` Matthew Jacob
2002-04-10 16:44 berthiaume_wayne
2002-04-10 19:02 Martin Peschke3
2002-04-10 20:24 berthiaume_wayne
2002-04-11 16:01 Bryan Henderson
2002-04-12 13:15 berthiaume_wayne
2002-04-12 17:18 Bryan Henderson
2002-04-12 18:03 berthiaume_wayne
2002-06-05 20:13 sullivan
2002-06-06  1:08 ` Douglas Gilbert
2002-06-11  2:46 Proposed changes to generic blk tag for use in SCSI (1/3) James Bottomley
2002-06-11  5:50 ` Jens Axboe
2002-06-11 14:29   ` James Bottomley
2002-06-11 14:45     ` Jens Axboe
2002-06-11 16:39       ` James Bottomley
2002-06-13 21:01 ` Doug Ledford
2002-06-13 21:26   ` James Bottomley
     [not found] <200206132126.g5DLQiQ24889@localhost.localdomain>
2002-06-13 21:50 ` Doug Ledford
2002-06-13 22:09   ` James Bottomley
2002-08-05 23:53 When must the io_request_lock be held? Jamie Wellnitz
2002-08-06 17:58 ` Mukul Kotwani
2002-08-07 14:48 ` Doug Ledford
2002-08-07 15:26   ` James Bottomley
2002-08-07 16:18     ` Doug Ledford
2002-08-07 16:48       ` James Bottomley
2002-08-07 18:06         ` Mike Anderson
2002-08-07 23:17           ` James Bottomley
2002-08-08 19:28         ` Luben Tuikov
2002-08-07 16:55       ` Patrick Mansfield
2002-08-12 23:38 [PATCH] 2.5.31 scsi_error.c cleanup Mike Anderson
2002-08-22 14:05 ` James Bottomley
2002-08-22 16:34   ` Mike Anderson
2002-08-22 17:11     ` James Bottomley
2002-08-22 20:10       ` Mike Anderson
2002-08-26 16:29 [RFC]: 64 bit LUN/Tags, dummy device in host_queue, host_lock <-> LLDD reentrancy Aron Zeh
2002-08-26 16:48 ` James Bottomley
2002-08-26 17:27   ` Mike Anderson
2002-08-26 19:00     ` James Bottomley
2002-08-26 20:57       ` Mike Anderson
2002-08-26 21:10         ` James Bottomley
2002-08-26 22:38           ` Mike Anderson
2002-08-26 22:56             ` Patrick Mansfield
2002-08-26 23:10             ` Doug Ledford
2002-08-28 14:38             ` James Bottomley
2002-08-26 21:15         ` Mike Anderson
2002-09-03 14:35 aic7xxx sets CDR offline, how to reset? James Bottomley
2002-09-03 18:23 ` Doug Ledford
2002-09-03 19:09   ` James Bottomley
2002-09-03 20:59     ` Alan Cox
2002-09-03 21:32       ` James Bottomley
2002-09-03 21:54         ` Alan Cox
2002-09-03 22:50         ` Doug Ledford
2002-09-03 23:28           ` Alan Cox
2002-09-04  7:40           ` Jeremy Higdon
2002-09-04 16:24             ` James Bottomley
2002-09-04 17:13               ` Mike Anderson
2002-09-05  9:50               ` Jeremy Higdon
2002-09-04 16:13           ` James Bottomley
2002-09-04 16:50             ` Justin T. Gibbs
2002-09-05  9:39               ` Jeremy Higdon
2002-09-05 13:35                 ` Justin T. Gibbs
2002-09-05 23:56                   ` Jeremy Higdon
2002-09-06  0:13                     ` Justin T. Gibbs
2002-09-06  0:32                       ` Jeremy Higdon
2002-09-03 21:13     ` Doug Ledford
2002-09-03 21:48       ` James Bottomley
2002-09-03 22:42         ` Doug Ledford
2002-09-03 22:52           ` Doug Ledford
2002-09-03 23:29           ` Alan Cox
2002-09-04 21:16           ` Luben Tuikov
2002-09-04 10:37         ` Andries Brouwer
2002-09-04 10:48           ` Doug Ledford
2002-09-04 11:23           ` Alan Cox
2002-09-04 16:25             ` Rogier Wolff
2002-09-04 19:34               ` Thunder from the hill
2002-09-03 21:24     ` Patrick Mansfield
2002-09-03 22:02       ` James Bottomley
2002-09-03 23:26         ` Alan Cox
     [not found] <200209091458.g89Evv806056@localhost.localdomain>
2002-09-09 16:56 ` [RFC] Multi-path IO in 2.5/2.6 ? Patrick Mansfield
2002-09-09 17:34   ` James Bottomley
2002-09-09 18:40     ` Mike Anderson
2002-09-10 13:02       ` Lars Marowsky-Bree
2002-09-10 16:03         ` Patrick Mansfield
2002-09-10 16:27         ` Mike Anderson
2002-09-10  0:08     ` Patrick Mansfield
2002-09-10  7:55       ` Jeremy Higdon
2002-09-10 13:04         ` Lars Marowsky-Bree
2002-09-10 16:20           ` Patrick Mansfield
2002-09-10 13:16       ` Lars Marowsky-Bree
2002-09-10 19:26         ` Patrick Mansfield
2002-09-11 14:20           ` James Bottomley
2002-09-11 19:17             ` Lars Marowsky-Bree
2002-09-11 19:37               ` James Bottomley
2002-09-11 19:52                 ` Lars Marowsky-Bree
2002-09-11 21:38                 ` Oliver Xymoron
2002-09-11 20:30             ` Doug Ledford
2002-09-11 21:17               ` Mike Anderson
2002-09-10 17:21       ` Patrick Mochel
2002-09-10 18:42         ` Patrick Mansfield
2002-09-10 19:00           ` Patrick Mochel
2002-09-10 19:37             ` Patrick Mansfield
2002-09-24 11:35 SCSI woes (followup) Russell King
2002-09-24 13:46 ` James Bottomley
2002-09-24 13:58   ` Russell King
2002-09-24 14:29     ` James Bottomley
2002-09-24 18:16       ` Luben Tuikov
2002-09-24 18:18     ` Patrick Mansfield
2002-09-24 19:01       ` Russell King
2002-09-24 19:08       ` Mike Anderson
2002-09-24 19:21         ` Russell King
2002-09-24 19:32       ` Patrick Mansfield
2002-09-24 20:00         ` Russell King
2002-09-24 22:23           ` Patrick Mansfield
2002-09-24 23:04             ` Russell King
2002-09-24 22:39         ` Russell King
2002-09-24 23:14           ` James Bottomley
2002-09-24 23:26             ` Mike Anderson
2002-09-24 23:31               ` James Bottomley
2002-09-24 23:56                 ` Mike Anderson
2002-09-24 23:33               ` Russell King
2002-09-25  0:47                 ` Mike Anderson
2002-09-25  8:45                   ` Russell King
2002-09-25  2:18                 ` Doug Ledford
2002-09-25 14:41               ` Russell King
2002-09-24 23:33           ` Mike Anderson
2002-09-24 23:45             ` Russell King
2002-09-25  0:08           ` Patrick Mansfield
2002-09-25  8:41             ` Russell King
2002-09-25 17:22               ` Patrick Mansfield
2002-09-25 12:46             ` Russell King
2002-09-24 17:57   ` Luben Tuikov
2002-09-24 18:39     ` Mike Anderson
2002-09-24 18:49       ` Luben Tuikov
2002-09-30 21:06 [PATCH] first cut at fixing unable to requeue with no outstanding commands James Bottomley
2002-09-30 23:28 ` Mike Anderson
2002-10-01  0:38   ` James Bottomley
2002-10-01 15:01     ` Patrick Mansfield
2002-10-01 15:14       ` James Bottomley
2002-10-01 16:23         ` Mike Anderson
2002-10-01 16:30           ` James Bottomley
2002-10-01 20:18         ` Inhibit auto-attach of scsi disks ? Scott Merritt
2002-10-02  0:46           ` Alan Cox
2002-10-02  1:49             ` Scott Merritt
2002-10-02  1:58               ` Doug Ledford
2002-10-02  2:45                 ` Scott Merritt
2002-10-02 13:40               ` Alan Cox
2002-10-10 15:01 [PATCH] scsi host cleanup 3/3 (driver changes) Stephen Cameron
2002-10-10 16:46 ` Mike Anderson
2002-10-10 16:59   ` James Bottomley
2002-10-10 20:05     ` Mike Anderson
     [not found] <patmans@us.ibm.com>
2002-10-15 16:55 ` [RFC PATCH] consolidate SCSI-2 command lun setting Patrick Mansfield
2002-10-15 20:29   ` James Bottomley
2002-10-15 22:00     ` Patrick Mansfield
2002-10-30 16:58 ` [PATCH] 2.5 current bk fix setting scsi queue depths Patrick Mansfield
2002-10-30 17:17   ` James Bottomley
2002-10-30 18:05     ` Patrick Mansfield
2002-10-31  0:44       ` James Bottomley
2002-10-15 18:55 [patch 2.5] ips " Jeffery, David
2002-10-15 19:30 ` Dave Hansen
2002-10-15 19:47 ` Doug Ledford
2002-10-15 20:04   ` Patrick Mansfield
2002-10-15 20:52     ` Doug Ledford
2002-10-15 23:30       ` Patrick Mansfield
2002-10-15 23:56         ` Luben Tuikov
2002-10-16  2:32         ` Doug Ledford
2002-10-16 19:04           ` Patrick Mansfield
2002-10-16 20:15             ` Doug Ledford
2002-10-17  0:39             ` Luben Tuikov
2002-10-17 17:01               ` Mike Anderson
2002-10-17 21:13                 ` Luben Tuikov
2002-10-15 20:10   ` Mike Anderson
2002-10-15 20:24     ` Doug Ledford
2002-10-15 20:38     ` James Bottomley
2002-10-15 22:10       ` Mike Anderson
2002-10-16  1:04         ` James Bottomley
2002-10-15 20:24   ` Mike Anderson
2002-10-15 22:46     ` Doug Ledford
2002-10-15 20:26   ` Luben Tuikov
2002-10-15 21:27     ` Patrick Mansfield
2002-10-16  0:43       ` Luben Tuikov
2002-10-21  7:28   ` Mike Anderson
2002-10-21 16:16     ` Doug Ledford
2002-10-21 16:29       ` James Bottomley
     [not found] <dledford@redhat.com>
2002-10-02  0:28 ` PATCH: scsi device queue depth adjustability patch Doug Ledford
2002-10-02  1:16   ` Alan Cox
2002-10-02  1:41     ` Doug Ledford
2002-10-02 13:44       ` Alan Cox
2002-10-02 21:41   ` James Bottomley
2002-10-02 22:18     ` Doug Ledford
2002-10-02 23:19       ` James Bottomley
2002-10-03 12:46       ` James Bottomley
2002-10-03 16:35         ` Doug Ledford
2002-10-04  1:40         ` Jeremy Higdon
2002-10-03 14:25   ` James Bottomley
2002-10-03 16:41     ` Doug Ledford
2002-10-03 17:00       ` James Bottomley
2002-10-16 21:35 ` scsi_scan.c question Doug Ledford
2002-10-16 21:41   ` James Bottomley
2002-10-17  0:18     ` Doug Ledford
2002-10-16 21:57   ` Patrick Mansfield
2002-10-18 15:57     ` Patrick Mansfield
2002-11-18  0:27 ` aic7xxx_biosparam Doug Ledford
2002-11-18  0:36   ` aic7xxx_biosparam J.E.J. Bottomley
2002-11-18  2:46     ` aic7xxx_biosparam Doug Ledford
2002-11-18  3:20       ` aic7xxx_biosparam J.E.J. Bottomley
2002-11-18  3:26         ` aic7xxx_biosparam Doug Ledford
2002-11-18  0:43   ` aic7xxx_biosparam Andries Brouwer
2002-11-18  2:47     ` aic7xxx_biosparam Doug Ledford
2002-11-18  0:57   ` aic7xxx_biosparam Alan Cox
2002-11-18  2:34     ` aic7xxx_biosparam Doug Ledford
2002-12-21  1:22 ` scsi_scan changes Doug Ledford
2002-12-21  1:27   ` James Bottomley
2002-10-21 19:34 [PATCH] get rid of ->finish method for highlevel drivers Christoph Hellwig
2002-10-21 23:58 ` James Bottomley
2002-10-22 15:48   ` James Bottomley
2002-10-22 18:43     ` Patrick Mansfield
2002-10-22 23:17       ` Mike Anderson
2002-10-22 23:30         ` Doug Ledford
2002-10-23 14:16           ` James Bottomley
2002-10-23 15:13             ` Christoph Hellwig
2002-10-24  1:36               ` Patrick Mansfield
2002-10-24 23:20               ` Willem Riede
2002-10-24 23:36                 ` Christoph Hellwig
2002-10-25  0:02                   ` Willem Riede
2002-10-22  7:30 ` Mike Anderson
2002-10-22 11:14   ` Christoph Hellwig
2002-11-06  4:24 [PATCH] fix 2.5 scsi queue depth setting Patrick Mansfield
2002-11-06  4:35 ` Patrick Mansfield
2002-11-06 17:15 ` J.E.J. Bottomley
2002-11-06 17:47 ` J.E.J. Bottomley
2002-11-06 18:24   ` Patrick Mansfield
2002-11-06 18:32     ` J.E.J. Bottomley
2002-11-06 18:39       ` Patrick Mansfield
2002-11-06 18:50         ` J.E.J. Bottomley
2002-11-06 19:50           ` Patrick Mansfield
2002-11-06 20:45     ` Doug Ledford
2002-11-06 21:19       ` J.E.J. Bottomley
2002-11-06 20:50 ` Doug Ledford
2002-11-06 22:18 [PATCH] add request prep functions to SCSI J.E.J. Bottomley
2002-11-06 23:16 ` Doug Ledford
2002-11-06 23:43   ` J.E.J. Bottomley
2002-11-07 21:45 ` Mike Anderson
2002-11-15 20:34 [RFC][PATCH] move dma_mask into struct device J.E.J. Bottomley
2002-11-16  0:19 ` Mike Anderson
2002-11-16 14:48   ` J.E.J. Bottomley
2002-11-16 20:33 ` Patrick Mansfield
2002-11-17 15:07   ` J.E.J. Bottomley
2002-11-16 19:40 [PATCH] removel useless mod use count manipulation Christoph Hellwig
2002-11-17  2:59 ` Doug Ledford
2002-11-17 17:31   ` J.E.J. Bottomley
2002-11-17 18:14     ` Doug Ledford
2002-11-17 12:40 ` Douglas Gilbert
2002-11-17 12:48   ` Christoph Hellwig
2002-11-17 13:38     ` Douglas Gilbert
2002-11-21 15:16 [PATCH] turn scsi_allocate_device into readable code Christoph Hellwig
2002-11-21 15:36 ` Doug Ledford
2002-11-21 15:39   ` J.E.J. Bottomley
2002-11-21 15:49     ` Doug Ledford
2002-11-21 16:12       ` J.E.J. Bottomley
2002-11-21 17:08         ` [PATCH] current scsi-misc-2.5 include files Patrick Mansfield

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).