1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris/**
57230557Sjimharris * @file
58230557Sjimharris *
59230557Sjimharris * @brief This file contains the implementation of the public methods for a
60230557Sjimharris *        SCIC_SDS_LIBRARY object.
61230557Sjimharris */
62230557Sjimharris
63230557Sjimharris#include <dev/isci/scil/scic_library.h>
64230557Sjimharris#include <dev/isci/scil/scic_sds_library.h>
65230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h>
66230557Sjimharris#include <dev/isci/scil/scic_sds_request.h>
67230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h>
68230557Sjimharris#include <dev/isci/scil/intel_pci.h>
69230557Sjimharris#include <dev/isci/scil/scic_sds_pci.h>
70230557Sjimharris#include <dev/isci/scil/scu_constants.h>
71230557Sjimharris
72230557Sjimharrisstruct SCIC_SDS_CONTROLLER;
73230557Sjimharris
74230557Sjimharris#define SCIC_LIBRARY_CONTROLLER_MEMORY_START(library) \
75230557Sjimharris   ((char *)(library) + sizeof(SCIC_SDS_LIBRARY_T))
76230557Sjimharris
77230557Sjimharris// ---------------------------------------------------------------------------
78230557Sjimharris
79230557SjimharrisU32 scic_library_get_object_size(
80230557Sjimharris   U8 max_controller_count
81230557Sjimharris)
82230557Sjimharris{
83230557Sjimharris   return   sizeof(SCIC_SDS_LIBRARY_T)
84230557Sjimharris          + scic_sds_controller_get_object_size() * max_controller_count;
85230557Sjimharris}
86230557Sjimharris
87230557Sjimharris// ---------------------------------------------------------------------------
88230557Sjimharris
89230557SjimharrisSCI_LIBRARY_HANDLE_T scic_library_construct(
90230557Sjimharris   void                    * library_memory,
91230557Sjimharris   U8                        max_controller_count
92230557Sjimharris)
93230557Sjimharris{
94230557Sjimharris   SCI_STATUS status;
95230557Sjimharris   SCIC_SDS_LIBRARY_T *this_library;
96230557Sjimharris
97230557Sjimharris   this_library = (SCIC_SDS_LIBRARY_T *)library_memory;
98230557Sjimharris
99230557Sjimharris   this_library->max_controller_count = max_controller_count;
100230557Sjimharris
101230557Sjimharris   this_library->controllers =
102230557Sjimharris      (SCIC_SDS_CONTROLLER_T *)((char *)library_memory + sizeof(SCIC_SDS_LIBRARY_T));
103230557Sjimharris
104230557Sjimharris   SCI_BASE_LIBRARY_CONSTRUCT(this_library,
105230557Sjimharris                              &this_library->parent,
106230557Sjimharris                              max_controller_count,
107230557Sjimharris                              struct SCIC_SDS_CONTROLLER,
108230557Sjimharris                              status);
109230557Sjimharris   return this_library;
110230557Sjimharris}
111230557Sjimharris
112230557Sjimharris// ---------------------------------------------------------------------------
113230557Sjimharris
114230557Sjimharrisvoid scic_library_set_pci_info(
115230557Sjimharris   SCI_LIBRARY_HANDLE_T      library,
116230557Sjimharris   SCI_PCI_COMMON_HEADER_T * pci_header
117230557Sjimharris)
118230557Sjimharris{
119230557Sjimharris   SCIC_SDS_LIBRARY_T *this_library;
120230557Sjimharris   this_library = (SCIC_SDS_LIBRARY_T *)library;
121230557Sjimharris
122230557Sjimharris   this_library->pci_device   = pci_header->device_id;
123230557Sjimharris
124230557Sjimharris#if defined(PBG_HBA_A0_BUILD)
125230557Sjimharris   this_library->pci_revision = SCIC_SDS_PCI_REVISION_A0;
126230557Sjimharris#elif defined(PBG_HBA_A2_BUILD)
127230557Sjimharris   this_library->pci_revision = SCIC_SDS_PCI_REVISION_A2;
128230557Sjimharris#elif defined(PBG_HBA_BETA_BUILD)
129230557Sjimharris   this_library->pci_revision = SCIC_SDS_PCI_REVISION_B0;
130230557Sjimharris#elif defined(PBG_BUILD)
131230557Sjimharris   // The SCU PCI function revision ID for A0/A2 is not populated
132230557Sjimharris   // properly.  As a result, we force the revision ID to A2 for
133230557Sjimharris   // this situation.  Therefore, the standard PBG build will not
134230557Sjimharris   // work for A0.
135230557Sjimharris   if (pci_header->revision == SCIC_SDS_PCI_REVISION_A0)
136230557Sjimharris      this_library->pci_revision = SCIC_SDS_PCI_REVISION_A2;
137230557Sjimharris   else
138230557Sjimharris      this_library->pci_revision = pci_header->revision;
139230557Sjimharris#endif
140230557Sjimharris}
141230557Sjimharris
142230557Sjimharris// ---------------------------------------------------------------------------
143230557Sjimharris
144230557SjimharrisSCI_STATUS scic_library_allocate_controller(
145230557Sjimharris   SCI_LIBRARY_HANDLE_T    library,
146230557Sjimharris   SCI_CONTROLLER_HANDLE_T *new_controller
147230557Sjimharris)
148230557Sjimharris{
149230557Sjimharris   SCI_STATUS status;
150230557Sjimharris   SCIC_SDS_LIBRARY_T *this_library;
151230557Sjimharris
152230557Sjimharris   this_library = (SCIC_SDS_LIBRARY_T *)library;
153230557Sjimharris
154230557Sjimharris   if (
155230557Sjimharris         (  (this_library->pci_device >= 0x1D60)
156230557Sjimharris         && (this_library->pci_device <= 0x1D62)
157230557Sjimharris         )
158230557Sjimharris      || (  (this_library->pci_device >= 0x1D64)
159230557Sjimharris         && (this_library->pci_device <= 0x1D65)
160230557Sjimharris         )
161230557Sjimharris      || (  (this_library->pci_device >= 0x1D68)
162230557Sjimharris         && (this_library->pci_device <= 0x1D6F)
163230557Sjimharris         )
164230557Sjimharris      )
165230557Sjimharris   {
166230557Sjimharris      SCI_BASE_LIBRARY_ALLOCATE_CONTROLLER(
167230557Sjimharris         this_library, new_controller, &status);
168230557Sjimharris   }
169230557Sjimharris   else
170230557Sjimharris      status = SCI_FAILURE_UNSUPPORTED_PCI_DEVICE_ID;
171230557Sjimharris
172230557Sjimharris   return status;
173230557Sjimharris}
174230557Sjimharris
175230557Sjimharris// ---------------------------------------------------------------------------
176230557Sjimharris
177230557SjimharrisSCI_STATUS scic_library_free_controller(
178230557Sjimharris   SCI_LIBRARY_HANDLE_T library,
179230557Sjimharris   SCI_CONTROLLER_HANDLE_T controller
180230557Sjimharris)
181230557Sjimharris{
182230557Sjimharris   SCI_STATUS status;
183230557Sjimharris   SCIC_SDS_LIBRARY_T *this_library;
184230557Sjimharris   this_library = (SCIC_SDS_LIBRARY_T *)library;
185230557Sjimharris
186230557Sjimharris   SCI_BASE_LIBRARY_FREE_CONTROLLER(
187230557Sjimharris      this_library, controller, struct SCIC_SDS_CONTROLLER, &status);
188230557Sjimharris
189230557Sjimharris   return status;
190230557Sjimharris}
191230557Sjimharris
192230557Sjimharris// ---------------------------------------------------------------------------
193230557Sjimharris
194230557SjimharrisU8 scic_library_get_pci_device_controller_count(
195230557Sjimharris   SCI_LIBRARY_HANDLE_T library
196230557Sjimharris)
197230557Sjimharris{
198230557Sjimharris   SCIC_SDS_LIBRARY_T *this_library;
199230557Sjimharris   U16 device_id;
200230557Sjimharris
201230557Sjimharris   this_library = (SCIC_SDS_LIBRARY_T *)library;
202230557Sjimharris   device_id = this_library->pci_device;
203230557Sjimharris
204230557Sjimharris   //Check if we are on a b0 or c0 which has 2 controllers
205230557Sjimharris   if (
206230557Sjimharris         // Warning: If 0x1d66 is ever defined to be a single controller
207230557Sjimharris         //          this logic will fail.
208230557Sjimharris         //          If 0x1d63 or 0x1d67 is ever defined to be dual
209230557Sjimharris         //          controller this logic will fail.
210230557Sjimharris         ((device_id & 0xFFF1) == 0x1D60)
211230557Sjimharris      && (
212230557Sjimharris            (this_library->pci_revision == SCU_PBG_HBA_REV_B0)
213230557Sjimharris         || (this_library->pci_revision == SCU_PBG_HBA_REV_C0)
214230557Sjimharris         || (this_library->pci_revision == SCU_PBG_HBA_REV_C1)
215230557Sjimharris         )
216230557Sjimharris      )
217230557Sjimharris      return 2;
218230557Sjimharris   else
219230557Sjimharris      return 1;
220230557Sjimharris}
221230557Sjimharris
222230557Sjimharris// ---------------------------------------------------------------------------
223230557Sjimharris
224230557SjimharrisU32 scic_library_get_max_sge_size(
225230557Sjimharris   SCI_LIBRARY_HANDLE_T library
226230557Sjimharris)
227230557Sjimharris{
228230557Sjimharris   return SCU_IO_REQUEST_MAX_SGE_SIZE;
229230557Sjimharris}
230230557Sjimharris
231230557Sjimharris// ---------------------------------------------------------------------------
232230557Sjimharris
233230557SjimharrisU32 scic_library_get_max_sge_count(
234230557Sjimharris   SCI_LIBRARY_HANDLE_T library
235230557Sjimharris)
236230557Sjimharris{
237230557Sjimharris   return SCU_IO_REQUEST_SGE_COUNT;
238230557Sjimharris}
239230557Sjimharris
240230557Sjimharris// ---------------------------------------------------------------------------
241230557Sjimharris
242230557SjimharrisU32 scic_library_get_max_io_length(
243230557Sjimharris   SCI_LIBRARY_HANDLE_T library
244230557Sjimharris)
245230557Sjimharris{
246230557Sjimharris   return SCU_IO_REQUEST_MAX_TRANSFER_LENGTH;
247230557Sjimharris}
248230557Sjimharris
249230557Sjimharris// ---------------------------------------------------------------------------
250230557Sjimharris
251230557SjimharrisU16 scic_library_get_min_timer_count(void)
252230557Sjimharris{
253230557Sjimharris   return (U16) (scic_sds_controller_get_min_timer_count()
254230557Sjimharris               + scic_sds_remote_device_get_min_timer_count()
255230557Sjimharris               + scic_sds_request_get_min_timer_count());
256230557Sjimharris}
257230557Sjimharris
258230557Sjimharris// ---------------------------------------------------------------------------
259230557Sjimharris
260230557SjimharrisU16 scic_library_get_max_timer_count(void)
261230557Sjimharris{
262230557Sjimharris   return (U16) (scic_sds_controller_get_max_timer_count()
263230557Sjimharris               + scic_sds_remote_device_get_max_timer_count()
264230557Sjimharris               + scic_sds_request_get_max_timer_count());
265230557Sjimharris}
266230557Sjimharris
267230557Sjimharris/**
268230557Sjimharris *
269230557Sjimharris */
270230557SjimharrisU8 scic_sds_library_get_controller_index(
271230557Sjimharris   SCIC_SDS_LIBRARY_T    * library,
272230557Sjimharris   SCIC_SDS_CONTROLLER_T * controller
273230557Sjimharris)
274230557Sjimharris{
275230557Sjimharris   U8 index;
276230557Sjimharris
277230557Sjimharris   for (index = 0; index < library->max_controller_count; index++)
278230557Sjimharris   {
279230557Sjimharris      if (controller == &library->controllers[index])
280230557Sjimharris      {
281230557Sjimharris         return index;
282230557Sjimharris      }
283230557Sjimharris   }
284230557Sjimharris
285230557Sjimharris   return 0xff;
286230557Sjimharris}
287230557Sjimharris
288