Commit Graph

66 Commits

Author SHA1 Message Date
Joe Eykholt
0685230c59 [SCSI] libfc: add discovery-private pointer for LLD
For VN_port to VN_port mode, FIP will do discovery and needs a
way to find its state from the local port or discovery structure.
It seems that any other LLD that implements its own discovery
would also need something like this.

Replace disc->lport with disc->priv, and use container_of to
find the lport.  We could use disc->priv for that, but
container_of is smaller and faster.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-07-28 09:05:52 -05:00
Joe Eykholt
f90377abca [SCSI] libfc: provide space for LLD after remote port structure
Add pre-zeroed space after the allocation for fc_rport_priv
for use by the lower-level driver.

This is primarily for VN2VN FIP mode, but could be used in
other ways someday.

The space required is specified in lport->rport_priv_size.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-07-28 09:05:49 -05:00
Joe Eykholt
42e9041467 [SCSI] libfc: convert rport lookup to be RCU safe
To allow LLD to do lookups on rports without grabbing a mutex,
make them RCU-safe.  The caller of lport->tt.rport_lookup will
have the choice of holding disc_mutex or the rcu_read_lock().

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-07-28 09:05:48 -05:00
Joe Eykholt
f034260db3 [SCSI] libfc: fix indefinite rport restart
Remote ports were restarting indefinitely after getting
rejects in PRLI.

Fix by adding a counter of restarts and limiting that with
the port login retry limit as well.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-07-27 12:01:53 -05:00
Joe Eykholt
4b2164d4d2 [SCSI] libfc: Fix remote port restart problem
This patch somewhat combines two fixes to remote port handing in libfc.

The first problem was that rport work could be queued on a deleted
and freed rport.  This is handled by not resetting rdata->event
ton NONE if the rdata is about to be deleted.

However, that fix led to the second problem, described by
Bhanu Gollapudi, as follows:
> Here is the sequence of events. T1 is first LOGO receive thread, T2 is
> fc_rport_work() scheduled by T1 and T3 is second LOGO receive thread and
> T4 is fc_rport_work scheduled by T3.
>
> 1. (T1)Received 1st LOGO in state Ready
> 2. (T1)Delete port & enter to RESTART state.
> 3. (T1)schdule event_work, since event is RPORT_EV_NONE.
> 4. (T1)set event = RPORT_EV_LOGO
> 5. (T1)Enter RESTART state as disc_id is set.
> 6. (T2)remember to PLOGI, and set event = RPORT_EV_NONE
> 6. (T3)Received 2nd LOGO
> 7. (T3)Delete Port & enter to RESTART state.
> 8. (T3)schedule event_work, since event is RPORT_EV_NONE.
> 9. (T3)Enter RESTART state as disc_id is set.
> 9. (T3)set event = RPORT_EV_LOGO
> 10.(T2)work restart, enter PLOGI state and issues PLOGI
> 11.(T4)Since state is not RESTART anymore, restart is not set, and the
> event is not reset to RPORT_EV_NONE. (current event is RPORT_EV_LOGO).
> 12. Now, PLOGI succeeds and fc_rport_enter_ready() will not schedule
> event_work, and hence the rport will never be created, eventually losing
> the target after dev_loss_tmo.

So, the problem here is that we were tracking the desire for
the rport be restarted by state RESTART, which was otherwise
equivalent to DELETE.  A contributing factor is that we dropped
the lock between steps 6 and 10 in thread T2, which allows the
state to change, and we didn't completely re-evaluate then.

This is hopefully corrected by the following minor redesign:

Simplify the rport restart logic by making the decision to
restart after deleting the transport rport.  That decision
is based on a new STARTED flag that indicates fc_rport_login()
has been called and fc_rport_logoff() has not been called
since then.  This replaces the need for the RESTART state.

Only restart if the rdata is still in DELETED state
and only if it still has the STARTED flag set.

Also now, since we clear the event code much later in the
work thread, allow for the possibility that the rport may
have become READY again via incoming PLOGI, and if so,
queue another event to handle that.

In the problem scenario, the second LOGO received will
cause the LOGO event to occur again.

Reported-by: Bhanu Gollapudi <bprakash@broadcom.com>
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-07-27 12:01:52 -05:00
Robert Love
7b2787ec15 [SCSI] libfc: Move the port_id into lport
This patch creates a port_id member in struct fc_lport.
This allows libfc to just deal with fc_lport instances
instead of calling into the fc_host to get the port_id.

This change helps in only using symbols necessary for
operation from the libfc structures. libfc still needs
to change the fc_host_port_id() if the port_id changes
so the presentation layer (scsi_transport_fc) can provide
the user with the correct value, but libfc shouldn't
rely on the presentation layer for operational values.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-05-16 22:22:34 -04:00
Robert Love
1b80e0f91c [SCSI] libfc: Remove unused fc_get_host_port_type
Remove this unused routine.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-05-16 22:22:29 -04:00
Joe Eykholt
0b2f74a47f [SCSI] libfc: fix hton24 macro to take expressions as args
hton24(p + 3, value) would fail to compile because
p + 3[0] is not a valid expression.

Went ahead and converted hton24 and ntoh24 to inline
functions, which is better because the parameters
are evalutated only once.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-04-11 14:02:34 -05:00
Joe Eykholt
f018b73af6 [SCSI] libfc, libfcoe, fcoe: use smp_processor_id() only when preempt disabled
When the kernel is configured for preemption, using smp_processor_id()
when preemption is enabled causes a warning backtrace and is wrong
since we could move off of that CPU as soon as we get the ID,
and we would be referencing the wrong CPU, and possibly an invalid one
if it could be hotswapped out.

Remove the fc_lport_get_stats() function and explicitly use per_cpu_ptr()
to get the statistics.  Where preemption has been disabled by holding
a _bh lock continue to use smp_processor_id(), but otherwise use
get_cpu()/put_cpu().

In fcoe_recv_frame() also changed the cases where we return in the
middle to do a goto to the code which bumps ErrorFrames and does
a put_cpu().  Two of these cases didn't bump ErrorFrames before, but
doing so is harmless because they "can't happen", due to prior length
checks.

Also rearranged code in fcoe_recv_frame() to have only one call to
fc_exch_recv().  It's just as efficient and saves a call to put_cpu().

In fc_fcp.c, adjusted a FIXME comment for code which doesn't need fixing.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-04-11 09:23:44 -05:00
Yi Zou
b84056bf68 [SCSI] fcoe, libfc: add get_lesb() to allow LLD to fill the link error status block (LESB)
Add a member function pointer as get_lesb to libfc_function_template so LLD
can fill the LESB based on its own statistics. For fcoe, it fills the LESB
as a fcoe_fc_els_lesb struct according to FC-BB-5.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:58 -06:00
Yi Zou
6580bbd0af [SCSI] libfc: add FC-BB-5 LESB counters to fcoe_dev_stats
FC-BB-5 Rev2.0, Clause 7.10 extends the FC-LS-3 LESB for FC-BB_E. We are
already tracking Link Failure Count so add the rest in this patch.

For VLinkFailureCount and MissDiscAdvCount, they are part of the per-cpu
fcoe_dev_stats. For SymbolErrorCount, ErroredBlockCount, and FCSErrorCount,
they are defined in IEEE 802.3-2008 and are per LLD. They are expected to
come from LLD.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:55 -06:00
Joe Eykholt
ab593b1873 [SCSI] libfc: register FC4 features with the FC switch
Customers and certification tests have pointed out that we don't
show up on the switch management software as an initiator.

On some MDS switches 'show fcns database' command shows libfc
initiators as 'fcp' not 'fcp:init' like other initiators.

On others switches, I think the switch gets the features by doing a PRLI,
but it may be only certain models or under certain configurations.

Fix this by registering our FC4 features with the RFF_ID CT request
after local port login and after the RFT_ID.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:20 -06:00
Joe Eykholt
093bb6a2d3 [SCSI] libfc: add set_fid function to libfc template
This is to notify the LLD when an FC_ID is assigned to the local port.

