Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
scsi
isci
host.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
#ifndef _SCI_HOST_H_
56
#define _SCI_HOST_H_
57
58
#include <
scsi/sas_ata.h
>
59
#include "
remote_device.h
"
60
#include "
phy.h
"
61
#include "
isci.h
"
62
#include "
remote_node_table.h
"
63
#include "
registers.h
"
64
#include "
unsolicited_frame_control.h
"
65
#include "
probe_roms.h
"
66
67
struct
isci_request
;
68
struct
scu_task_context
;
69
70
77
struct
sci_power_control
{
82
bool
timer_started
;
83
87
struct
sci_timer
timer
;
88
93
u8
phys_waiting
;
94
98
u8
phys_granted_power
;
99
104
struct
isci_phy
*
requesters
[
SCI_MAX_PHYS
];
105
106
};
107
108
struct
sci_port_configuration_agent
;
109
typedef
void
(*
port_config_fn
)(
struct
isci_host
*,
110
struct
sci_port_configuration_agent
*,
111
struct
isci_port
*,
struct
isci_phy
*);
112
bool
is_port_config_apc
(
struct
isci_host
*ihost);
113
bool
is_controller_start_complete
(
struct
isci_host
*ihost);
114
115
struct
sci_port_configuration_agent
{
116
u16
phy_configured_mask
;
117
u16
phy_ready_mask
;
118
struct
{
119
u8
min_index
;
120
u8
max_index
;
121
}
phy_valid_port_range
[
SCI_MAX_PHYS
];
122
bool
timer_pending
;
123
port_config_fn
link_up_handler
;
124
port_config_fn
link_down_handler
;
125
struct
sci_timer
timer
;
126
};
127
149
struct
isci_host
{
150
struct
sci_base_state_machine
sm
;
151
/* XXX can we time this externally */
152
struct
sci_timer
timer
;
153
/* XXX drop reference module params directly */
154
struct
sci_user_parameters
user_parameters
;
155
/* XXX no need to be a union */
156
struct
sci_oem_params
oem_parameters
;
157
struct
sci_port_configuration_agent
port_agent
;
158
struct
isci_remote_device
*
device_table
[
SCI_MAX_REMOTE_DEVICES
];
159
struct
sci_remote_node_table
available_remote_nodes
;
160
struct
sci_power_control
power_control
;
161
u8
io_request_sequence
[
SCI_MAX_IO_REQUESTS
];
162
struct
scu_task_context
*
task_context_table
;
163
dma_addr_t
tc_dma
;
164
union
scu_remote_node_context
*
remote_node_context_table
;
165
dma_addr_t
rnc_dma
;
166
u32
*
completion_queue
;
167
dma_addr_t
cq_dma
;
168
u32
completion_queue_get
;
169
u32
logical_port_entries
;
170
u32
remote_node_entries
;
171
u32
task_context_entries
;
172
void
*
ufi_buf
;
173
dma_addr_t
ufi_dma
;
174
struct
sci_unsolicited_frame_control
uf_control
;
175
176
/* phy startup */
177
struct
sci_timer
phy_timer
;
178
/* XXX kill */
179
bool
phy_startup_timer_pending
;
180
u32
next_phy_to_start
;
181
/* XXX convert to unsigned long and use bitops */
182
u8
invalid_phy_mask
;
183
184
/* TODO attempt dynamic interrupt coalescing scheme */
185
u16
interrupt_coalesce_number
;
186
u32
interrupt_coalesce_timeout
;
187
struct
smu_registers
__iomem
*
smu_registers
;
188
struct
scu_registers
__iomem
*
scu_registers
;
189
190
u16
tci_head
;
191
u16
tci_tail
;
192
u16
tci_pool
[
SCI_MAX_IO_REQUESTS
];
193
194
int
id
;
/* unique within a given pci device */
195
struct
isci_phy
phys
[
SCI_MAX_PHYS
];
196
struct
isci_port
ports
[
SCI_MAX_PORTS
+ 1];
/* includes dummy port */
197
struct
asd_sas_port
sas_ports
[
SCI_MAX_PORTS
];
198
struct
sas_ha_struct
sas_ha
;
199
200
struct
pci_dev
*
pdev
;
201
#define IHOST_START_PENDING 0
202
#define IHOST_STOP_PENDING 1
203
#define IHOST_IRQ_ENABLED 2
204
unsigned
long
flags
;
205
wait_queue_head_t
eventq
;
206
struct
tasklet_struct
completion_tasklet
;
207
spinlock_t
scic_lock
;
208
struct
isci_request
*
reqs
[
SCI_MAX_IO_REQUESTS
];
209
struct
isci_remote_device
devices
[
SCI_MAX_REMOTE_DEVICES
];
210
};
211
216
enum
sci_controller_states
{
220
SCIC_INITIAL
= 0,
221
229
SCIC_RESET
,
230
237
SCIC_INITIALIZING
,
238
244
SCIC_INITIALIZED
,
245
251
SCIC_STARTING
,
252
258
SCIC_READY
,
259
269
SCIC_RESETTING
,
270
277
SCIC_STOPPING
,
278
287
SCIC_FAILED
,
288
};
289
295
#define SCI_MAX_MSIX_INT (SCI_NUM_MSI_X_INT*SCI_MAX_CONTROLLERS)
296
297
struct
isci_pci_info
{
298
struct
msix_entry
msix_entries
[
SCI_MAX_MSIX_INT
];
299
struct
isci_host
*
hosts
[
SCI_MAX_CONTROLLERS
];
300
struct
isci_orom
*
orom
;
301
};
302
303
static
inline
struct
isci_pci_info
*to_pci_info(
struct
pci_dev
*pdev)
304
{
305
return
pci_get_drvdata(pdev);
306
}
307
308
static
inline
struct
Scsi_Host
*to_shost(
struct
isci_host
*ihost)
309
{
310
return
ihost->
sas_ha
.core.shost;
311
}
312
313
#define for_each_isci_host(id, ihost, pdev) \
314
for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \
315
id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \
316
ihost = to_pci_info(pdev)->hosts[++id])
317
318
static
inline
void
wait_for_start
(
struct
isci_host
*ihost)
319
{
320
wait_event
(ihost->
eventq
, !
test_bit
(
IHOST_START_PENDING
, &ihost->
flags
));
321
}
322
323
static
inline
void
wait_for_stop(
struct
isci_host
*ihost)
324
{
325
wait_event
(ihost->
eventq
, !
test_bit
(
IHOST_STOP_PENDING
, &ihost->
flags
));
326
}
327
328
static
inline
void
wait_for_device_start(
struct
isci_host
*ihost,
struct
isci_remote_device
*
idev
)
329
{
330
wait_event
(ihost->
eventq
, !
test_bit
(
IDEV_START_PENDING
, &idev->
flags
));
331
}
332
333
static
inline
void
wait_for_device_stop(
struct
isci_host
*ihost,
struct
isci_remote_device
*idev)
334
{
335
wait_event
(ihost->
eventq
, !
test_bit
(
IDEV_STOP_PENDING
, &idev->
flags
));
336
}
337
338
static
inline
struct
isci_host
*dev_to_ihost(
struct
domain_device
*
dev
)
339
{
340
return
dev->
port
->ha->lldd_ha;
341
}
342
343
static
inline
struct
isci_host
*idev_to_ihost(
struct
isci_remote_device
*idev)
344
{
345
return
dev_to_ihost(idev->
domain_dev
);
346
}
347
348
/* we always use protocol engine group zero */
349
#define ISCI_PEG 0
350
351
/* see sci_controller_io_tag_allocate|free for how seq and tci are built */
352
#define ISCI_TAG(seq, tci) (((u16) (seq)) << 12 | tci)
353
354
/* these are returned by the hardware, so sanitize them */
355
#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
356
#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))
357
358
/* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */
359
#define ISCI_COALESCE_BASE 9
360
361
/* expander attached sata devices require 3 rnc slots */
362
static
inline
int
sci_remote_device_node_count(
struct
isci_remote_device
*idev)
363
{
364
struct
domain_device
*
dev
= idev->
domain_dev
;
365
366
if
(dev_is_sata(dev) && dev->
parent
)
367
return
SCU_STP_REMOTE_NODE_COUNT
;
368
return
SCU_SSP_REMOTE_NODE_COUNT
;
369
}
370
378
#define sci_controller_clear_invalid_phy(controller, phy) \
379
((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))
380
381
static
inline
struct
device
*scirdev_to_dev(
struct
isci_remote_device
*idev)
382
{
383
if
(!idev || !idev->
isci_port
|| !idev->
isci_port
->isci_host)
384
return
NULL
;
385
386
return
&idev->
isci_port
->isci_host->pdev->dev;
387
}
388
389
static
inline
bool
is_a2(
struct
pci_dev
*pdev)
390
{
391
if
(pdev->
revision
< 4)
392
return
true
;
393
return
false
;
394
}
395
396
static
inline
bool
is_b0(
struct
pci_dev
*pdev)
397
{
398
if
(pdev->
revision
== 4)
399
return
true
;
400
return
false
;
401
}
402
403
static
inline
bool
is_c0(
struct
pci_dev
*pdev)
404
{
405
if
(pdev->
revision
== 5)
406
return
true
;
407
return
false
;
408
}
409
410
static
inline
bool
is_c1(
struct
pci_dev
*pdev)
411
{
412
if
(pdev->
revision
>= 6)
413
return
true
;
414
return
false
;
415
}
416
417
enum
cable_selections
{
418
short_cable
= 0,
419
long_cable
= 1,
420
medium_cable
= 2,
421
undefined_cable
= 3
422
};
423
424
#define CABLE_OVERRIDE_DISABLED (0x10000)
425
426
static
inline
int
is_cable_select_overridden(
void
)
427
{
428
return
cable_selection_override
<
CABLE_OVERRIDE_DISABLED
;
429
}
430
431
enum
cable_selections
decode_cable_selection
(
struct
isci_host
*ihost,
int
phy
);
432
void
validate_cable_selections
(
struct
isci_host
*ihost);
433
char
*
lookup_cable_names
(
enum
cable_selections
);
434
435
/* set hw control for 'activity', even though active enclosures seem to drive
436
* the activity led on their own. Skip setting FSENG control on 'status' due
437
* to unexpected operation and 'error' due to not being a supported automatic
438
* FSENG output
439
*/
440
#define SGPIO_HW_CONTROL 0x00000443
441
442
static
inline
int
isci_gpio_count(
struct
isci_host
*ihost)
443
{
444
return
ARRAY_SIZE
(ihost->
scu_registers
->peg0.sgpio.output_data_select);
445
}
446
447
void
sci_controller_post_request
(
struct
isci_host
*ihost,
448
u32
request
);
449
void
sci_controller_release_frame
(
struct
isci_host
*ihost,
450
u32
frame_index
);
451
void
sci_controller_copy_sata_response
(
void
*response_buffer,
452
void
*frame_header,
453
void
*
frame_buffer
);
454
enum
sci_status
sci_controller_allocate_remote_node_context
(
struct
isci_host
*ihost,
455
struct
isci_remote_device
*idev,
456
u16
*
node_id
);
457
void
sci_controller_free_remote_node_context
(
458
struct
isci_host
*ihost,
459
struct
isci_remote_device
*idev,
460
u16
node_id
);
461
462
struct
isci_request
*
sci_request_by_tag
(
struct
isci_host
*ihost,
u16
io_tag
);
463
void
sci_controller_power_control_queue_insert
(
struct
isci_host
*ihost,
464
struct
isci_phy
*iphy);
465
void
sci_controller_power_control_queue_remove
(
struct
isci_host
*ihost,
466
struct
isci_phy
*iphy);
467
void
sci_controller_link_up
(
struct
isci_host
*ihost,
struct
isci_port
*iport,
468
struct
isci_phy
*iphy);
469
void
sci_controller_link_down
(
struct
isci_host
*ihost,
struct
isci_port
*iport,
470
struct
isci_phy
*iphy);
471
void
sci_controller_remote_device_stopped
(
struct
isci_host
*ihost,
472
struct
isci_remote_device
*idev);
473
474
enum
sci_status
sci_controller_continue_io
(
struct
isci_request
*ireq);
475
int
isci_host_scan_finished
(
struct
Scsi_Host
*,
unsigned
long
);
476
void
isci_host_start
(
struct
Scsi_Host
*);
477
u16
isci_alloc_tag
(
struct
isci_host
*ihost);
478
enum
sci_status
isci_free_tag
(
struct
isci_host
*ihost,
u16
io_tag
);
479
void
isci_tci_free
(
struct
isci_host
*ihost,
u16
tci);
480
void
ireq_done
(
struct
isci_host
*ihost,
struct
isci_request
*ireq,
struct
sas_task
*
task
);
481
482
int
isci_host_init
(
struct
isci_host
*);
483
void
isci_host_completion_routine
(
unsigned
long
data
);
484
void
isci_host_deinit
(
struct
isci_host
*);
485
void
sci_controller_disable_interrupts
(
struct
isci_host
*ihost);
486
bool
sci_controller_has_remote_devices_stopping
(
struct
isci_host
*ihost);
487
void
sci_controller_transition_to_ready
(
struct
isci_host
*ihost,
enum
sci_status
status
);
488
489
enum
sci_status
sci_controller_start_io
(
490
struct
isci_host
*ihost,
491
struct
isci_remote_device
*idev,
492
struct
isci_request
*ireq);
493
494
enum
sci_task_status
sci_controller_start_task
(
495
struct
isci_host
*ihost,
496
struct
isci_remote_device
*idev,
497
struct
isci_request
*ireq);
498
499
enum
sci_status
sci_controller_terminate_request
(
500
struct
isci_host
*ihost,
501
struct
isci_remote_device
*idev,
502
struct
isci_request
*ireq);
503
504
enum
sci_status
sci_controller_complete_io
(
505
struct
isci_host
*ihost,
506
struct
isci_remote_device
*idev,
507
struct
isci_request
*ireq);
508
509
void
sci_port_configuration_agent_construct
(
510
struct
sci_port_configuration_agent
*port_agent);
511
512
enum
sci_status
sci_port_configuration_agent_initialize
(
513
struct
isci_host
*ihost,
514
struct
sci_port_configuration_agent
*port_agent);
515
516
int
isci_gpio_write
(
struct
sas_ha_struct
*,
u8
reg_type,
u8
reg_index,
517
u8
reg_count,
u8
*write_data);
518
#endif
Generated on Thu Jan 10 2013 13:55:23 for Linux Kernel by
1.8.2