We have unsafe references to remote devices that are notified to
disappear at lldd_dev_gone. In order to clean this up we need a single
canonical source for device lookups and stable references once a lookup
succeeds. Towards that end guarantee that domain_device.lldd_dev is
NULL as soon as we start the process of stopping a device. Any code
path that wants to safely lookup a remote device must do so through
task->dev->lldd_dev (isci_lookup_device()).
For in-flight references outside of scic_lock we need reference counting
to ensure that the device is not recycled before we are done with it.
Simplify device back references to just scic_sds_request.target_device
which is now the only permissible internal reference that is maintained
relative to the reference count.
There were two occasions where we wanted new i/o's to be treated as
SAS_TASK_UNDELIVERED but where the domain_dev->lldd_dev link is still
intact. Introduce a 'gone' flag to prevent i/o while waiting for libsas
to take action on the port down event.
One 'core' leftover is that we currently call
scic_remote_device_destruct() from isci_remote_device_deconstruct()
which is called when the 'core' says the device is stopped. It would be
more natural for the final put to trigger
isci_remote_device_deconstruct() but this implementation is deferred as
it requires other changes.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
In isci_task_request_complete() we save the response/sense data from the
command. Make sure isci_tmf has enough space to hold the full response.
[ it does not look like we actually use this data, and
response_data_len/sense_data_len should be specifying the byte count,
in any event do the simple fix first so we don't corrupt memory ]
Reported-by: Adam Gruchala <adam.gruchala@intel.com>
Tested-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Rather than return an error code and update a pointer that was passed by
reference just return the request object directly (or null if allocation
failed).
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Every single i/o or event completion incurs a test and branch to see if
the cycle bit changed. For power-of-2 queue sizes the cycle bit can be
read directly from the rollover of the queue pointer.
Likely premature optimization, but the hidden if() and hidden
assignments / side-effects in the macros were already asking to be
cleaned up.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
A tag is a 16 bit number where the upper four bits is a sequence number
and the remainder is the task context index (tci). Sanitize the macro
names and shave 256-bytes out of scic_sds_controller by reducing the size of
io_request_sequence.
scic_sds_io_tag_construct --> ISCI_TAG
scic_sds_io_tag_get_sequence --> ISCI_TAG_SEQ
scic_sds_io_tag_get_index() --> ISCI_TAG_TCI
scic_sds_io_sequence_increment() [delete / open code]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
The circ_buf macros are ~6% faster, as measured by perf, because they take
advantage of power-of-two math assumptions i.e. no test and branch for
rollover. Their semantics are clearer than the hidden side effects in pool.h
(like sci_pool_get() which hides an assignment).
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
In the case where the hard reset process fails, each link in
the port is put through a link reset sequence.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Walk through the list of pending requests being careful to consider that
multiple requests can be terminated when the lock is dropped (i.e.
invalidating the 'next' reference established by
list_for_each_entry_safe).
Also noticed that all callers to isci_terminate_pending_requests()
specifying terminating, so just drop the parameter.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
In the situation where a termination of an I/O times-out,
make sure that the linkage from the request to the task
is severed completely. Also make sure that the selection
of tasks to terminate occurs under scic_lock.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Requests that fail at start because of a reset pending condition
must be set to complete in order to allow for later cleanup.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
There are situations with slow expanders in which a first attempt
to execute an SMP request will fail with a timeout. Immediate
subsequent retries will generally succeed. This change makes sure
SMP I/O failures are immediately failed to libsas so that retries
happen with no discovery process timeout delay.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
When resetting a sata device in the domain we have seen occasions where
libsas prematurely marks a device gone in the time it takes for the
device to re-establish the link. This plays badly with software raid
arrays. Other libsas drivers have non-uniform delays in their reset
handlers to try to cover this condition, but not sufficient to close the
hole. Given that a sata device can take many seconds to recover we
filter bcns and poll for the device reattach state before notifying
libsas that the port needs the domain to be rediscovered. Once this has
been proven out at the lldd level we can think about uplevelling this
feature to a common implementation in libsas.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
[ use kzalloc instead of kmem_cache ]
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
[ use eventq and time macros ]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
The old 'core' had aspirations of running in severely memory constrained
environments like bios option-rom, it's not needed for Linux and gets in
the way of other cleanups (like unifying/reducing the number of structure
members in scic_sds_controller/isci_host).
This also fixes a theoretical bug in that the driver would blindly override
the silicon advertised limits for number of ports, task contexts, and remote
node contexts.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
C0 silicon updates the pci revision id and requires new AFE parameters
for phy signal integrity. Support for previous silicon revisions is
deprecated (it's also broken for the theoretical case of multiple
controllers at different silicon revisions, all the more reason to get
it removed as soon as possible)
Signed-off-by: Adam Gruchala <adam.gruchala@intel.com>
[fixed up deprecated silicon support]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Additional state machine cleanups:
o Remove static functions sci_state_machine_exit_state() and
sci_state_machine_enter_state()
o Combines sci_base_state_machine_construct() and
sci_base_state_machine_start() into a single function,
sci_init_sm()
o Remove sci_base_state_machine_stop() which is unused.
o Kill state_machine.[ch]
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
[fixed too large to inline functions]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This cleans up several areas of the state machine mechanism:
o Rename sci_base_state_machine_change_state to sci_change_state
o Remove sci_base_state_machine_get_state function
o Rename 'state_machine' struct member to 'sm' in client structs
o Shorten the name of request states
o Shorten state machine state names as follows:
SCI_BASE_CONTROLLER_STATE_xxx to SCIC_xxx
SCI_BASE_PHY_STATE_xxx to SCI_PHY_xxx
SCIC_SDS_PHY_STARTING_SUBSTATE_xxx to SCI_PHY_SUB_xxx
SCI_BASE_PORT_STATE_xxx to SCI_PORT_xxx and
SCIC_SDS_PORT_READY_SUBSTATE_xxx to SCI_PORT_SUB_xxx
SCI_BASE_REMOTE_DEVICE_STATE_xxx to SCI_DEV_xxx
SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_xxx to SCI_STP_DEV_xxx
SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_xxx to SCI_SMP_DEV_xxx
SCIC_SDS_REMOTE_NODE_CONTEXT_xxx_STATE to SCI_RNC_xxx
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
We can call the EFI get_variable service routine directly to retrieve
the EFI variable that holds the OEM parameters table.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
It doesn't look like there is any reason to do a kmalloc. We can do the
byte swap in place and avoid the allocation. This allow us to remove
a kmalloc and a memcpy.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Replace the timeout_timer in the isci_tmf with a call to
wait_for_completion_timeout
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>