The fnic driver needs to push the assigned FC_ID to firmware.
It currently does this by intercepting the FLOGI responses, and
in order to make that code more common with FIP and NPIV, it
makes more sense to wait until the local port has completely
handled the FLOGI or FDISC response.  Also, when we fix
point-to-point FC_ID assignment, we'll need this callback as well.

Add a call to the libfc template, which is called whenever
the local port FC_ID is being assigned.  It defaults to
fc_lport_set_fid(), supplied by libfc.

As additional benefit of this function, the LLD may determine
the MAC address that caused the change by looking at the received frame.

We also print the assigned port ID as long as it isn't 0.
Setting port ID to 0 happens often in reset while retrying FLOGI,
and would be uninteresting.  This replaces the previous message
which didn't identify the host adapter instance.

patch v2 note: changed one word in a comment.  "intercepted" -> "provided".

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:17 -06:00
Robert Love
3a3b42bf89 [SCSI] libfc: Formatting cleanups across libfc
This patch makes a variety of cleanup changes to all libfc files.

This patch adds kernel-doc headers to all functions lacking them
and attempts to better format existing headers. It also add kernel-doc
headers to structures.

This patch ensures that the current naming conventions for local ports,
remote ports and remote port private data is upheld in the following
manner.

struct               instance (i.e. variable name)
--------------------------------------------------
fc_lport                      lport
fc_rport                      rport
fc_rport_libfc_priv           rpriv
fc_rport_priv                 rdata

I also renamed dns_rp and ptp_rp to dns_rdata and ptp_rdata
respectively.

I used emacs 'indent-region' and 'tabify' on all libfc files
to correct spacing alignments.

I feel sorry for anyone attempting to review this patch.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:07 -06:00
Steve Ma
a51ab39606 [SCSI] libfc, fcoe: Add FC passthrough support
This is the Open-FCoE implementation of the FC
passthrough support via bsg interface.

Passthrough support is added to both N_Ports and
VN_Ports.

Signed-off-by: Steve Ma <steve.ma@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:06 -06:00
Chris Leech
c9866a5480 [SCSI] libfc: Register Symbolic Port Name (RSPN_ID)
Register the fc_host symbolic name as the symbolic port name
with the fabric name server.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:02 -06:00
Chris Leech
5baa17c3e6 [SCSI] libfc: Register Symbolic Node Name (RSNN_NN)
Register the fc_host symbolic name as the symbolic node name
with the fabric name server.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:02 -06:00
Chris Leech
c9c7bd7a5e [SCSI] libfc: RNN_ID may be required before RSNN_NN with some switches
One could interpret FC-GS-5 to say that an explicit RNN_ID is required
before RSNN_NN is allowed to succeed, which is why RNN_ID was not obsoleted
along with RPN_ID acording to this document:
ftp://ftp.t11.org/t11/member/fc/gs-5/05-546v2.pdf

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:01 -06:00
Chris Leech
28cc0e31d8 [SCSI] libfc: RPN_ID is obsolete and unnecessary
RPN_ID has been obsolete per FC-GS-5 for several years.  The port name is
registered implicitly as part of FLOGI, and it is undesirable for ports to
change a registered port name using RPN_ID while logged into the fabric.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:01:00 -06:00
Chris Leech
11b5618866 [SCSI] libfcoe, fcoe: libfcoe NPIV support
The FIP code in libfcoe needed several changes to support NPIV

1) dst_src_addr needs to be managed per-n_port-ID for FPMA fabrics with NPIV
   enabled.  Managing the MAC address is now handled in fcoe, with some slight
   changes to update_mac() and a new get_src_addr() function pointer.

2) The libfc elsct_send() hook is used to setup FCoE specific response
   handlers for FIP encapsulated ELS exchanges.  This lets the FCoE specific
   handling know which VN_Port the exchange is for, and doesn't require
   tracking OX_IDs.  It might be possible to roll back to the full FIP frame
   in these, but for now I've just stashed the contents of the MAC address
   descriptor in the skb context block for later use.  Also, because
   fcoe_elsct_send() just passes control on to fc_elsct_send(), all transmits
   still come through the normal frame_send() path.

3) The NPIV changes added a mutex hold in the keep alive sending, the lport
   mutex is protecting the vport list.  We can't take a mutex from a timer,
   so move the FIP keep alive logic to the link work struct.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:58 -06:00
Chris Leech
8faecddb21 [SCSI] libfc: vport link handling and fc_vport state managment
NPIV vports are managed in libfc by changing their virtual link state
when the parent N_Ports internal state changes.  The vport link is only
online when the N_Port is in a ready state (logged into the fabric).

vport_state is updated as needed in this patch as well, currently the states
LINKDOWN, INITIALIZING, ACTIVE, DSIABLED, and NO_FABRIC_SUPP are used.

This also changes the fc_host port_state handling to differentiate between
LINKDOWN and OFFLINE.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:57 -06:00
Chris Leech
174e1ebffd [SCSI] libfc: add some generic NPIV support routines to libfc
Adds a function to create a new VN_Port instances, which share the EM
list with the N_Port, VN_Port lookup by fabric ID when responding to a new
request (otherwise the exchange lookup from the N_Ports EM list is trusted to
return an exchange with a cached lport value for the correct VN_Port),
a pointer to a fc_vport structure for VN_Ports, and flags to indicate if an
N_Port supports NPIV and if the switch/fabric allows it.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:56 -06:00
Chris Leech
86221969e2 [SCSI] libfc: changes to libfc_host_alloc to consolidate initialization with allocation
I'd like to keep basic initialization together with allocation, which means
this can't just be a tail-call to scsi_host_alloc.

This is needed to create a generic libfc host allocation routine for NPIV
VN_Ports, which will share the exchange ID space (through sharing exchange
manager structures) with the parent lport.  In order to clone the exchange
manager list when the lport is allocated, the list head must be initialized
earlier.

Also, update fnic to use the libfc_host_alloc so that later changes do not break
it. (contribution by Joe Eykholt)

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:56 -06:00
Robert Love
8866a5d907 [SCSI] libfc: Add libfc/fc_libfc.[ch] for libfc internal routines
include/scsi/libfc.h is currently loaded with common code
shared between libfc's sub-modules as well as shared between
libfc and fcoe. Previous patches attempted to move out
non-common code. This patch creates two files for common
libfc routines that will not be shared with fcoe, fnic or
any other LLDs.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:55 -06:00
Robert Love
255f6386b8 [SCSI] libfc: Remove fc_fcp_complete
This function is never used, let's remove it.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:54 -06:00
Robert Love
1a7b75ae71 [SCSI] libfc: Move non-common routines and prototypes out of libfc.h
This patch moves all non-common routines and function prototypes
out of libfc.h and into the appropriate .c files. It makes these
routines 'static' when necessary and removes any unnecessary EXPORT_SYMBOL
statements.

A result of moving the fc_exch_seq_send, fc_seq_els_rsp_send, fc_exch_alloc
and fc_seq_start_next prototypes out of libfc.h is that they were no longer
being imported into fc_exch.c when libfc.h was included. This caused errors
where routines in fc_exch.c were looking for undefined symbols. To fix this
this patch reorganizes fc_seq_alloc, fc_seq_start_next and
fc_seq_start_next_locked. This move also made it so that
fc_seq_start_next_locked did not need to be prototyped at the top of
fc_exch.c.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:53 -06:00
Mike Christie
e881a172da [SCSI] modify change_queue_depth to take in reason why it is being called
This patch modifies scsi_host_template->change_queue_depth so that
it takes an argument indicating why it is being called. This will be
used so that if a LLD needs to do some extra processing when
handling queue fulls or later ramp ups, it can do so.

This is a simple port of the drivers setting a change_queue_depth
callback. In the patch I just have these LLDs adjust the queue depth
if the user was requesting it.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>

