Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
remote_device.h
Go to the documentation of this file.
1 /*
2  * This file is provided under a dual BSD/GPLv2 license. When using or
3  * redistributing this file, you may do so under either license.
4  *
5  * GPL LICENSE SUMMARY
6  *
7  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21  * The full GNU General Public License is included in this distribution
22  * in the file called LICENSE.GPL.
23  *
24  * BSD LICENSE
25  *
26  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  * * Redistributions of source code must retain the above copyright
34  * notice, this list of conditions and the following disclaimer.
35  * * Redistributions in binary form must reproduce the above copyright
36  * notice, this list of conditions and the following disclaimer in
37  * the documentation and/or other materials provided with the
38  * distribution.
39  * * Neither the name of Intel Corporation nor the names of its
40  * contributors may be used to endorse or promote products derived
41  * from this software without specific prior written permission.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54  */
55 
56 #ifndef _ISCI_REMOTE_DEVICE_H_
57 #define _ISCI_REMOTE_DEVICE_H_
58 #include <scsi/libsas.h>
59 #include <linux/kref.h>
61 #include "remote_node_context.h"
62 #include "port.h"
63 
71 };
72 
82  #define IDEV_START_PENDING 0
83  #define IDEV_STOP_PENDING 1
84  #define IDEV_ALLOCATED 2
85  #define IDEV_GONE 3
86  #define IDEV_IO_READY 4
87  #define IDEV_IO_NCQERROR 5
88  #define IDEV_RNC_LLHANG_ENABLED 6
89  #define IDEV_ABORT_PATH_ACTIVE 7
90  #define IDEV_ABORT_PATH_RESUME_PENDING 8
91  unsigned long flags;
92  struct kref kref;
95  struct list_head node;
101  /* XXX unify with device reference counting and delete */
107 };
108 
109 #define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000
110 
111 /* device reference routines must be called under sci_lock */
112 static inline struct isci_remote_device *isci_get_device(
113  struct isci_remote_device *idev)
114 {
115  if (idev)
116  kref_get(&idev->kref);
117  return idev;
118 }
119 
120 static inline struct isci_remote_device *isci_lookup_device(struct domain_device *dev)
121 {
122  struct isci_remote_device *idev = dev->lldd_dev;
123 
124  if (idev && !test_bit(IDEV_GONE, &idev->flags)) {
125  kref_get(&idev->kref);
126  return idev;
127  }
128 
129  return NULL;
130 }
131 
132 void isci_remote_device_release(struct kref *kref);
133 static inline void isci_put_device(struct isci_remote_device *idev)
134 {
135  if (idev)
136  kref_put(&idev->kref, isci_remote_device_release);
137 }
138 
139 enum sci_status isci_remote_device_stop(struct isci_host *ihost,
140  struct isci_remote_device *idev);
142  struct isci_remote_device *idev);
145 
159  struct isci_remote_device *idev,
160  u32 timeout);
161 
175  struct isci_remote_device *idev);
176 
188  struct isci_remote_device *idev);
189 
265 #define REMOTE_DEV_STATES {\
266  C(DEV_INITIAL),\
267  C(DEV_STOPPED),\
268  C(DEV_STARTING),\
269  C(DEV_READY),\
270  C(STP_DEV_IDLE),\
271  C(STP_DEV_CMD),\
272  C(STP_DEV_NCQ),\
273  C(STP_DEV_NCQ_ERROR),\
274  C(STP_DEV_ATAPI_ERROR),\
275  C(STP_DEV_AWAIT_RESET),\
276  C(SMP_DEV_IDLE),\
277  C(SMP_DEV_CMD),\
278  C(DEV_STOPPING),\
279  C(DEV_FAILED),\
280  C(DEV_RESETTING),\
281  C(DEV_FINAL),\
282  }
283 #undef C
284 #define C(a) SCI_##a
285 enum sci_remote_device_states REMOTE_DEV_STATES;
286 #undef C
287 const char *dev_state_name(enum sci_remote_device_states state);
288 
289 static inline struct isci_remote_device *rnc_to_dev(struct sci_remote_node_context *rnc)
290 {
291  struct isci_remote_device *idev;
292 
293  idev = container_of(rnc, typeof(*idev), rnc);
294 
295  return idev;
296 }
297 
298 static inline bool dev_is_expander(struct domain_device *dev)
299 {
300  return dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV;
301 }
302 
303 static inline void sci_remote_device_decrement_request_count(struct isci_remote_device *idev)
304 {
305  /* XXX delete this voodoo when converting to the top-level device
306  * reference count
307  */
308  if (WARN_ONCE(idev->started_request_count == 0,
309  "%s: tried to decrement started_request_count past 0!?",
310  __func__))
311  /* pass */;
312  else
313  idev->started_request_count--;
314 }
315 
317 
319  struct isci_remote_device *idev,
320  u32 frame_index);
321 
323  struct isci_remote_device *idev,
324  u32 event_code);
325 
327  struct isci_host *ihost,
328  struct isci_remote_device *idev,
329  struct isci_request *ireq);
330 
332  struct isci_host *ihost,
333  struct isci_remote_device *idev,
334  struct isci_request *ireq);
335 
337  struct isci_host *ihost,
338  struct isci_remote_device *idev,
339  struct isci_request *ireq);
340 
342  struct isci_remote_device *idev,
343  u32 request);
344 
346  struct isci_remote_device *idev);
347 
349  struct isci_remote_device *idev);
350 
351 enum sci_status
353  struct isci_remote_device *idev);
354 
356  struct isci_host *ihost,
357  struct isci_remote_device *idev);
358 
360  struct isci_remote_device *idev,
362  void *cb_p);
363 
365  struct isci_host *ihost,
366  struct isci_remote_device *idev);
367 
369  struct isci_host *ihost,
370  struct isci_remote_device *idev);
371 
373  struct isci_host *ihost,
374  struct isci_remote_device *idev);
375 
377  struct isci_host *ihost,
378  struct isci_remote_device *idev,
379  struct isci_request *ireq);
380 
382  struct isci_host *ihost,
383  struct isci_remote_device *idev,
384  struct isci_request *ireq);
387 #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */