diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-06-01 19:00:01 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:50 -0400 |
commit | 7c78da3175177c905a75c54b5830029c778494ea (patch) | |
tree | 6b5f74e75ec0a0393ed5ed504bda78765ef66570 /drivers/scsi | |
parent | dbb0743a58825d94f1b3fdfa90a8d61dfef88f7b (diff) |
isci: remove 'min memory' infrastructure
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/isci/host.c | 305 | ||||
-rw-r--r-- | drivers/scsi/isci/host.h | 13 | ||||
-rw-r--r-- | drivers/scsi/isci/isci.h | 90 | ||||
-rw-r--r-- | drivers/scsi/isci/request.h | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/unsolicited_frame_control.c | 186 | ||||
-rw-r--r-- | drivers/scsi/isci/unsolicited_frame_control.h | 20 |
6 files changed, 144 insertions, 472 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 009c0ee83ed6..41a7c5099dea 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -70,46 +70,24 @@ | |||
70 | 70 | ||
71 | #define SCU_CONTEXT_RAM_INIT_STALL_TIME 200 | 71 | #define SCU_CONTEXT_RAM_INIT_STALL_TIME 200 |
72 | 72 | ||
73 | /** | 73 | #define smu_max_ports(dcc_value) \ |
74 | * smu_dcc_get_max_ports() - | ||
75 | * | ||
76 | * This macro returns the maximum number of logical ports supported by the | ||
77 | * hardware. The caller passes in the value read from the device context | ||
78 | * capacity register and this macro will mash and shift the value appropriately. | ||
79 | */ | ||
80 | #define smu_dcc_get_max_ports(dcc_value) \ | ||
81 | (\ | 74 | (\ |
82 | (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK) \ | 75 | (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK) \ |
83 | >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT) + 1 \ | 76 | >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT) + 1 \ |
84 | ) | 77 | ) |
85 | 78 | ||
86 | /** | 79 | #define smu_max_task_contexts(dcc_value) \ |
87 | * smu_dcc_get_max_task_context() - | ||
88 | * | ||
89 | * This macro returns the maximum number of task contexts supported by the | ||
90 | * hardware. The caller passes in the value read from the device context | ||
91 | * capacity register and this macro will mash and shift the value appropriately. | ||
92 | */ | ||
93 | #define smu_dcc_get_max_task_context(dcc_value) \ | ||
94 | (\ | 80 | (\ |
95 | (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK) \ | 81 | (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK) \ |
96 | >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT) + 1 \ | 82 | >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT) + 1 \ |
97 | ) | 83 | ) |
98 | 84 | ||
99 | /** | 85 | #define smu_max_rncs(dcc_value) \ |
100 | * smu_dcc_get_max_remote_node_context() - | ||
101 | * | ||
102 | * This macro returns the maximum number of remote node contexts supported by | ||
103 | * the hardware. The caller passes in the value read from the device context | ||
104 | * capacity register and this macro will mash and shift the value appropriately. | ||
105 | */ | ||
106 | #define smu_dcc_get_max_remote_node_context(dcc_value) \ | ||
107 | (\ | 86 | (\ |
108 | (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) \ | 87 | (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) \ |
109 | >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT) + 1 \ | 88 | >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT) + 1 \ |
110 | ) | 89 | ) |
111 | 90 | ||
112 | |||
113 | #define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 100 | 91 | #define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 100 |
114 | 92 | ||
115 | /** | 93 | /** |
@@ -153,9 +131,8 @@ | |||
153 | INCREMENT_QUEUE_GET(\ | 131 | INCREMENT_QUEUE_GET(\ |
154 | (index), \ | 132 | (index), \ |
155 | (cycle), \ | 133 | (cycle), \ |
156 | (controller)->completion_queue_entries, \ | 134 | SCU_MAX_COMPLETION_QUEUE_ENTRIES, \ |
157 | SMU_CQGR_CYCLE_BIT \ | 135 | SMU_CQGR_CYCLE_BIT) |
158 | ) | ||
159 | 136 | ||
160 | /** | 137 | /** |
161 | * INCREMENT_EVENT_QUEUE_GET() - | 138 | * INCREMENT_EVENT_QUEUE_GET() - |
@@ -167,7 +144,7 @@ | |||
167 | INCREMENT_QUEUE_GET(\ | 144 | INCREMENT_QUEUE_GET(\ |
168 | (index), \ | 145 | (index), \ |
169 | (cycle), \ | 146 | (cycle), \ |
170 | (controller)->completion_event_entries, \ | 147 | SCU_MAX_EVENTS, \ |
171 | SMU_CQGR_EVENT_CYCLE_BIT \ | 148 | SMU_CQGR_EVENT_CYCLE_BIT \ |
172 | ) | 149 | ) |
173 | 150 | ||
@@ -843,10 +820,9 @@ static void scic_sds_controller_initialize_completion_queue(struct scic_sds_cont | |||
843 | 820 | ||
844 | scic->completion_queue_get = 0; | 821 | scic->completion_queue_get = 0; |
845 | 822 | ||
846 | completion_queue_control_value = ( | 823 | completion_queue_control_value = |
847 | SMU_CQC_QUEUE_LIMIT_SET(scic->completion_queue_entries - 1) | 824 | (SMU_CQC_QUEUE_LIMIT_SET(SCU_MAX_COMPLETION_QUEUE_ENTRIES - 1) | |
848 | | SMU_CQC_EVENT_LIMIT_SET(scic->completion_event_entries - 1) | 825 | SMU_CQC_EVENT_LIMIT_SET(SCU_MAX_EVENTS - 1)); |
849 | ); | ||
850 | 826 | ||
851 | writel(completion_queue_control_value, | 827 | writel(completion_queue_control_value, |
852 | &scic->smu_registers->completion_queue_control); | 828 | &scic->smu_registers->completion_queue_control); |
@@ -873,7 +849,7 @@ static void scic_sds_controller_initialize_completion_queue(struct scic_sds_cont | |||
873 | &scic->smu_registers->completion_queue_put); | 849 | &scic->smu_registers->completion_queue_put); |
874 | 850 | ||
875 | /* Initialize the cycle bit of the completion queue entries */ | 851 | /* Initialize the cycle bit of the completion queue entries */ |
876 | for (index = 0; index < scic->completion_queue_entries; index++) { | 852 | for (index = 0; index < SCU_MAX_COMPLETION_QUEUE_ENTRIES; index++) { |
877 | /* | 853 | /* |
878 | * If get.cycle_bit != completion_queue.cycle_bit | 854 | * If get.cycle_bit != completion_queue.cycle_bit |
879 | * its not a valid completion queue entry | 855 | * its not a valid completion queue entry |
@@ -890,8 +866,7 @@ static void scic_sds_controller_initialize_unsolicited_frame_queue(struct scic_s | |||
890 | 866 | ||
891 | /* Write the queue size */ | 867 | /* Write the queue size */ |
892 | frame_queue_control_value = | 868 | frame_queue_control_value = |
893 | SCU_UFQC_GEN_VAL(QUEUE_SIZE, | 869 | SCU_UFQC_GEN_VAL(QUEUE_SIZE, SCU_MAX_UNSOLICITED_FRAMES); |
894 | scic->uf_control.address_table.count); | ||
895 | 870 | ||
896 | writel(frame_queue_control_value, | 871 | writel(frame_queue_control_value, |
897 | &scic->scu_registers->sdma.unsolicited_frame_queue_control); | 872 | &scic->scu_registers->sdma.unsolicited_frame_queue_control); |
@@ -1863,15 +1838,6 @@ static enum sci_status scic_controller_construct(struct scic_sds_controller *sci | |||
1863 | 1838 | ||
1864 | sci_init_timer(&scic->timer, controller_timeout); | 1839 | sci_init_timer(&scic->timer, controller_timeout); |
1865 | 1840 | ||
1866 | /* Set the default maximum values */ | ||
1867 | scic->completion_event_entries = SCU_EVENT_COUNT; | ||
1868 | scic->completion_queue_entries = SCU_COMPLETION_QUEUE_COUNT; | ||
1869 | scic->remote_node_entries = SCI_MAX_REMOTE_DEVICES; | ||
1870 | scic->logical_port_entries = SCI_MAX_PORTS; | ||
1871 | scic->task_context_entries = SCU_IO_REQUEST_COUNT; | ||
1872 | scic->uf_control.buffers.count = SCU_UNSOLICITED_FRAME_COUNT; | ||
1873 | scic->uf_control.address_table.count = SCU_UNSOLICITED_FRAME_COUNT; | ||
1874 | |||
1875 | /* Initialize the User and OEM parameters to default values. */ | 1841 | /* Initialize the User and OEM parameters to default values. */ |
1876 | scic_sds_controller_set_default_config_parameters(scic); | 1842 | scic_sds_controller_set_default_config_parameters(scic); |
1877 | 1843 | ||
@@ -2207,44 +2173,6 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s | |||
2207 | udelay(AFE_REGISTER_WRITE_DELAY); | 2173 | udelay(AFE_REGISTER_WRITE_DELAY); |
2208 | } | 2174 | } |
2209 | 2175 | ||
2210 | static enum sci_status scic_controller_set_mode(struct scic_sds_controller *scic, | ||
2211 | enum sci_controller_mode operating_mode) | ||
2212 | { | ||
2213 | enum sci_status status = SCI_SUCCESS; | ||
2214 | |||
2215 | if ((scic->sm.current_state_id == SCIC_INITIALIZING) || | ||
2216 | (scic->sm.current_state_id == SCIC_INITIALIZED)) { | ||
2217 | switch (operating_mode) { | ||
2218 | case SCI_MODE_SPEED: | ||
2219 | scic->remote_node_entries = SCI_MAX_REMOTE_DEVICES; | ||
2220 | scic->task_context_entries = SCU_IO_REQUEST_COUNT; | ||
2221 | scic->uf_control.buffers.count = | ||
2222 | SCU_UNSOLICITED_FRAME_COUNT; | ||
2223 | scic->completion_event_entries = SCU_EVENT_COUNT; | ||
2224 | scic->completion_queue_entries = | ||
2225 | SCU_COMPLETION_QUEUE_COUNT; | ||
2226 | break; | ||
2227 | |||
2228 | case SCI_MODE_SIZE: | ||
2229 | scic->remote_node_entries = SCI_MIN_REMOTE_DEVICES; | ||
2230 | scic->task_context_entries = SCI_MIN_IO_REQUESTS; | ||
2231 | scic->uf_control.buffers.count = | ||
2232 | SCU_MIN_UNSOLICITED_FRAMES; | ||
2233 | scic->completion_event_entries = SCU_MIN_EVENTS; | ||
2234 | scic->completion_queue_entries = | ||
2235 | SCU_MIN_COMPLETION_QUEUE_ENTRIES; | ||
2236 | break; | ||
2237 | |||
2238 | default: | ||
2239 | status = SCI_FAILURE_INVALID_PARAMETER_VALUE; | ||
2240 | break; | ||
2241 | } | ||
2242 | } else | ||
2243 | status = SCI_FAILURE_INVALID_STATE; | ||
2244 | |||
2245 | return status; | ||
2246 | } | ||
2247 | |||
2248 | static void scic_sds_controller_initialize_power_control(struct scic_sds_controller *scic) | 2176 | static void scic_sds_controller_initialize_power_control(struct scic_sds_controller *scic) |
2249 | { | 2177 | { |
2250 | sci_init_timer(&scic->power_control.timer, power_control_timeout); | 2178 | sci_init_timer(&scic->power_control.timer, power_control_timeout); |
@@ -2259,9 +2187,9 @@ static void scic_sds_controller_initialize_power_control(struct scic_sds_control | |||
2259 | static enum sci_status scic_controller_initialize(struct scic_sds_controller *scic) | 2187 | static enum sci_status scic_controller_initialize(struct scic_sds_controller *scic) |
2260 | { | 2188 | { |
2261 | struct sci_base_state_machine *sm = &scic->sm; | 2189 | struct sci_base_state_machine *sm = &scic->sm; |
2262 | enum sci_status result = SCI_SUCCESS; | ||
2263 | struct isci_host *ihost = scic_to_ihost(scic); | 2190 | struct isci_host *ihost = scic_to_ihost(scic); |
2264 | u32 index, state; | 2191 | enum sci_status result = SCI_FAILURE; |
2192 | unsigned long i, state, val; | ||
2265 | 2193 | ||
2266 | if (scic->sm.current_state_id != SCIC_RESET) { | 2194 | if (scic->sm.current_state_id != SCIC_RESET) { |
2267 | dev_warn(scic_to_dev(scic), | 2195 | dev_warn(scic_to_dev(scic), |
@@ -2286,133 +2214,81 @@ static enum sci_status scic_controller_initialize(struct scic_sds_controller *sc | |||
2286 | * / presently they seem to be wrong. */ | 2214 | * / presently they seem to be wrong. */ |
2287 | scic_sds_controller_afe_initialization(scic); | 2215 | scic_sds_controller_afe_initialization(scic); |
2288 | 2216 | ||
2289 | if (result == SCI_SUCCESS) { | ||
2290 | u32 status; | ||
2291 | u32 terminate_loop; | ||
2292 | |||
2293 | /* Take the hardware out of reset */ | ||
2294 | writel(0, &scic->smu_registers->soft_reset_control); | ||
2295 | 2217 | ||
2296 | /* | 2218 | /* Take the hardware out of reset */ |
2297 | * / @todo Provide meaningfull error code for hardware failure | 2219 | writel(0, &scic->smu_registers->soft_reset_control); |
2298 | * result = SCI_FAILURE_CONTROLLER_HARDWARE; */ | ||
2299 | result = SCI_FAILURE; | ||
2300 | terminate_loop = 100; | ||
2301 | |||
2302 | while (terminate_loop-- && (result != SCI_SUCCESS)) { | ||
2303 | /* Loop until the hardware reports success */ | ||
2304 | udelay(SCU_CONTEXT_RAM_INIT_STALL_TIME); | ||
2305 | status = readl(&scic->smu_registers->control_status); | ||
2306 | |||
2307 | if ((status & SCU_RAM_INIT_COMPLETED) == | ||
2308 | SCU_RAM_INIT_COMPLETED) | ||
2309 | result = SCI_SUCCESS; | ||
2310 | } | ||
2311 | } | ||
2312 | |||
2313 | if (result == SCI_SUCCESS) { | ||
2314 | u32 max_supported_ports; | ||
2315 | u32 max_supported_devices; | ||
2316 | u32 max_supported_io_requests; | ||
2317 | u32 device_context_capacity; | ||
2318 | 2220 | ||
2319 | /* | 2221 | /* |
2320 | * Determine what are the actaul device capacities that the | 2222 | * / @todo Provide meaningfull error code for hardware failure |
2321 | * hardware will support */ | 2223 | * result = SCI_FAILURE_CONTROLLER_HARDWARE; */ |
2322 | device_context_capacity = | 2224 | for (i = 100; i >= 1; i--) { |
2323 | readl(&scic->smu_registers->device_context_capacity); | 2225 | u32 status; |
2324 | |||
2325 | |||
2326 | max_supported_ports = smu_dcc_get_max_ports(device_context_capacity); | ||
2327 | max_supported_devices = smu_dcc_get_max_remote_node_context(device_context_capacity); | ||
2328 | max_supported_io_requests = smu_dcc_get_max_task_context(device_context_capacity); | ||
2329 | 2226 | ||
2330 | /* | 2227 | /* Loop until the hardware reports success */ |
2331 | * Make all PEs that are unassigned match up with the | 2228 | udelay(SCU_CONTEXT_RAM_INIT_STALL_TIME); |
2332 | * logical ports | 2229 | status = readl(&scic->smu_registers->control_status); |
2333 | */ | ||
2334 | for (index = 0; index < max_supported_ports; index++) { | ||
2335 | struct scu_port_task_scheduler_group_registers __iomem | ||
2336 | *ptsg = &scic->scu_registers->peg0.ptsg; | ||
2337 | 2230 | ||
2338 | writel(index, &ptsg->protocol_engine[index]); | 2231 | if ((status & SCU_RAM_INIT_COMPLETED) == SCU_RAM_INIT_COMPLETED) |
2339 | } | 2232 | break; |
2233 | } | ||
2234 | if (i == 0) | ||
2235 | goto out; | ||
2340 | 2236 | ||
2341 | /* Record the smaller of the two capacity values */ | 2237 | /* |
2342 | scic->logical_port_entries = | 2238 | * Determine what are the actaul device capacities that the |
2343 | min(max_supported_ports, scic->logical_port_entries); | 2239 | * hardware will support */ |
2240 | val = readl(&scic->smu_registers->device_context_capacity); | ||
2344 | 2241 | ||
2345 | scic->task_context_entries = | 2242 | /* Record the smaller of the two capacity values */ |
2346 | min(max_supported_io_requests, | 2243 | scic->logical_port_entries = min(smu_max_ports(val), SCI_MAX_PORTS); |
2347 | scic->task_context_entries); | 2244 | scic->task_context_entries = min(smu_max_task_contexts(val), SCI_MAX_IO_REQUESTS); |
2245 | scic->remote_node_entries = min(smu_max_rncs(val), SCI_MAX_REMOTE_DEVICES); | ||
2348 | 2246 | ||
2349 | scic->remote_node_entries = | 2247 | /* |
2350 | min(max_supported_devices, scic->remote_node_entries); | 2248 | * Make all PEs that are unassigned match up with the |
2249 | * logical ports | ||
2250 | */ | ||
2251 | for (i = 0; i < scic->logical_port_entries; i++) { | ||
2252 | struct scu_port_task_scheduler_group_registers __iomem | ||
2253 | *ptsg = &scic->scu_registers->peg0.ptsg; | ||
2351 | 2254 | ||
2352 | /* | 2255 | writel(i, &ptsg->protocol_engine[i]); |
2353 | * Now that we have the correct hardware reported minimum values | ||
2354 | * build the MDL for the controller. Default to a performance | ||
2355 | * configuration. | ||
2356 | */ | ||
2357 | scic_controller_set_mode(scic, SCI_MODE_SPEED); | ||
2358 | } | 2256 | } |
2359 | 2257 | ||
2360 | /* Initialize hardware PCI Relaxed ordering in DMA engines */ | 2258 | /* Initialize hardware PCI Relaxed ordering in DMA engines */ |
2361 | if (result == SCI_SUCCESS) { | 2259 | val = readl(&scic->scu_registers->sdma.pdma_configuration); |
2362 | u32 dma_configuration; | 2260 | val |= SCU_PDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE); |
2363 | 2261 | writel(val, &scic->scu_registers->sdma.pdma_configuration); | |
2364 | /* Configure the payload DMA */ | 2262 | |
2365 | dma_configuration = | 2263 | val = readl(&scic->scu_registers->sdma.cdma_configuration); |
2366 | readl(&scic->scu_registers->sdma.pdma_configuration); | 2264 | val |= SCU_CDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE); |
2367 | dma_configuration |= | 2265 | writel(val, &scic->scu_registers->sdma.cdma_configuration); |
2368 | SCU_PDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE); | ||
2369 | writel(dma_configuration, | ||
2370 | &scic->scu_registers->sdma.pdma_configuration); | ||
2371 | |||
2372 | /* Configure the control DMA */ | ||
2373 | dma_configuration = | ||
2374 | readl(&scic->scu_registers->sdma.cdma_configuration); | ||
2375 | dma_configuration |= | ||
2376 | SCU_CDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE); | ||
2377 | writel(dma_configuration, | ||
2378 | &scic->scu_registers->sdma.cdma_configuration); | ||
2379 | } | ||
2380 | 2266 | ||
2381 | /* | 2267 | /* |
2382 | * Initialize the PHYs before the PORTs because the PHY registers | 2268 | * Initialize the PHYs before the PORTs because the PHY registers |
2383 | * are accessed during the port initialization. | 2269 | * are accessed during the port initialization. |
2384 | */ | 2270 | */ |
2385 | if (result == SCI_SUCCESS) { | 2271 | for (i = 0; i < SCI_MAX_PHYS; i++) { |
2386 | /* Initialize the phys */ | 2272 | result = scic_sds_phy_initialize(&ihost->phys[i].sci, |
2387 | for (index = 0; | 2273 | &scic->scu_registers->peg0.pe[i].tl, |
2388 | (result == SCI_SUCCESS) && (index < SCI_MAX_PHYS); | 2274 | &scic->scu_registers->peg0.pe[i].ll); |
2389 | index++) { | 2275 | if (result != SCI_SUCCESS) |
2390 | result = scic_sds_phy_initialize( | 2276 | goto out; |
2391 | &ihost->phys[index].sci, | ||
2392 | &scic->scu_registers->peg0.pe[index].tl, | ||
2393 | &scic->scu_registers->peg0.pe[index].ll); | ||
2394 | } | ||
2395 | } | 2277 | } |
2396 | 2278 | ||
2397 | if (result == SCI_SUCCESS) { | 2279 | for (i = 0; i < scic->logical_port_entries; i++) { |
2398 | /* Initialize the logical ports */ | 2280 | result = scic_sds_port_initialize(&ihost->ports[i].sci, |
2399 | for (index = 0; | 2281 | &scic->scu_registers->peg0.ptsg.port[i], |
2400 | (index < scic->logical_port_entries) && | 2282 | &scic->scu_registers->peg0.ptsg.protocol_engine, |
2401 | (result == SCI_SUCCESS); | 2283 | &scic->scu_registers->peg0.viit[i]); |
2402 | index++) { | 2284 | |
2403 | result = scic_sds_port_initialize( | 2285 | if (result != SCI_SUCCESS) |
2404 | &ihost->ports[index].sci, | 2286 | goto out; |
2405 | &scic->scu_registers->peg0.ptsg.port[index], | ||
2406 | &scic->scu_registers->peg0.ptsg.protocol_engine, | ||
2407 | &scic->scu_registers->peg0.viit[index]); | ||
2408 | } | ||
2409 | } | 2287 | } |
2410 | 2288 | ||
2411 | if (result == SCI_SUCCESS) | 2289 | result = scic_sds_port_configuration_agent_initialize(scic, &scic->port_agent); |
2412 | result = scic_sds_port_configuration_agent_initialize( | ||
2413 | scic, | ||
2414 | &scic->port_agent); | ||
2415 | 2290 | ||
2291 | out: | ||
2416 | /* Advance the controller state machine */ | 2292 | /* Advance the controller state machine */ |
2417 | if (result == SCI_SUCCESS) | 2293 | if (result == SCI_SUCCESS) |
2418 | state = SCIC_INITIALIZED; | 2294 | state = SCIC_INITIALIZED; |
@@ -2480,47 +2356,38 @@ static enum sci_status scic_user_parameters_set( | |||
2480 | static int scic_controller_mem_init(struct scic_sds_controller *scic) | 2356 | static int scic_controller_mem_init(struct scic_sds_controller *scic) |
2481 | { | 2357 | { |
2482 | struct device *dev = scic_to_dev(scic); | 2358 | struct device *dev = scic_to_dev(scic); |
2483 | dma_addr_t dma_handle; | 2359 | dma_addr_t dma; |
2484 | enum sci_status result; | 2360 | size_t size; |
2361 | int err; | ||
2485 | 2362 | ||
2486 | scic->completion_queue = dmam_alloc_coherent(dev, | 2363 | size = SCU_MAX_COMPLETION_QUEUE_ENTRIES * sizeof(u32); |
2487 | scic->completion_queue_entries * sizeof(u32), | 2364 | scic->completion_queue = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL); |
2488 | &dma_handle, GFP_KERNEL); | ||
2489 | if (!scic->completion_queue) | 2365 | if (!scic->completion_queue) |
2490 | return -ENOMEM; | 2366 | return -ENOMEM; |
2491 | 2367 | ||
2492 | writel(lower_32_bits(dma_handle), | 2368 | writel(lower_32_bits(dma), &scic->smu_registers->completion_queue_lower); |
2493 | &scic->smu_registers->completion_queue_lower); | 2369 | writel(upper_32_bits(dma), &scic->smu_registers->completion_queue_upper); |
2494 | writel(upper_32_bits(dma_handle), | ||
2495 | &scic->smu_registers->completion_queue_upper); | ||
2496 | 2370 | ||
2497 | scic->remote_node_context_table = dmam_alloc_coherent(dev, | 2371 | size = scic->remote_node_entries * sizeof(union scu_remote_node_context); |
2498 | scic->remote_node_entries * | 2372 | scic->remote_node_context_table = dmam_alloc_coherent(dev, size, &dma, |
2499 | sizeof(union scu_remote_node_context), | 2373 | GFP_KERNEL); |
2500 | &dma_handle, GFP_KERNEL); | ||
2501 | if (!scic->remote_node_context_table) | 2374 | if (!scic->remote_node_context_table) |
2502 | return -ENOMEM; | 2375 | return -ENOMEM; |
2503 | 2376 | ||
2504 | writel(lower_32_bits(dma_handle), | 2377 | writel(lower_32_bits(dma), &scic->smu_registers->remote_node_context_lower); |
2505 | &scic->smu_registers->remote_node_context_lower); | 2378 | writel(upper_32_bits(dma), &scic->smu_registers->remote_node_context_upper); |
2506 | writel(upper_32_bits(dma_handle), | ||
2507 | &scic->smu_registers->remote_node_context_upper); | ||
2508 | 2379 | ||
2509 | scic->task_context_table = dmam_alloc_coherent(dev, | 2380 | size = scic->task_context_entries * sizeof(struct scu_task_context), |
2510 | scic->task_context_entries * | 2381 | scic->task_context_table = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL); |
2511 | sizeof(struct scu_task_context), | ||
2512 | &dma_handle, GFP_KERNEL); | ||
2513 | if (!scic->task_context_table) | 2382 | if (!scic->task_context_table) |
2514 | return -ENOMEM; | 2383 | return -ENOMEM; |
2515 | 2384 | ||
2516 | writel(lower_32_bits(dma_handle), | 2385 | writel(lower_32_bits(dma), &scic->smu_registers->host_task_table_lower); |
2517 | &scic->smu_registers->host_task_table_lower); | 2386 | writel(upper_32_bits(dma), &scic->smu_registers->host_task_table_upper); |
2518 | writel(upper_32_bits(dma_handle), | ||
2519 | &scic->smu_registers->host_task_table_upper); | ||
2520 | 2387 | ||
2521 | result = scic_sds_unsolicited_frame_control_construct(scic); | 2388 | err = scic_sds_unsolicited_frame_control_construct(scic); |
2522 | if (result) | 2389 | if (err) |
2523 | return result; | 2390 | return err; |
2524 | 2391 | ||
2525 | /* | 2392 | /* |
2526 | * Inform the silicon as to the location of the UF headers and | 2393 | * Inform the silicon as to the location of the UF headers and |
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 04698dd75ad6..740350043d89 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -240,18 +240,6 @@ struct scic_sds_controller { | |||
240 | u32 logical_port_entries; | 240 | u32 logical_port_entries; |
241 | 241 | ||
242 | /** | 242 | /** |
243 | * This field is the minimum number of hardware supported completion queue | ||
244 | * entries and the software requested completion queue entries. | ||
245 | */ | ||
246 | u32 completion_queue_entries; | ||
247 | |||
248 | /** | ||
249 | * This field is the minimum number of hardware supported event entries and | ||
250 | * the software requested event entries. | ||
251 | */ | ||
252 | u32 completion_event_entries; | ||
253 | |||
254 | /** | ||
255 | * This field is the minimum number of devices supported by the hardware and | 243 | * This field is the minimum number of devices supported by the hardware and |
256 | * the number of devices requested by the software. | 244 | * the number of devices requested by the software. |
257 | */ | 245 | */ |
@@ -325,7 +313,6 @@ struct isci_host { | |||
325 | union scic_oem_parameters oem_parameters; | 313 | union scic_oem_parameters oem_parameters; |
326 | 314 | ||
327 | int id; /* unique within a given pci device */ | 315 | int id; /* unique within a given pci device */ |
328 | void *core_ctrl_memory; | ||
329 | struct dma_pool *dma_pool; | 316 | struct dma_pool *dma_pool; |
330 | struct isci_phy phys[SCI_MAX_PHYS]; | 317 | struct isci_phy phys[SCI_MAX_PHYS]; |
331 | struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ | 318 | struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ |
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h index 80cfb45f8da1..714ed926171b 100644 --- a/drivers/scsi/isci/isci.h +++ b/drivers/scsi/isci/isci.h | |||
@@ -78,39 +78,16 @@ enum sci_controller_mode { | |||
78 | SCI_MODE_SIZE /* deprecated */ | 78 | SCI_MODE_SIZE /* deprecated */ |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #define SCI_MAX_PHYS (4) | 81 | #define SCI_MAX_PHYS (4UL) |
82 | #define SCI_MAX_PORTS SCI_MAX_PHYS | 82 | #define SCI_MAX_PORTS SCI_MAX_PHYS |
83 | #define SCI_MIN_SMP_PHYS (38) | ||
84 | #define SCI_MAX_SMP_PHYS (384) /* not silicon constrained */ | 83 | #define SCI_MAX_SMP_PHYS (384) /* not silicon constrained */ |
85 | #define SCI_MAX_REMOTE_DEVICES (256) | 84 | #define SCI_MAX_REMOTE_DEVICES (256UL) |
86 | #define SCI_MIN_REMOTE_DEVICES (16) | 85 | #define SCI_MAX_IO_REQUESTS (256UL) |
87 | #define SCI_MAX_IO_REQUESTS (256) | ||
88 | #define SCI_MIN_IO_REQUESTS (1) | ||
89 | #define SCI_MAX_MSIX_MESSAGES (2) | 86 | #define SCI_MAX_MSIX_MESSAGES (2) |
90 | #define SCI_MAX_SCATTER_GATHER_ELEMENTS 130 /* not silicon constrained */ | 87 | #define SCI_MAX_SCATTER_GATHER_ELEMENTS 130 /* not silicon constrained */ |
91 | #define SCI_MIN_SCATTER_GATHER_ELEMENTS 1 | ||
92 | #define SCI_MAX_CONTROLLERS 2 | 88 | #define SCI_MAX_CONTROLLERS 2 |
93 | #define SCI_MAX_DOMAINS SCI_MAX_PORTS | 89 | #define SCI_MAX_DOMAINS SCI_MAX_PORTS |
94 | 90 | ||
95 | /* 2 indicates the maximum number of UFs that can occur for a given IO request. | ||
96 | * The hardware handles reception of additional unsolicited frames while all | ||
97 | * UFs are in use, by holding off the transmitting device. This number could | ||
98 | * be theoretically reduced to 1, but 2 provides for more reliable operation. | ||
99 | * During SATA PIO operation, it is possible under some conditions for there to | ||
100 | * be 3 separate FISes received, back to back to back (PIO Setup, Data, D2H | ||
101 | * Register). It is unlikely to have all 3 pending all at once without some of | ||
102 | * them already being processed. | ||
103 | */ | ||
104 | #define SCU_MIN_UNSOLICITED_FRAMES (1) | ||
105 | #define SCU_MIN_CRITICAL_NOTIFICATIONS (24) | ||
106 | #define SCU_MIN_EVENTS (4) | ||
107 | #define SCU_MIN_COMPLETION_QUEUE_SCRATCH (2) | ||
108 | #define SCU_MIN_COMPLETION_QUEUE_ENTRIES (SCU_MIN_CRITICAL_NOTIFICATIONS \ | ||
109 | + SCU_MIN_EVENTS \ | ||
110 | + SCU_MIN_UNSOLICITED_FRAMES \ | ||
111 | + SCI_MIN_IO_REQUESTS \ | ||
112 | + SCU_MIN_COMPLETION_QUEUE_SCRATCH) | ||
113 | |||
114 | #define SCU_MAX_CRITICAL_NOTIFICATIONS (384) | 91 | #define SCU_MAX_CRITICAL_NOTIFICATIONS (384) |
115 | #define SCU_MAX_EVENTS (128) | 92 | #define SCU_MAX_EVENTS (128) |
116 | #define SCU_MAX_UNSOLICITED_FRAMES (128) | 93 | #define SCU_MAX_UNSOLICITED_FRAMES (128) |
@@ -121,51 +98,6 @@ enum sci_controller_mode { | |||
121 | + SCI_MAX_IO_REQUESTS \ | 98 | + SCI_MAX_IO_REQUESTS \ |
122 | + SCU_MAX_COMPLETION_QUEUE_SCRATCH) | 99 | + SCU_MAX_COMPLETION_QUEUE_SCRATCH) |
123 | 100 | ||
124 | #if !defined(ENABLE_MINIMUM_MEMORY_MODE) | ||
125 | #define SCU_UNSOLICITED_FRAME_COUNT SCU_MAX_UNSOLICITED_FRAMES | ||
126 | #define SCU_CRITICAL_NOTIFICATION_COUNT SCU_MAX_CRITICAL_NOTIFICATIONS | ||
127 | #define SCU_EVENT_COUNT SCU_MAX_EVENTS | ||
128 | #define SCU_COMPLETION_QUEUE_SCRATCH SCU_MAX_COMPLETION_QUEUE_SCRATCH | ||
129 | #define SCU_IO_REQUEST_COUNT SCI_MAX_IO_REQUESTS | ||
130 | #define SCU_IO_REQUEST_SGE_COUNT SCI_MAX_SCATTER_GATHER_ELEMENTS | ||
131 | #define SCU_COMPLETION_QUEUE_COUNT SCU_MAX_COMPLETION_QUEUE_ENTRIES | ||
132 | #else | ||
133 | #define SCU_UNSOLICITED_FRAME_COUNT SCU_MIN_UNSOLICITED_FRAMES | ||
134 | #define SCU_CRITICAL_NOTIFICATION_COUNT SCU_MIN_CRITICAL_NOTIFICATIONS | ||
135 | #define SCU_EVENT_COUNT SCU_MIN_EVENTS | ||
136 | #define SCU_COMPLETION_QUEUE_SCRATCH SCU_MIN_COMPLETION_QUEUE_SCRATCH | ||
137 | #define SCU_IO_REQUEST_COUNT SCI_MIN_IO_REQUESTS | ||
138 | #define SCU_IO_REQUEST_SGE_COUNT SCI_MIN_SCATTER_GATHER_ELEMENTS | ||
139 | #define SCU_COMPLETION_QUEUE_COUNT SCU_MIN_COMPLETION_QUEUE_ENTRIES | ||
140 | #endif /* !defined(ENABLE_MINIMUM_MEMORY_OPERATION) */ | ||
141 | |||
142 | /** | ||
143 | * | ||
144 | * | ||
145 | * The SCU_COMPLETION_QUEUE_COUNT constant indicates the size of the completion | ||
146 | * queue into which the hardware DMAs 32-bit quantas (completion entries). | ||
147 | */ | ||
148 | |||
149 | /** | ||
150 | * | ||
151 | * | ||
152 | * This queue must be programmed to a power of 2 size (e.g. 32, 64, 1024, etc.). | ||
153 | */ | ||
154 | #if (SCU_COMPLETION_QUEUE_COUNT != 16) && \ | ||
155 | (SCU_COMPLETION_QUEUE_COUNT != 32) && \ | ||
156 | (SCU_COMPLETION_QUEUE_COUNT != 64) && \ | ||
157 | (SCU_COMPLETION_QUEUE_COUNT != 128) && \ | ||
158 | (SCU_COMPLETION_QUEUE_COUNT != 256) && \ | ||
159 | (SCU_COMPLETION_QUEUE_COUNT != 512) && \ | ||
160 | (SCU_COMPLETION_QUEUE_COUNT != 1024) | ||
161 | #error "SCU_COMPLETION_QUEUE_COUNT must be set to a power of 2." | ||
162 | #endif | ||
163 | |||
164 | #if SCU_MIN_UNSOLICITED_FRAMES > SCU_MAX_UNSOLICITED_FRAMES | ||
165 | #error "Invalid configuration of unsolicited frame constants" | ||
166 | #endif /* SCU_MIN_UNSOLICITED_FRAMES > SCU_MAX_UNSOLICITED_FRAMES */ | ||
167 | |||
168 | #define SCU_MIN_UF_TABLE_ENTRIES (8) | ||
169 | #define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096) | 101 | #define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096) |
170 | #define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024) | 102 | #define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024) |
171 | #define SCU_INVALID_FRAME_INDEX (0xFFFF) | 103 | #define SCU_INVALID_FRAME_INDEX (0xFFFF) |
@@ -173,14 +105,14 @@ enum sci_controller_mode { | |||
173 | #define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF) | 105 | #define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF) |
174 | #define SCU_IO_REQUEST_MAX_TRANSFER_LENGTH (0x00FFFFFF) | 106 | #define SCU_IO_REQUEST_MAX_TRANSFER_LENGTH (0x00FFFFFF) |
175 | 107 | ||
176 | /* | 108 | static inline void check_sizes(void) |
177 | * Determine the size of the unsolicited frame array including | 109 | { |
178 | * unused buffers. */ | 110 | BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_EVENTS); |
179 | #if SCU_UNSOLICITED_FRAME_COUNT <= SCU_MIN_UF_TABLE_ENTRIES | 111 | BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES <= 8); |
180 | #define SCU_UNSOLICITED_FRAME_CONTROL_ARRAY_SIZE SCU_MIN_UF_TABLE_ENTRIES | 112 | BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_UNSOLICITED_FRAMES); |
181 | #else | 113 | BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_COMPLETION_QUEUE_ENTRIES); |
182 | #define SCU_UNSOLICITED_FRAME_CONTROL_ARRAY_SIZE SCU_MAX_UNSOLICITED_FRAMES | 114 | BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES > SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES); |
183 | #endif /* SCU_UNSOLICITED_FRAME_COUNT <= SCU_MIN_UF_TABLE_ENTRIES */ | 115 | } |
184 | 116 | ||
185 | /** | 117 | /** |
186 | * enum sci_status - This is the general return status enumeration for non-IO, | 118 | * enum sci_status - This is the general return status enumeration for non-IO, |
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index 757cd99ae2ed..547c35cbe459 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -213,7 +213,7 @@ struct scic_sds_request { | |||
213 | struct scu_task_context tc ____cacheline_aligned; | 213 | struct scu_task_context tc ____cacheline_aligned; |
214 | 214 | ||
215 | /* could be larger with sg chaining */ | 215 | /* could be larger with sg chaining */ |
216 | #define SCU_SGL_SIZE ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2) | 216 | #define SCU_SGL_SIZE ((SCI_MAX_SCATTER_GATHER_ELEMENTS + 1) / 2) |
217 | struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32))); | 217 | struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32))); |
218 | 218 | ||
219 | /* | 219 | /* |
diff --git a/drivers/scsi/isci/unsolicited_frame_control.c b/drivers/scsi/isci/unsolicited_frame_control.c index 12e676346386..d89570700ffd 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.c +++ b/drivers/scsi/isci/unsolicited_frame_control.c | |||
@@ -57,120 +57,30 @@ | |||
57 | #include "unsolicited_frame_control.h" | 57 | #include "unsolicited_frame_control.h" |
58 | #include "registers.h" | 58 | #include "registers.h" |
59 | 59 | ||
60 | /** | ||
61 | * This method will program the unsolicited frames (UFs) into the UF address | ||
62 | * table and construct the UF frame structure being modeled in the core. It | ||
63 | * will handle the case where some of the UFs are not being used and thus | ||
64 | * should have entries programmed to zero in the address table. | ||
65 | * @uf_control: This parameter specifies the unsolicted frame control object | ||
66 | * for which to construct the unsolicited frames objects. | ||
67 | * @uf_buffer_phys_address: This parameter specifies the physical address for | ||
68 | * the first unsolicited frame buffer. | ||
69 | * @uf_buffer_virt_address: This parameter specifies the virtual address for | ||
70 | * the first unsolicited frame buffer. | ||
71 | * @unused_uf_header_entries: This parameter specifies the number of unused UF | ||
72 | * headers. This value can be non-zero when there are a non-power of 2 | ||
73 | * number of unsolicited frames being supported. | ||
74 | * @used_uf_header_entries: This parameter specifies the number of actually | ||
75 | * utilized UF headers. | ||
76 | * | ||
77 | */ | ||
78 | static void scic_sds_unsolicited_frame_control_construct_frames( | ||
79 | struct scic_sds_unsolicited_frame_control *uf_control, | ||
80 | dma_addr_t uf_buffer_phys_address, | ||
81 | void *uf_buffer_virt_address, | ||
82 | u32 unused_uf_header_entries, | ||
83 | u32 used_uf_header_entries) | ||
84 | { | ||
85 | u32 index; | ||
86 | struct scic_sds_unsolicited_frame *uf; | ||
87 | |||
88 | /* | ||
89 | * Program the unused buffers into the UF address table and the | ||
90 | * controller's array of UFs. | ||
91 | */ | ||
92 | for (index = 0; index < unused_uf_header_entries; index++) { | ||
93 | uf = &uf_control->buffers.array[index]; | ||
94 | |||
95 | uf->buffer = NULL; | ||
96 | uf_control->address_table.array[index] = 0; | ||
97 | uf->header = &uf_control->headers.array[index]; | ||
98 | uf->state = UNSOLICITED_FRAME_EMPTY; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Program the actual used UF buffers into the UF address table and | ||
103 | * the controller's array of UFs. | ||
104 | */ | ||
105 | for (index = unused_uf_header_entries; | ||
106 | index < unused_uf_header_entries + used_uf_header_entries; | ||
107 | index++) { | ||
108 | uf = &uf_control->buffers.array[index]; | ||
109 | |||
110 | uf_control->address_table.array[index] = uf_buffer_phys_address; | ||
111 | |||
112 | uf->buffer = uf_buffer_virt_address; | ||
113 | uf->header = &uf_control->headers.array[index]; | ||
114 | uf->state = UNSOLICITED_FRAME_EMPTY; | ||
115 | |||
116 | /* | ||
117 | * Increment the address of the physical and virtual memory | ||
118 | * pointers. Everything is aligned on 1k boundary with an | ||
119 | * increment of 1k. | ||
120 | */ | ||
121 | uf_buffer_virt_address += SCU_UNSOLICITED_FRAME_BUFFER_SIZE; | ||
122 | uf_buffer_phys_address += SCU_UNSOLICITED_FRAME_BUFFER_SIZE; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *scic) | 60 | int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *scic) |
127 | { | 61 | { |
128 | struct scic_sds_unsolicited_frame_control *uf_control = &scic->uf_control; | 62 | struct scic_sds_unsolicited_frame_control *uf_control = &scic->uf_control; |
129 | u32 unused_uf_header_entries; | 63 | struct scic_sds_unsolicited_frame *uf; |
130 | u32 used_uf_header_entries; | 64 | u32 buf_len, header_len, i; |
131 | u32 used_uf_buffer_bytes; | 65 | dma_addr_t dma; |
132 | u32 unused_uf_header_bytes; | ||
133 | u32 used_uf_header_bytes; | ||
134 | dma_addr_t uf_buffer_phys_address; | ||
135 | void *uf_buffer_virt_address; | ||
136 | size_t size; | 66 | size_t size; |
137 | 67 | void *virt; | |
138 | /* | ||
139 | * The UF buffer address table size must be programmed to a power | ||
140 | * of 2. Find the first power of 2 that is equal to or greater then | ||
141 | * the number of unsolicited frame buffers to be utilized. | ||
142 | */ | ||
143 | uf_control->address_table.count = SCU_MIN_UF_TABLE_ENTRIES; | ||
144 | while (uf_control->address_table.count < uf_control->buffers.count && | ||
145 | uf_control->address_table.count < SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES) | ||
146 | uf_control->address_table.count <<= 1; | ||
147 | 68 | ||
148 | /* | 69 | /* |
149 | * Prepare all of the memory sizes for the UF headers, UF address | 70 | * Prepare all of the memory sizes for the UF headers, UF address |
150 | * table, and UF buffers themselves. | 71 | * table, and UF buffers themselves. |
151 | */ | 72 | */ |
152 | used_uf_buffer_bytes = uf_control->buffers.count | 73 | buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; |
153 | * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; | 74 | header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header); |
154 | unused_uf_header_entries = uf_control->address_table.count | 75 | size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t); |
155 | - uf_control->buffers.count; | ||
156 | used_uf_header_entries = uf_control->buffers.count; | ||
157 | unused_uf_header_bytes = unused_uf_header_entries | ||
158 | * sizeof(struct scu_unsolicited_frame_header); | ||
159 | used_uf_header_bytes = used_uf_header_entries | ||
160 | * sizeof(struct scu_unsolicited_frame_header); | ||
161 | |||
162 | size = used_uf_buffer_bytes + used_uf_header_bytes + | ||
163 | uf_control->address_table.count * sizeof(dma_addr_t); | ||
164 | |||
165 | 76 | ||
166 | /* | 77 | /* |
167 | * The Unsolicited Frame buffers are set at the start of the UF | 78 | * The Unsolicited Frame buffers are set at the start of the UF |
168 | * memory descriptor entry. The headers and address table will be | 79 | * memory descriptor entry. The headers and address table will be |
169 | * placed after the buffers. | 80 | * placed after the buffers. |
170 | */ | 81 | */ |
171 | uf_buffer_virt_address = dmam_alloc_coherent(scic_to_dev(scic), size, | 82 | virt = dmam_alloc_coherent(scic_to_dev(scic), size, &dma, GFP_KERNEL); |
172 | &uf_buffer_phys_address, GFP_KERNEL); | 83 | if (!virt) |
173 | if (!uf_buffer_virt_address) | ||
174 | return -ENOMEM; | 84 | return -ENOMEM; |
175 | 85 | ||
176 | /* | 86 | /* |
@@ -183,15 +93,8 @@ int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *sci | |||
183 | * headers, since we program the UF address table pointers to | 93 | * headers, since we program the UF address table pointers to |
184 | * NULL. | 94 | * NULL. |
185 | */ | 95 | */ |
186 | uf_control->headers.physical_address = | 96 | uf_control->headers.physical_address = dma + buf_len; |
187 | uf_buffer_phys_address + | 97 | uf_control->headers.array = virt + buf_len; |
188 | used_uf_buffer_bytes - | ||
189 | unused_uf_header_bytes; | ||
190 | |||
191 | uf_control->headers.array = | ||
192 | uf_buffer_virt_address + | ||
193 | used_uf_buffer_bytes - | ||
194 | unused_uf_header_bytes; | ||
195 | 98 | ||
196 | /* | 99 | /* |
197 | * Program the location of the UF address table into the SCU. | 100 | * Program the location of the UF address table into the SCU. |
@@ -200,16 +103,8 @@ int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *sci | |||
200 | * byte boundary already due to above programming headers being on a | 103 | * byte boundary already due to above programming headers being on a |
201 | * 64-bit boundary and headers are on a 64-bytes in size. | 104 | * 64-bit boundary and headers are on a 64-bytes in size. |
202 | */ | 105 | */ |
203 | uf_control->address_table.physical_address = | 106 | uf_control->address_table.physical_address = dma + buf_len + header_len; |
204 | uf_buffer_phys_address + | 107 | uf_control->address_table.array = virt + buf_len + header_len; |
205 | used_uf_buffer_bytes + | ||
206 | used_uf_header_bytes; | ||
207 | |||
208 | uf_control->address_table.array = | ||
209 | uf_buffer_virt_address + | ||
210 | used_uf_buffer_bytes + | ||
211 | used_uf_header_bytes; | ||
212 | |||
213 | uf_control->get = 0; | 108 | uf_control->get = 0; |
214 | 109 | ||
215 | /* | 110 | /* |
@@ -220,16 +115,26 @@ int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *sci | |||
220 | * - Aligned on a 1KB boundary. */ | 115 | * - Aligned on a 1KB boundary. */ |
221 | 116 | ||
222 | /* | 117 | /* |
223 | * If the user provided less then the maximum amount of memory, | 118 | * Program the actual used UF buffers into the UF address table and |
224 | * then be sure that we programm the first entries in the UF | 119 | * the controller's array of UFs. |
225 | * address table to NULL. */ | 120 | */ |
226 | scic_sds_unsolicited_frame_control_construct_frames( | 121 | for (i = 0; i < SCU_MAX_UNSOLICITED_FRAMES; i++) { |
227 | uf_control, | 122 | uf = &uf_control->buffers.array[i]; |
228 | uf_buffer_phys_address, | 123 | |
229 | uf_buffer_virt_address, | 124 | uf_control->address_table.array[i] = dma; |
230 | unused_uf_header_entries, | 125 | |
231 | used_uf_header_entries | 126 | uf->buffer = virt; |
232 | ); | 127 | uf->header = &uf_control->headers.array[i]; |
128 | uf->state = UNSOLICITED_FRAME_EMPTY; | ||
129 | |||
130 | /* | ||
131 | * Increment the address of the physical and virtual memory | ||
132 | * pointers. Everything is aligned on 1k boundary with an | ||
133 | * increment of 1k. | ||
134 | */ | ||
135 | virt += SCU_UNSOLICITED_FRAME_BUFFER_SIZE; | ||
136 | dma += SCU_UNSOLICITED_FRAME_BUFFER_SIZE; | ||
137 | } | ||
233 | 138 | ||
234 | return 0; | 139 | return 0; |
235 | } | 140 | } |
@@ -247,7 +152,7 @@ enum sci_status scic_sds_unsolicited_frame_control_get_header( | |||
247 | u32 frame_index, | 152 | u32 frame_index, |
248 | void **frame_header) | 153 | void **frame_header) |
249 | { | 154 | { |
250 | if (frame_index < uf_control->address_table.count) { | 155 | if (frame_index < SCU_MAX_UNSOLICITED_FRAMES) { |
251 | /* | 156 | /* |
252 | * Skip the first word in the frame since this is a controll word used | 157 | * Skip the first word in the frame since this is a controll word used |
253 | * by the hardware. */ | 158 | * by the hardware. */ |
@@ -272,7 +177,7 @@ enum sci_status scic_sds_unsolicited_frame_control_get_buffer( | |||
272 | u32 frame_index, | 177 | u32 frame_index, |
273 | void **frame_buffer) | 178 | void **frame_buffer) |
274 | { | 179 | { |
275 | if (frame_index < uf_control->address_table.count) { | 180 | if (frame_index < SCU_MAX_UNSOLICITED_FRAMES) { |
276 | *frame_buffer = uf_control->buffers.array[frame_index].buffer; | 181 | *frame_buffer = uf_control->buffers.array[frame_index].buffer; |
277 | 182 | ||
278 | return SCI_SUCCESS; | 183 | return SCI_SUCCESS; |
@@ -298,26 +203,24 @@ bool scic_sds_unsolicited_frame_control_release_frame( | |||
298 | u32 frame_get; | 203 | u32 frame_get; |
299 | u32 frame_cycle; | 204 | u32 frame_cycle; |
300 | 205 | ||
301 | frame_get = uf_control->get & (uf_control->address_table.count - 1); | 206 | frame_get = uf_control->get & (SCU_MAX_UNSOLICITED_FRAMES - 1); |
302 | frame_cycle = uf_control->get & uf_control->address_table.count; | 207 | frame_cycle = uf_control->get & SCU_MAX_UNSOLICITED_FRAMES; |
303 | 208 | ||
304 | /* | 209 | /* |
305 | * In the event there are NULL entries in the UF table, we need to | 210 | * In the event there are NULL entries in the UF table, we need to |
306 | * advance the get pointer in order to find out if this frame should | 211 | * advance the get pointer in order to find out if this frame should |
307 | * be released (i.e. update the get pointer). */ | 212 | * be released (i.e. update the get pointer). */ |
308 | while (((lower_32_bits(uf_control->address_table.array[frame_get]) | 213 | while (lower_32_bits(uf_control->address_table.array[frame_get]) == 0 && |
309 | == 0) && | 214 | upper_32_bits(uf_control->address_table.array[frame_get]) == 0 && |
310 | (upper_32_bits(uf_control->address_table.array[frame_get]) | 215 | frame_get < SCU_MAX_UNSOLICITED_FRAMES) |
311 | == 0)) && | ||
312 | (frame_get < uf_control->address_table.count)) | ||
313 | frame_get++; | 216 | frame_get++; |
314 | 217 | ||
315 | /* | 218 | /* |
316 | * The table has a NULL entry as it's last element. This is | 219 | * The table has a NULL entry as it's last element. This is |
317 | * illegal. */ | 220 | * illegal. */ |
318 | BUG_ON(frame_get >= uf_control->address_table.count); | 221 | BUG_ON(frame_get >= SCU_MAX_UNSOLICITED_FRAMES); |
319 | 222 | ||
320 | if (frame_index < uf_control->address_table.count) { | 223 | if (frame_index < SCU_MAX_UNSOLICITED_FRAMES) { |
321 | uf_control->buffers.array[frame_index].state = UNSOLICITED_FRAME_RELEASED; | 224 | uf_control->buffers.array[frame_index].state = UNSOLICITED_FRAME_RELEASED; |
322 | 225 | ||
323 | /* | 226 | /* |
@@ -333,9 +236,8 @@ bool scic_sds_unsolicited_frame_control_release_frame( | |||
333 | INCREMENT_QUEUE_GET( | 236 | INCREMENT_QUEUE_GET( |
334 | frame_get, | 237 | frame_get, |
335 | frame_cycle, | 238 | frame_cycle, |
336 | uf_control->address_table.count - 1, | 239 | SCU_MAX_UNSOLICITED_FRAMES - 1, |
337 | uf_control->address_table.count | 240 | SCU_MAX_UNSOLICITED_FRAMES); |
338 | ); | ||
339 | } | 241 | } |
340 | 242 | ||
341 | uf_control->get = | 243 | uf_control->get = |
diff --git a/drivers/scsi/isci/unsolicited_frame_control.h b/drivers/scsi/isci/unsolicited_frame_control.h index 0d8ca8c4770f..2954904f025a 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.h +++ b/drivers/scsi/isci/unsolicited_frame_control.h | |||
@@ -144,25 +144,18 @@ struct scic_sds_uf_header_array { | |||
144 | */ | 144 | */ |
145 | struct scic_sds_uf_buffer_array { | 145 | struct scic_sds_uf_buffer_array { |
146 | /** | 146 | /** |
147 | * This field is the minimum number of unsolicited frames supported by the | 147 | * This field is the unsolicited frame data its used to manage |
148 | * hardware and the number of unsolicited frames requested by the software. | ||
149 | */ | ||
150 | u32 count; | ||
151 | |||
152 | /** | ||
153 | * This field is the SCIC_UNSOLICITED_FRAME data its used to manage | ||
154 | * the data for the unsolicited frame requests. It also represents | 148 | * the data for the unsolicited frame requests. It also represents |
155 | * the virtual address location that corresponds to the | 149 | * the virtual address location that corresponds to the |
156 | * physical_address field. | 150 | * physical_address field. |
157 | */ | 151 | */ |
158 | struct scic_sds_unsolicited_frame array[SCU_UNSOLICITED_FRAME_CONTROL_ARRAY_SIZE]; | 152 | struct scic_sds_unsolicited_frame array[SCU_MAX_UNSOLICITED_FRAMES]; |
159 | 153 | ||
160 | /** | 154 | /** |
161 | * This field specifies the physical address location for the UF | 155 | * This field specifies the physical address location for the UF |
162 | * buffer array. | 156 | * buffer array. |
163 | */ | 157 | */ |
164 | dma_addr_t physical_address; | 158 | dma_addr_t physical_address; |
165 | |||
166 | }; | 159 | }; |
167 | 160 | ||
168 | /** | 161 | /** |
@@ -174,15 +167,6 @@ struct scic_sds_uf_buffer_array { | |||
174 | */ | 167 | */ |
175 | struct scic_sds_uf_address_table_array { | 168 | struct scic_sds_uf_address_table_array { |
176 | /** | 169 | /** |
177 | * This field specifies the actual programmed size of the | ||
178 | * unsolicited frame buffer address table. The size of the table | ||
179 | * can be larger than the actual number of UF buffers, but it must | ||
180 | * be a power of 2 and the last entry in the table is not allowed | ||
181 | * to be NULL. | ||
182 | */ | ||
183 | u32 count; | ||
184 | |||
185 | /** | ||
186 | * This field represents a virtual pointer that refers to the | 170 | * This field represents a virtual pointer that refers to the |
187 | * starting address of the UF address table. | 171 | * starting address of the UF address table. |
188 | * 64-bit pointers are required by the hardware. | 172 | * 64-bit pointers are required by the hardware. |