[Vasu.Dev: v2
	Also converted pmcraid_change_queue_depth and then verified
all modules compile  using "make allmodconfig" for any new build
warnings on X86_64.

	Updated original description after combing two original
patches from Mike to make this patch git bisectable.]
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
[jejb: fixed up 53c700]
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:41 -06:00
Joe Eykholt
b4a9c7ede9 [SCSI] libfc: fix free of fc_rport_priv with timer pending
Timer crashes were caused by freeing a struct fc_rport_priv
with a timer pending, causing the timer facility list to be
corrupted.  This was during FC uplink flap tests with a lot
of targets.

After discovery, we were doing an PLOGI on an rdata that was
in DELETE state but not yet removed from the lookup list.
This moved the rdata from DELETE state to PLOGI state.
If the PLOGI exchange allocation failed and needed to be
retried, the timer scheduling could race with the free
being done by fc_rport_work().

When fc_rport_login() is called on a rport in DELETE state,
move it to a new state RESTART.  In fc_rport_work, when
handling a LOGO, STOPPED or FAILED event, look for restart
state.  In the RESTART case, don't take the rdata off the
list and after the transport remote port is deleted and
exchanges are reset, re-login to the remote port.

Note that the new RESTART state also corrects a problem we
had when re-discovering a port that had moved to DELETE state.
In that case, a new rdata was created, but the old rdata
would do an exchange manager reset affecting the FC_ID
for both the new rdata and old rdata.  With the new state,
the new port isn't logged into until after any old exchanges
are reset.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:37 -06:00
Vasu Dev
e95147d8fa [SCSI] libfc: removes unused disc_work and ex_list
Reported-by: Alex Lyakas <alexl@mellanox.co.il>
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-12-04 12:00:31 -06:00
Joe Eykholt
370c3bd05c [SCSI] libfc: use ADISC to verify rport login state
When rport_login is called on an rport that is already thought
to be logged in, use ADISC.  If that fails, redo PLOGI.
This is less disruptive after fabric changes that don't affect
the state of the target.

Implement the sending of ADISC via fc_els_fill.

Add ADISC state to the rport state machine.  This is entered from READY
and returns to READY after successful completion.  If it fails, the rport
is either logged off and deleted or re-does PLOGI.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:08:02 -05:00
Joe Eykholt
f657d299cf [SCSI] libfc: improve debug messages for ELS response handlers
Improve lport and rport debug messages to indicate whether
the response is LS_ACC, LS_RJT, closed, or timeout.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:59 -05:00
Joe Eykholt
131203a1ef [SCSI] libfc: move remote port lookup for ELS requests into fc_rport.c.
This moves the remote port lookup for incoming ELS requests into
fc_rport.c, in preparation for handing PLOGI and LOGO from
unknown rports.

This changes the arg to rport_recv_req from an rdata to an lport.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:58 -05:00
Robert Love
9737e6a7b5 [SCSI] libfc: Initialize fc_rport_identifiers inside fc_rport_create
Currently these values are initialized by the callers. This was exposed
by a later patch that adds PLOGI request support. The patch failed to
initialize the new remote port's roles and it caused problems. This patch
has the rport_create routine initialize the identifiers and then the
callers can override them with real values.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:57 -05:00
Joe Eykholt
0f6c614987 [SCSI] libfc: do not log off rports before or after discovery
When receiving an RSCN, do not log off all rports.  This is
extremely disruptive.  If, after the GPN_FT response, some
rports haven't been listed, delete them.

Add field disc_id to structs fc_rport_priv and fc_disc.
disc_id is an arbitrary serial number used to identify the
rports found by the latest discovery.  This eliminates the need
to go through the rport list when restarting discovery.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:48 -05:00
Joe Eykholt
b84c796265 [SCSI] libfc: remove unused disc->delay element
Delete unused disc->delay element.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:45 -05:00
Joe Eykholt
786681b96f [SCSI] libfc: eliminate disc->event
There was no need to have the discovery status stored in struct fc_disc.

Change fc_disc_done() to take the discovery status as an argument
and just pass it on to the discovery callback.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:44 -05:00
Joe Eykholt
9e9d0452fe [SCSI] libfc: don't create dummy (rogue) remote ports
Don't create a "dummy" remote port to go with fc_rport_priv.

