Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is provided under a dual BSD/GPLv2 license.  When using or
0003  * redistributing this file, you may do so under either license.
0004  *
0005  * GPL LICENSE SUMMARY
0006  *
0007  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
0008  *
0009  * This program is free software; you can redistribute it and/or modify
0010  * it under the terms of version 2 of the GNU General Public License as
0011  * published by the Free Software Foundation.
0012  *
0013  * This program is distributed in the hope that it will be useful, but
0014  * WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU General Public License
0019  * along with this program; if not, write to the Free Software
0020  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
0021  * The full GNU General Public License is included in this distribution
0022  * in the file called LICENSE.GPL.
0023  *
0024  * BSD LICENSE
0025  *
0026  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
0027  * All rights reserved.
0028  *
0029  * Redistribution and use in source and binary forms, with or without
0030  * modification, are permitted provided that the following conditions
0031  * are met:
0032  *
0033  *   * Redistributions of source code must retain the above copyright
0034  *     notice, this list of conditions and the following disclaimer.
0035  *   * Redistributions in binary form must reproduce the above copyright
0036  *     notice, this list of conditions and the following disclaimer in
0037  *     the documentation and/or other materials provided with the
0038  *     distribution.
0039  *   * Neither the name of Intel Corporation nor the names of its
0040  *     contributors may be used to endorse or promote products derived
0041  *     from this software without specific prior written permission.
0042  *
0043  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0044  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0045  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0046  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0047  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0048  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0049  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0050  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0051  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0052  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0053  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0054  */
0055 
0056 #ifndef __ISCI_H__
0057 #define __ISCI_H__
0058 
0059 #include <linux/interrupt.h>
0060 #include <linux/types.h>
0061 
0062 #define DRV_NAME "isci"
0063 #define SCI_PCI_BAR_COUNT 2
0064 #define SCI_NUM_MSI_X_INT 2
0065 #define SCI_SMU_BAR       0
0066 #define SCI_SMU_BAR_SIZE  (16*1024)
0067 #define SCI_SCU_BAR       1
0068 #define SCI_SCU_BAR_SIZE  (4*1024*1024)
0069 #define SCI_IO_SPACE_BAR0 2
0070 #define SCI_IO_SPACE_BAR1 3
0071 #define ISCI_CAN_QUEUE_VAL 250 /* < SCI_MAX_IO_REQUESTS ? */
0072 #define SCIC_CONTROLLER_STOP_TIMEOUT 5000
0073 
0074 #define SCI_CONTROLLER_INVALID_IO_TAG 0xFFFF
0075 
0076 #define SCI_MAX_PHYS  (4UL)
0077 #define SCI_MAX_PORTS SCI_MAX_PHYS
0078 #define SCI_MAX_SMP_PHYS  (384) /* not silicon constrained */
0079 #define SCI_MAX_REMOTE_DEVICES (256UL)
0080 #define SCI_MAX_IO_REQUESTS (256UL)
0081 #define SCI_MAX_SEQ (16)
0082 #define SCI_MAX_MSIX_MESSAGES  (2)
0083 #define SCI_MAX_SCATTER_GATHER_ELEMENTS 130 /* not silicon constrained */
0084 #define SCI_MAX_CONTROLLERS 2
0085 #define SCI_MAX_DOMAINS  SCI_MAX_PORTS
0086 
0087 #define SCU_MAX_CRITICAL_NOTIFICATIONS    (384)
0088 #define SCU_MAX_EVENTS_SHIFT          (7)
0089 #define SCU_MAX_EVENTS                    (1 << SCU_MAX_EVENTS_SHIFT)
0090 #define SCU_MAX_UNSOLICITED_FRAMES        (128)
0091 #define SCU_MAX_COMPLETION_QUEUE_SCRATCH  (128)
0092 #define SCU_MAX_COMPLETION_QUEUE_ENTRIES  (SCU_MAX_CRITICAL_NOTIFICATIONS \
0093                        + SCU_MAX_EVENTS \
0094                        + SCU_MAX_UNSOLICITED_FRAMES \
0095                        + SCI_MAX_IO_REQUESTS \
0096                        + SCU_MAX_COMPLETION_QUEUE_SCRATCH)
0097 #define SCU_MAX_COMPLETION_QUEUE_SHIFT    (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES))
0098 
0099 #define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096)
0100 #define SCU_UNSOLICITED_FRAME_BUFFER_SIZE   (1024U)
0101 #define SCU_INVALID_FRAME_INDEX             (0xFFFF)
0102 
0103 #define SCU_IO_REQUEST_MAX_SGE_SIZE         (0x00FFFFFF)
0104 #define SCU_IO_REQUEST_MAX_TRANSFER_LENGTH  (0x00FFFFFF)
0105 
0106 static inline void check_sizes(void)
0107 {
0108     BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_EVENTS);
0109     BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES <= 8);
0110     BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_UNSOLICITED_FRAMES);
0111     BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_COMPLETION_QUEUE_ENTRIES);
0112     BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES > SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES);
0113     BUILD_BUG_ON_NOT_POWER_OF_2(SCI_MAX_IO_REQUESTS);
0114     BUILD_BUG_ON_NOT_POWER_OF_2(SCI_MAX_SEQ);
0115 }
0116 
0117 /**
0118  * enum sci_status - This is the general return status enumeration for non-IO,
0119  *    non-task management related SCI interface methods.
0120  *
0121  *
0122  */
0123 enum sci_status {
0124     /**
0125      * This member indicates successful completion.
0126      */
0127     SCI_SUCCESS = 0,
0128 
0129     /**
0130      * This value indicates that the calling method completed successfully,
0131      * but that the IO may have completed before having it's start method
0132      * invoked.  This occurs during SAT translation for requests that do
0133      * not require an IO to the target or for any other requests that may
0134      * be completed without having to submit IO.
0135      */
0136     SCI_SUCCESS_IO_COMPLETE_BEFORE_START,
0137 
0138     /**
0139      *  This Value indicates that the SCU hardware returned an early response
0140      *  because the io request specified more data than is returned by the
0141      *  target device (mode pages, inquiry data, etc.). The completion routine
0142      *  will handle this case to get the actual number of bytes transferred.
0143      */
0144     SCI_SUCCESS_IO_DONE_EARLY,
0145 
0146     /**
0147      * This member indicates that the object for which a state change is
0148      * being requested is already in said state.
0149      */
0150     SCI_WARNING_ALREADY_IN_STATE,
0151 
0152     /**
0153      * This member indicates interrupt coalescence timer may cause SAS
0154      * specification compliance issues (i.e. SMP target mode response
0155      * frames must be returned within 1.9 milliseconds).
0156      */
0157     SCI_WARNING_TIMER_CONFLICT,
0158 
0159     /**
0160      * This field indicates a sequence of action is not completed yet. Mostly,
0161      * this status is used when multiple ATA commands are needed in a SATI translation.
0162      */
0163     SCI_WARNING_SEQUENCE_INCOMPLETE,
0164 
0165     /**
0166      * This member indicates that there was a general failure.
0167      */
0168     SCI_FAILURE,
0169 
0170     /**
0171      * This member indicates that the SCI implementation is unable to complete
0172      * an operation due to a critical flaw the prevents any further operation
0173      * (i.e. an invalid pointer).
0174      */
0175     SCI_FATAL_ERROR,
0176 
0177     /**
0178      * This member indicates the calling function failed, because the state
0179      * of the controller is in a state that prevents successful completion.
0180      */
0181     SCI_FAILURE_INVALID_STATE,
0182 
0183     /**
0184      * This member indicates the calling function failed, because there is
0185      * insufficient resources/memory to complete the request.
0186      */
0187     SCI_FAILURE_INSUFFICIENT_RESOURCES,
0188 
0189     /**
0190      * This member indicates the calling function failed, because the
0191      * controller object required for the operation can't be located.
0192      */
0193     SCI_FAILURE_CONTROLLER_NOT_FOUND,
0194 
0195     /**
0196      * This member indicates the calling function failed, because the
0197      * discovered controller type is not supported by the library.
0198      */
0199     SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE,
0200 
0201     /**
0202      * This member indicates the calling function failed, because the
0203      * requested initialization data version isn't supported.
0204      */
0205     SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION,
0206 
0207     /**
0208      * This member indicates the calling function failed, because the
0209      * requested configuration of SAS Phys into SAS Ports is not supported.
0210      */
0211     SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION,
0212 
0213     /**
0214      * This member indicates the calling function failed, because the
0215      * requested protocol is not supported by the remote device, port,
0216      * or controller.
0217      */
0218     SCI_FAILURE_UNSUPPORTED_PROTOCOL,
0219 
0220     /**
0221      * This member indicates the calling function failed, because the
0222      * requested information type is not supported by the SCI implementation.
0223      */
0224     SCI_FAILURE_UNSUPPORTED_INFORMATION_TYPE,
0225 
0226     /**
0227      * This member indicates the calling function failed, because the
0228      * device already exists.
0229      */
0230     SCI_FAILURE_DEVICE_EXISTS,
0231 
0232     /**
0233      * This member indicates the calling function failed, because adding
0234      * a phy to the object is not possible.
0235      */
0236     SCI_FAILURE_ADDING_PHY_UNSUPPORTED,
0237 
0238     /**
0239      * This member indicates the calling function failed, because the
0240      * requested information type is not supported by the SCI implementation.
0241      */
0242     SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD,
0243 
0244     /**
0245      * This member indicates the calling function failed, because the SCI
0246      * implementation does not support the supplied time limit.
0247      */
0248     SCI_FAILURE_UNSUPPORTED_TIME_LIMIT,
0249 
0250     /**
0251      * This member indicates the calling method failed, because the SCI
0252      * implementation does not contain the specified Phy.
0253      */
0254     SCI_FAILURE_INVALID_PHY,
0255 
0256     /**
0257      * This member indicates the calling method failed, because the SCI
0258      * implementation does not contain the specified Port.
0259      */
0260     SCI_FAILURE_INVALID_PORT,
0261 
0262     /**
0263      * This member indicates the calling method was partly successful
0264      * The port was reset but not all phys in port are operational
0265      */
0266     SCI_FAILURE_RESET_PORT_PARTIAL_SUCCESS,
0267 
0268     /**
0269      * This member indicates that calling method failed
0270      * The port reset did not complete because none of the phys are operational
0271      */
0272     SCI_FAILURE_RESET_PORT_FAILURE,
0273 
0274     /**
0275      * This member indicates the calling method failed, because the SCI
0276      * implementation does not contain the specified remote device.
0277      */
0278     SCI_FAILURE_INVALID_REMOTE_DEVICE,
0279 
0280     /**
0281      * This member indicates the calling method failed, because the remote
0282      * device is in a bad state and requires a reset.
0283      */
0284     SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
0285 
0286     /**
0287      * This member indicates the calling method failed, because the SCI
0288      * implementation does not contain or support the specified IO tag.
0289      */
0290     SCI_FAILURE_INVALID_IO_TAG,
0291 
0292     /**
0293      * This member indicates that the operation failed and the user should
0294      * check the response data associated with the IO.
0295      */
0296     SCI_FAILURE_IO_RESPONSE_VALID,
0297 
0298     /**
0299      * This member indicates that the operation failed, the failure is
0300      * controller implementation specific, and the response data associated
0301      * with the request is not valid.  You can query for the controller
0302      * specific error information via sci_controller_get_request_status()
0303      */
0304     SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
0305 
0306     /**
0307      * This member indicated that the operation failed because the
0308      * user requested this IO to be terminated.
0309      */
0310     SCI_FAILURE_IO_TERMINATED,
0311 
0312     /**
0313      * This member indicates that the operation failed and the associated
0314      * request requires a SCSI abort task to be sent to the target.
0315      */
0316     SCI_FAILURE_IO_REQUIRES_SCSI_ABORT,
0317 
0318     /**
0319      * This member indicates that the operation failed because the supplied
0320      * device could not be located.
0321      */
0322     SCI_FAILURE_DEVICE_NOT_FOUND,
0323 
0324     /**
0325      * This member indicates that the operation failed because the
0326      * objects association is required and is not correctly set.
0327      */
0328     SCI_FAILURE_INVALID_ASSOCIATION,
0329 
0330     /**
0331      * This member indicates that the operation failed, because a timeout
0332      * occurred.
0333      */
0334     SCI_FAILURE_TIMEOUT,
0335 
0336     /**
0337      * This member indicates that the operation failed, because the user
0338      * specified a value that is either invalid or not supported.
0339      */
0340     SCI_FAILURE_INVALID_PARAMETER_VALUE,
0341 
0342     /**
0343      * This value indicates that the operation failed, because the number
0344      * of messages (MSI-X) is not supported.
0345      */
0346     SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT,
0347 
0348     /**
0349      * This value indicates that the method failed due to a lack of
0350      * available NCQ tags.
0351      */
0352     SCI_FAILURE_NO_NCQ_TAG_AVAILABLE,
0353 
0354     /**
0355      * This value indicates that a protocol violation has occurred on the
0356      * link.
0357      */
0358     SCI_FAILURE_PROTOCOL_VIOLATION,
0359 
0360     /**
0361      * This value indicates a failure condition that retry may help to clear.
0362      */
0363     SCI_FAILURE_RETRY_REQUIRED,
0364 
0365     /**
0366      * This field indicates the retry limit was reached when a retry is attempted
0367      */
0368     SCI_FAILURE_RETRY_LIMIT_REACHED,
0369 
0370     /**
0371      * This member indicates the calling method was partly successful.
0372      * Mostly, this status is used when a LUN_RESET issued to an expander attached
0373      * STP device in READY NCQ substate needs to have RNC suspended/resumed
0374      * before posting TC.
0375      */
0376     SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS,
0377 
0378     /**
0379      * This field indicates an illegal phy connection based on the routing attribute
0380      * of both expander phy attached to each other.
0381      */
0382     SCI_FAILURE_ILLEGAL_ROUTING_ATTRIBUTE_CONFIGURATION,
0383 
0384     /**
0385      * This field indicates a CONFIG ROUTE INFO command has a response with function result
0386      * INDEX DOES NOT EXIST, usually means exceeding max route index.
0387      */
0388     SCI_FAILURE_EXCEED_MAX_ROUTE_INDEX,
0389 
0390     /**
0391      * This value indicates that an unsupported PCI device ID has been
0392      * specified.  This indicates that attempts to invoke
0393      * sci_library_allocate_controller() will fail.
0394      */
0395     SCI_FAILURE_UNSUPPORTED_PCI_DEVICE_ID
0396 
0397 };
0398 
0399 /**
0400  * enum sci_io_status - This enumeration depicts all of the possible IO
0401  *    completion status values.  Each value in this enumeration maps directly
0402  *    to a value in the enum sci_status enumeration.  Please refer to that
0403  *    enumeration for detailed comments concerning what the status represents.
0404  *
0405  * Add the API to retrieve the SCU status from the core. Check to see that the
0406  * following status are properly handled: - SCI_IO_FAILURE_UNSUPPORTED_PROTOCOL
0407  * - SCI_IO_FAILURE_INVALID_IO_TAG
0408  */
0409 enum sci_io_status {
0410     SCI_IO_SUCCESS                         = SCI_SUCCESS,
0411     SCI_IO_FAILURE                         = SCI_FAILURE,
0412     SCI_IO_SUCCESS_COMPLETE_BEFORE_START   = SCI_SUCCESS_IO_COMPLETE_BEFORE_START,
0413     SCI_IO_SUCCESS_IO_DONE_EARLY           = SCI_SUCCESS_IO_DONE_EARLY,
0414     SCI_IO_FAILURE_INVALID_STATE           = SCI_FAILURE_INVALID_STATE,
0415     SCI_IO_FAILURE_INSUFFICIENT_RESOURCES  = SCI_FAILURE_INSUFFICIENT_RESOURCES,
0416     SCI_IO_FAILURE_UNSUPPORTED_PROTOCOL    = SCI_FAILURE_UNSUPPORTED_PROTOCOL,
0417     SCI_IO_FAILURE_RESPONSE_VALID          = SCI_FAILURE_IO_RESPONSE_VALID,
0418     SCI_IO_FAILURE_CONTROLLER_SPECIFIC_ERR = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
0419     SCI_IO_FAILURE_TERMINATED              = SCI_FAILURE_IO_TERMINATED,
0420     SCI_IO_FAILURE_REQUIRES_SCSI_ABORT     = SCI_FAILURE_IO_REQUIRES_SCSI_ABORT,
0421     SCI_IO_FAILURE_INVALID_PARAMETER_VALUE = SCI_FAILURE_INVALID_PARAMETER_VALUE,
0422     SCI_IO_FAILURE_NO_NCQ_TAG_AVAILABLE    = SCI_FAILURE_NO_NCQ_TAG_AVAILABLE,
0423     SCI_IO_FAILURE_PROTOCOL_VIOLATION      = SCI_FAILURE_PROTOCOL_VIOLATION,
0424 
0425     SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
0426 
0427     SCI_IO_FAILURE_RETRY_REQUIRED      = SCI_FAILURE_RETRY_REQUIRED,
0428     SCI_IO_FAILURE_RETRY_LIMIT_REACHED = SCI_FAILURE_RETRY_LIMIT_REACHED,
0429     SCI_IO_FAILURE_INVALID_REMOTE_DEVICE = SCI_FAILURE_INVALID_REMOTE_DEVICE
0430 };
0431 
0432 /**
0433  * enum sci_task_status - This enumeration depicts all of the possible task
0434  *    completion status values.  Each value in this enumeration maps directly
0435  *    to a value in the enum sci_status enumeration.  Please refer to that
0436  *    enumeration for detailed comments concerning what the status represents.
0437  *
0438  * Check to see that the following status are properly handled:
0439  */
0440 enum sci_task_status {
0441     SCI_TASK_SUCCESS                         = SCI_SUCCESS,
0442     SCI_TASK_FAILURE                         = SCI_FAILURE,
0443     SCI_TASK_FAILURE_INVALID_STATE           = SCI_FAILURE_INVALID_STATE,
0444     SCI_TASK_FAILURE_INSUFFICIENT_RESOURCES  = SCI_FAILURE_INSUFFICIENT_RESOURCES,
0445     SCI_TASK_FAILURE_UNSUPPORTED_PROTOCOL    = SCI_FAILURE_UNSUPPORTED_PROTOCOL,
0446     SCI_TASK_FAILURE_INVALID_TAG             = SCI_FAILURE_INVALID_IO_TAG,
0447     SCI_TASK_FAILURE_RESPONSE_VALID          = SCI_FAILURE_IO_RESPONSE_VALID,
0448     SCI_TASK_FAILURE_CONTROLLER_SPECIFIC_ERR = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
0449     SCI_TASK_FAILURE_TERMINATED              = SCI_FAILURE_IO_TERMINATED,
0450     SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE = SCI_FAILURE_INVALID_PARAMETER_VALUE,
0451 
0452     SCI_TASK_FAILURE_REMOTE_DEVICE_RESET_REQUIRED = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
0453     SCI_TASK_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS = SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS
0454 
0455 };
0456 
0457 /**
0458  * sci_swab32_cpy - convert between scsi and scu-hardware byte format
0459  * @dest: receive the 4-byte endian swapped version of src
0460  * @src: word aligned source buffer
0461  *
0462  * scu hardware handles SSP/SMP control, response, and unidentified
0463  * frames in "big endian dword" order.  Regardless of host endian this
0464  * is always a swab32()-per-dword conversion of the standard definition,
0465  * i.e. single byte fields swapped and multi-byte fields in little-
0466  * endian
0467  */
0468 static inline void sci_swab32_cpy(void *_dest, void *_src, ssize_t word_cnt)
0469 {
0470     u32 *dest = _dest, *src = _src;
0471 
0472     while (--word_cnt >= 0)
0473         dest[word_cnt] = swab32(src[word_cnt]);
0474 }
0475 
0476 extern unsigned char no_outbound_task_to;
0477 extern u16 ssp_max_occ_to;
0478 extern u16 stp_max_occ_to;
0479 extern u16 ssp_inactive_to;
0480 extern u16 stp_inactive_to;
0481 extern unsigned char phy_gen;
0482 extern unsigned char max_concurr_spinup;
0483 extern uint cable_selection_override;
0484 
0485 irqreturn_t isci_msix_isr(int vec, void *data);
0486 irqreturn_t isci_intx_isr(int vec, void *data);
0487 irqreturn_t isci_error_isr(int vec, void *data);
0488 
0489 /*
0490  * Each timer is associated with a cancellation flag that is set when
0491  * del_timer() is called and checked in the timer callback function. This
0492  * is needed since del_timer_sync() cannot be called with sci_lock held.
0493  * For deinit however, del_timer_sync() is used without holding the lock.
0494  */
0495 struct sci_timer {
0496     struct timer_list   timer;
0497     bool            cancel;
0498 };
0499 
0500 static inline
0501 void sci_init_timer(struct sci_timer *tmr, void (*fn)(struct timer_list *t))
0502 {
0503     tmr->cancel = false;
0504     timer_setup(&tmr->timer, fn, 0);
0505 }
0506 
0507 static inline void sci_mod_timer(struct sci_timer *tmr, unsigned long msec)
0508 {
0509     tmr->cancel = false;
0510     mod_timer(&tmr->timer, jiffies + msecs_to_jiffies(msec));
0511 }
0512 
0513 static inline void sci_del_timer(struct sci_timer *tmr)
0514 {
0515     tmr->cancel = true;
0516     del_timer(&tmr->timer);
0517 }
0518 
0519 struct sci_base_state_machine {
0520     const struct sci_base_state *state_table;
0521     u32 initial_state_id;
0522     u32 current_state_id;
0523     u32 previous_state_id;
0524 };
0525 
0526 typedef void (*sci_state_transition_t)(struct sci_base_state_machine *sm);
0527 
0528 struct sci_base_state {
0529     sci_state_transition_t enter_state; /* Called on state entry */
0530     sci_state_transition_t exit_state;  /* Called on state exit */
0531 };
0532 
0533 extern void sci_init_sm(struct sci_base_state_machine *sm,
0534             const struct sci_base_state *state_table,
0535             u32 initial_state);
0536 extern void sci_change_state(struct sci_base_state_machine *sm, u32 next_state);
0537 #endif  /* __ISCI_H__ */