Make the rport truly optional by allocating fc_rport_priv separately
and not requiring a dummy rport to be there if we haven't yet done
fc_remote_port_add().

The fc_rport_libfc_priv remains as a structure attached to the
rport for I/O purposes.

Be sure to hold references on rdata when the lock is dropped in
fc_rport_work().

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:43 -05:00
Joe Eykholt
4c0f62b567 [SCSI] libfc: rename rport event CREATED to READY
Remote ports will become READY more than once after
ADISC is implemented in a later patch.

The event callback that has been called "CREATED" will mean "READY".
Rename it now in preparation for those changes.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:43 -05:00
Joe Eykholt
f211fa514a [SCSI] libfc: make rport structure optional
Allow a struct fc_rport_priv to have no fc_rport associated with it.
This sets up to remove the need for "rogue" rports.

Add a few fields to fc_rport_priv that are needed before the fc_rport
is created.  These are the ids, maxframe_size, classes, and rport pointer.

Remove the macro PRIV_TO_RPORT().  Just use rdata->rport where appropriate.

To take the place of the get_device()/put_device ops that were used to
hold both the rport and rdata, add a reference count to rdata structures
using kref.  When kref_get decrements the refcount to zero, a new template
function releasing the rdata should be called.  This will take care of
freeing the rdata and releasing the hold on the rport (for now).  After
subsequent patches make the rport truly optional, this release function
will simply free the rdata.

Remove the simple inline function fc_rport_set_name(), which becomes
semanticly ambiguous otherwise.  The caller will set the port_name and
node_name in the rdata->Ids, which will later be copied to the rport
when it its created.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:42 -05:00
Joe Eykholt
a46f327aa5 [SCSI] libfc: change elsct to use FC_ID instead of rdata
tt.elsct_send is used by both FCP and by the rport state machine.
After further patches, these two modules will use different
structures for the remote port.

So, change elsct_send to use the FC_ID instead of the fc_rport_priv
as its argument.  It currently only uses the FC_ID anyway.

For CT requests the destination FC_ID is still implicitly 0xfffffc.
After further patches the did arg on CT requests will be used to
specify the FC_ID being inquired about for GPN_ID or other queries.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:41 -05:00
Joe Eykholt
9fb9d32831 [SCSI] libfc: make fc_rport_priv the primary rport interface.
The rport and discovery modules deal with remote ports
before fc_remote_port_add() can be done, because the
full set of rport identifiers is not known at early stages.

In preparation for splitting the fc_rport/fc_rport_priv allocation,
make fc_rport_priv the primary interface for the remote port and
discovery engines.

The FCP / SCSI layers still deal with fc_rport and
fc_rport_libfc_priv, however.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:41 -05:00
Joe Eykholt
922aa210bc [SCSI] libfc: fix RPORT_TO_PRIV and PRIV_TO_RPORT() macros.
These macros introduce extra undesirable semicolons that keep
them from being used in expressions, and they don't protect
against being passed an expression.

Add parens and remove the semicolons.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:40 -05:00
Joe Eykholt
795d86f55e [SCSI] libfc: change interface for rport_create
The interface for lport->tt.rport_create() takes a fc_disc_port arg,
which is unnatural for most calls.   The only reason for this was
to avoid passing in the local port as an argument, but otherwise
added to complexity.

Simplify by just using lport and fc_rport_identifiers.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:40 -05:00
Joe Eykholt
ab28f1fd3b [SCSI] libfc: prepare to split off struct fc_rport_priv from fc_rport_libfc_priv
While the I/O and LLD interfaces use fc_rport_libfc_priv, the
disc and rport interfaces will use fc_rport_priv, which will
be separately allocated.

Change the disc and rport usage of fc_rport_libfc_priv to fc_rport_priv.

Use #define temporarily to make both names equivalent until a
subsequent patch splits them.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-10 12:07:39 -05:00
Vasu Dev
b2f0091fbf [SCSI] fcoe, libfc: fully makes use of per cpu exch pool and then removes em_lock
1. Updates fcoe_rcv() to queue incoming frames to the fcoe per
   cpu thread on which this frame's exch was originated and simply
   use current cpu for request exch not originated by initiator.
   It is redundant to add this code under CONFIG_SMP, so removes
   CONFIG_SMP uses around this code.

2. Updates fc_exch_em_alloc, fc_exch_delete, fc_exch_find to use
   per cpu exch pools, here fc_exch_delete is rename of older
   fc_exch_mgr_delete_ep since ep/exch are now deleted in pools
   of EM and so brief new name is sufficient and better name.

   Updates these functions to map exch id to their index into exch
   pool using fc_cpu_mask, fc_cpu_order and EM min_xid.
   This mapping is as per detailed explanation about this in
   last patch and basically this is just as lower fc_cpu_mask
   bits of exch id as cpu number and upper bit sum of EM min_xid
   and exch index in pool.

   Uses pool next_index to keep track of exch allocation from
   pool along with pool_max_index as upper bound of exches array
   in pool.

3. Adds exch pool ptr to fc_exch to free exch to its pool in
   fc_exch_delete.

4. Updates fc_exch_mgr_reset to reset all exch pools of an EM,
   this required adding fc_exch_pool_reset func to reset exches
   in pool and then have fc_exch_mgr_reset call fc_exch_pool_reset
   for each pool within each EM for a lport.

5. Removes no longer needed exches array, em_lock, next_xid, and
   total_exches from struct fc_exch_mgr, these are not needed after
   use of per cpu exch pool, also removes not used max_read,
   last_read from struct fc_exch_mgr.

6. Updates locking notes for exch pool lock with fc_exch lock and
   uses pool lock in exch allocation, lookup and reset.

Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-05 09:47:37 -05:00
Vasu Dev
e4bc50bedf [SCSI] fcoe, libfc: adds per cpu exch pool within exchange manager(EM)
Adds per cpu exch pool for these reasons:-

 1. Currently an EM instance is shared across all cpus to manage
    all exches for all cpus. This required em_lock across all
    cpus for an exch alloc, free, lookup and reset each frame
    and that made em_lock expensive, so instead having per cpu
    exch pool with their own per cpu pool lock will likely reduce
    locking contention in fast path for an exch alloc, free and
    lookup.

 2. Per cpu exch pool will likely improve cache hit ratio since
    all frames of an exch will be processed on the same cpu on
    which exch originated.

This patch is only prep work to help in keeping complexity of next
patch low, so this patch only sets up per cpu exch pool and related
helper funcs to be used by next patch. The next patch fully makes
use of per cpu exch pool in all code paths ie. tx, rx and reset.

Divides per EM exch id range equally across all cpus to setup per
cpu exch pool. This division is such that lower bits of exch id
carries cpu number info on which exch originated, later a simple
bitwise AND operation on exch id of incoming frame with fc_cpu_mask
retrieves cpu number info to direct all frames to same cpu on which
exch originated. This required a global fc_cpu_mask and fc_cpu_order
initialized to max possible cpus number nr_cpu_ids rounded up to 2's
power, this will be used in mapping exch id and exch ptr array
index in pool during exch allocation, find or reset code paths.

Adds a check in fc_exch_mgr_alloc() to ensure specified min_xid
lower bits are zero since these bits are used to carry cpu info.

Adds and initializes struct fc_exch_pool with all required fields
to manage exches in pool.

Allocates per cpu struct fc_exch_pool with memory for exches array
for range of exches per pool. The exches array memory is followed
by struct fc_exch_pool.

Adds fc_exch_ptr_get/set() helper functions to get/set exch ptr in
pool exches array at specified array index.

Increases default FCOE_MAX_XID to 0x0FFF from 0x07EF, so that more
exches are available per cpu after above described exch id range
division across all cpus to each pool.

Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-09-05 09:47:36 -05:00
Vasu Dev
52ff878c91 [SCSI] fcoe, fnic, libfc: modifies current code paths to use EM anchor list
Modifies current code to use EM anchor list in EM allocation, EM free,
EM reset, exch allocation and exch lookup code paths.

 1. Modifies fc_exch_mgr_alloc to accept EM match function and then
    have allocated EM added to the lport using fc_exch_mgr_add API
    while also updating EM kref for newly added EM.

 2. Updates fc_exch_mgr_free API to accept only lport pointer instead
    EM and then have this API free all EMs of the lport from EM anchor
    list.

 3. Removes single lport pointer link from the EM, which was used in
    associating lport pointer in newly allocated exchange. Instead have
    lport pointer passed along new exchange allocation call path and
    then store passed lport pointer in newly allocated exchange, this
    will allow a single EM instance to be used across more than one
    lport and used in EM reset to reset only lport specific exchanges.

 4. Modifies fc_exch_mgr_reset to reset all EMs from the EM anchor list
    of the lport, adds additional exch lport pointer (ep->lp) check for
    shared EM case to reset exchange specific to a lport requested reset.

 5. Updates exch allocation API fc_exch_alloc to use EM anchor list and
    its anchor match func pointer. The fc_exch_alloc will walk the list
    of EMs until it finds a match, a match will be either null match
    func pointer or call to match function returning true value.

 6. Updates fc_exch_recv to accept incoming frame on local port using
    only lport pointer and frame pointer without specifying EM instance
    of incoming frame. Instead modified fc_exch_recv to locate EM for the
    incoming frame by matching xid of incoming frame against a EM xid range.
    This change was required to use EM list in libfc Rx path and after this
    change the lport fc_exch_mgr pointer emp is not needed anymore, so
    removed emp pointer.

 7. Updates fnic for removed lport emp pointer and above modified libfc APIs
    fc_exch_recv, fc_exch_mgr_alloc and fc_exch_mgr_free.

 8. Removes exch_get and exch_put from libfc_function_template as these
    are no longer needed with EM anchor list and its match function use.
    Also removes its default function fc_exch_get.

A defect this patch introduced regarding the libfc initialization order in
the fnic driver was fixed by Joe Eykholt <jeykholt@cisco.com>.

Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-08-22 17:52:08 -05:00
Robert Love
d459b7ea1b [SCSI] libfc: Remove the FC_EM_DBG macro
Currently there is a 1:1 relationship between the lport
and exchange manager. This macro takes an EM as an argument
and determines the lport from it. However, later patches
will use an EM list per lport, so we will no longer have
this 1:1 relationship- this macro must change.

The FC_EM_DBG macro is rarely used. There are four callers,
two can use FC_LPORT_DBG instead and two can be removed
since they're not necessary. This patch makes those changes
and removes the macro.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-08-22 17:52:08 -05:00
Vasu Dev
96316099ac [SCSI] fcoe, libfc: adds exchange manager(EM) anchor list per lport and related APIs
Adds EM list using a anchor struct fc_exch_mgr_anchor, anchor is used
to allow same EM instance sharing across more than one lport on a eth
device, this implementation is per discussed design posted at
http://www.open-fcoe.org/pipermail/devel/2009-June/002566.html.

The shared EM is required for multiple lports on eth device when
using multiple VLANs or NPIV.

Adds fc_exch_mgr_add API to add a EM to the lport and fc_exch_mgr_del
API to delete previously added EM.

Also adds function fc_exch_mgr_destroy() to destroy allocated EM.
The kref is added to the EM to keep track of EM usage count, the EM is
destroyed when no longer in use upon kref reaching to zero.

The caller can specify match function to fc_exch_mgr_add, this
will be used in determining exchange allocation from its EM or not.

Moved calling of fcoe_em_config below fcoe_libfc_config calling,
so that list head lp->ema_list is initialized before configuring
EM.

Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-08-22 17:52:07 -05:00
Joe Eykholt
141940548c [SCSI] libfc: rename rport state "NONE" to "DELETE".
State RPORT_ST_NONE was intented to be an invalid state (0), never used.
This was a misguided attempt to be sure it was always initialized.
Having an extra state meaning nothing requires switch statements to
have a case covering that state.

State NONE has been used instead to mean the remote port is being deleted.
Changing the name to RPORT_ST_DELETE.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2009-08-22 17:52:06 -05:00