blob: d8af4c64cd51ff5f90b39a04cd61b0136f2d4af2 [file] [log] [blame]
John Garrye8899fa2015-11-18 00:50:30 +08001/*
2 * Copyright (c) 2015 Linaro Ltd.
3 * Copyright (c) 2015 Hisilicon Limited.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 */
11
12#include "hisi_sas.h"
13#define DRV_NAME "hisi_sas"
14
John Garryabda97c2015-11-18 00:50:51 +080015#define DEV_IS_EXPANDER(type) \
16 ((type == SAS_EDGE_EXPANDER_DEVICE) || \
17 (type == SAS_FANOUT_EXPANDER_DEVICE))
John Garry42e7a692015-11-18 00:50:49 +080018
19#define DEV_IS_GONE(dev) \
20 ((!dev) || (dev->dev_type == SAS_PHY_UNUSED))
21
22static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device)
23{
24 return device->port->ha->lldd_ha;
25}
26
John Garry257efd12015-11-18 00:50:36 +080027static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx)
28{
29 void *bitmap = hisi_hba->slot_index_tags;
30
31 clear_bit(slot_idx, bitmap);
32}
33
John Garry42e7a692015-11-18 00:50:49 +080034static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx)
35{
36 hisi_sas_slot_index_clear(hisi_hba, slot_idx);
37}
38
39static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx)
40{
41 void *bitmap = hisi_hba->slot_index_tags;
42
43 set_bit(slot_idx, bitmap);
44}
45
46static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx)
47{
48 unsigned int index;
49 void *bitmap = hisi_hba->slot_index_tags;
50
51 index = find_first_zero_bit(bitmap, hisi_hba->slot_index_count);
52 if (index >= hisi_hba->slot_index_count)
53 return -SAS_QUEUE_FULL;
54 hisi_sas_slot_index_set(hisi_hba, index);
55 *slot_idx = index;
56 return 0;
57}
58
John Garry257efd12015-11-18 00:50:36 +080059static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba)
60{
61 int i;
62
63 for (i = 0; i < hisi_hba->slot_index_count; ++i)
64 hisi_sas_slot_index_clear(hisi_hba, i);
65}
John Garry27a3f222015-11-18 00:50:50 +080066
67void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
68 struct hisi_sas_slot *slot)
69{
70 struct device *dev = &hisi_hba->pdev->dev;
71
72 if (!slot->task)
73 return;
74
75 if (!sas_protocol_ata(task->task_proto))
76 if (slot->n_elem)
77 dma_unmap_sg(dev, task->scatter, slot->n_elem,
78 task->data_dir);
79
80 if (slot->command_table)
81 dma_pool_free(hisi_hba->command_table_pool,
82 slot->command_table, slot->command_table_dma);
83
84 if (slot->status_buffer)
85 dma_pool_free(hisi_hba->status_buffer_pool,
86 slot->status_buffer, slot->status_buffer_dma);
87
88 if (slot->sge_page)
89 dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page,
90 slot->sge_page_dma);
91
92 list_del_init(&slot->entry);
93 task->lldd_task = NULL;
94 slot->task = NULL;
95 slot->port = NULL;
96 hisi_sas_slot_index_free(hisi_hba, slot->idx);
97 memset(slot, 0, sizeof(*slot));
98}
99EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free);
100
John Garry42e7a692015-11-18 00:50:49 +0800101static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba,
102 struct hisi_sas_slot *slot, int is_tmf,
103 struct hisi_sas_tmf_task *tmf)
104{
105 return hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf);
106}
107
108static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
109 int is_tmf, struct hisi_sas_tmf_task *tmf,
110 int *pass)
111{
112 struct domain_device *device = task->dev;
113 struct hisi_sas_device *sas_dev = device->lldd_dev;
114 struct hisi_sas_port *port;
115 struct hisi_sas_slot *slot;
116 struct hisi_sas_cmd_hdr *cmd_hdr_base;
117 struct device *dev = &hisi_hba->pdev->dev;
118 int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
119
120 if (!device->port) {
121 struct task_status_struct *ts = &task->task_status;
122
123 ts->resp = SAS_TASK_UNDELIVERED;
124 ts->stat = SAS_PHY_DOWN;
125 /*
126 * libsas will use dev->port, should
127 * not call task_done for sata
128 */
129 if (device->dev_type != SAS_SATA_DEV)
130 task->task_done(task);
131 return 0;
132 }
133
134 if (DEV_IS_GONE(sas_dev)) {
135 if (sas_dev)
136 dev_info(dev, "task prep: device %llu not ready\n",
137 sas_dev->device_id);
138 else
139 dev_info(dev, "task prep: device %016llx not ready\n",
140 SAS_ADDR(device->sas_addr));
141
142 rc = SAS_PHY_DOWN;
143 return rc;
144 }
145 port = device->port->lldd_port;
146 if (port && !port->port_attached && !tmf) {
147 if (sas_protocol_ata(task->task_proto)) {
148 struct task_status_struct *ts = &task->task_status;
149
150 dev_info(dev,
151 "task prep: SATA/STP port%d not attach device\n",
152 device->port->id);
153 ts->resp = SAS_TASK_COMPLETE;
154 ts->stat = SAS_PHY_DOWN;
155 task->task_done(task);
156 } else {
157 struct task_status_struct *ts = &task->task_status;
158
159 dev_info(dev,
160 "task prep: SAS port%d does not attach device\n",
161 device->port->id);
162 ts->resp = SAS_TASK_UNDELIVERED;
163 ts->stat = SAS_PHY_DOWN;
164 task->task_done(task);
165 }
166 return 0;
167 }
168
169 if (!sas_protocol_ata(task->task_proto)) {
170 if (task->num_scatter) {
171 n_elem = dma_map_sg(dev, task->scatter,
172 task->num_scatter, task->data_dir);
173 if (!n_elem) {
174 rc = -ENOMEM;
175 goto prep_out;
176 }
177 }
178 } else
179 n_elem = task->num_scatter;
180
181 rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
182 if (rc)
183 goto err_out;
184 rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue,
185 &dlvry_queue_slot);
186 if (rc)
187 goto err_out_tag;
188
189 slot = &hisi_hba->slot_info[slot_idx];
190 memset(slot, 0, sizeof(struct hisi_sas_slot));
191
192 slot->idx = slot_idx;
193 slot->n_elem = n_elem;
194 slot->dlvry_queue = dlvry_queue;
195 slot->dlvry_queue_slot = dlvry_queue_slot;
196 cmd_hdr_base = hisi_hba->cmd_hdr[dlvry_queue];
197 slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot];
198 slot->task = task;
199 slot->port = port;
200 task->lldd_task = slot;
201
202 slot->status_buffer = dma_pool_alloc(hisi_hba->status_buffer_pool,
203 GFP_ATOMIC,
204 &slot->status_buffer_dma);
205 if (!slot->status_buffer)
206 goto err_out_slot_buf;
207 memset(slot->status_buffer, 0, HISI_SAS_STATUS_BUF_SZ);
208
209 slot->command_table = dma_pool_alloc(hisi_hba->command_table_pool,
210 GFP_ATOMIC,
211 &slot->command_table_dma);
212 if (!slot->command_table)
213 goto err_out_status_buf;
214 memset(slot->command_table, 0, HISI_SAS_COMMAND_TABLE_SZ);
215 memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
216
217 switch (task->task_proto) {
218 case SAS_PROTOCOL_SSP:
219 rc = hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf);
220 break;
221 case SAS_PROTOCOL_SATA:
222 case SAS_PROTOCOL_STP:
223 case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
224 default:
225 dev_err(dev, "task prep: unknown/unsupported proto (0x%x)\n",
226 task->task_proto);
227 rc = -EINVAL;
228 break;
229 }
230
231 if (rc) {
232 dev_err(dev, "task prep: rc = 0x%x\n", rc);
233 if (slot->sge_page)
234 goto err_out_sge;
235 goto err_out_command_table;
236 }
237
238 list_add_tail(&slot->entry, &port->list);
239 spin_lock(&task->task_state_lock);
240 task->task_state_flags |= SAS_TASK_AT_INITIATOR;
241 spin_unlock(&task->task_state_lock);
242
243 hisi_hba->slot_prep = slot;
244
245 sas_dev->running_req++;
246 ++(*pass);
247
248 return rc;
249
250err_out_sge:
251 dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page,
252 slot->sge_page_dma);
253err_out_command_table:
254 dma_pool_free(hisi_hba->command_table_pool, slot->command_table,
255 slot->command_table_dma);
256err_out_status_buf:
257 dma_pool_free(hisi_hba->status_buffer_pool, slot->status_buffer,
258 slot->status_buffer_dma);
259err_out_slot_buf:
260 /* Nothing to be done */
261err_out_tag:
262 hisi_sas_slot_index_free(hisi_hba, slot_idx);
263err_out:
264 dev_err(dev, "task prep: failed[%d]!\n", rc);
265 if (!sas_protocol_ata(task->task_proto))
266 if (n_elem)
267 dma_unmap_sg(dev, task->scatter, n_elem,
268 task->data_dir);
269prep_out:
270 return rc;
271}
272
273static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
274 int is_tmf, struct hisi_sas_tmf_task *tmf)
275{
276 u32 rc;
277 u32 pass = 0;
278 unsigned long flags;
279 struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev);
280 struct device *dev = &hisi_hba->pdev->dev;
281
282 /* protect task_prep and start_delivery sequence */
283 spin_lock_irqsave(&hisi_hba->lock, flags);
284 rc = hisi_sas_task_prep(task, hisi_hba, is_tmf, tmf, &pass);
285 if (rc)
286 dev_err(dev, "task exec: failed[%d]!\n", rc);
287
288 if (likely(pass))
289 hisi_hba->hw->start_delivery(hisi_hba);
290 spin_unlock_irqrestore(&hisi_hba->lock, flags);
291
292 return rc;
293}
John Garry257efd12015-11-18 00:50:36 +0800294
John Garry66139922015-11-18 00:50:48 +0800295static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
296{
297 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
298 struct asd_sas_phy *sas_phy = &phy->sas_phy;
299 struct sas_ha_struct *sas_ha;
300
301 if (!phy->phy_attached)
302 return;
303
304 sas_ha = &hisi_hba->sha;
305 sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE);
306
307 if (sas_phy->phy) {
308 struct sas_phy *sphy = sas_phy->phy;
309
310 sphy->negotiated_linkrate = sas_phy->linkrate;
311 sphy->minimum_linkrate = phy->minimum_linkrate;
312 sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
313 sphy->maximum_linkrate = phy->maximum_linkrate;
314 }
315
316 if (phy->phy_type & PORT_TYPE_SAS) {
317 struct sas_identify_frame *id;
318
319 id = (struct sas_identify_frame *)phy->frame_rcvd;
320 id->dev_type = phy->identify.device_type;
321 id->initiator_bits = SAS_PROTOCOL_ALL;
322 id->target_bits = phy->identify.target_port_protocols;
323 } else if (phy->phy_type & PORT_TYPE_SATA) {
324 /*Nothing*/
325 }
326
327 sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
328 sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED);
329}
330
John Garryabda97c2015-11-18 00:50:51 +0800331static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
332{
333 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
334 struct hisi_sas_device *sas_dev = NULL;
335 int i;
336
337 spin_lock(&hisi_hba->lock);
338 for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
339 if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) {
340 hisi_hba->devices[i].device_id = i;
341 sas_dev = &hisi_hba->devices[i];
342 sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
343 sas_dev->dev_type = device->dev_type;
344 sas_dev->hisi_hba = hisi_hba;
345 sas_dev->sas_device = device;
346 break;
347 }
348 }
349 spin_unlock(&hisi_hba->lock);
350
351 return sas_dev;
352}
353
354static int hisi_sas_dev_found(struct domain_device *device)
355{
356 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
357 struct domain_device *parent_dev = device->parent;
358 struct hisi_sas_device *sas_dev;
359 struct device *dev = &hisi_hba->pdev->dev;
360
361 sas_dev = hisi_sas_alloc_dev(device);
362 if (!sas_dev) {
363 dev_err(dev, "fail alloc dev: max support %d devices\n",
364 HISI_SAS_MAX_DEVICES);
365 return -EINVAL;
366 }
367
368 device->lldd_dev = sas_dev;
369 hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
370
371 if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) {
372 int phy_no;
373 u8 phy_num = parent_dev->ex_dev.num_phys;
374 struct ex_phy *phy;
375
376 for (phy_no = 0; phy_no < phy_num; phy_no++) {
377 phy = &parent_dev->ex_dev.ex_phy[phy_no];
378 if (SAS_ADDR(phy->attached_sas_addr) ==
379 SAS_ADDR(device->sas_addr)) {
380 sas_dev->attached_phy = phy_no;
381 break;
382 }
383 }
384
385 if (phy_no == phy_num) {
386 dev_info(dev, "dev found: no attached "
387 "dev:%016llx at ex:%016llx\n",
388 SAS_ADDR(device->sas_addr),
389 SAS_ADDR(parent_dev->sas_addr));
390 return -EINVAL;
391 }
392 }
393
394 return 0;
395}
396
John Garry66139922015-11-18 00:50:48 +0800397static void hisi_sas_phyup_work(struct work_struct *work)
398{
399 struct hisi_sas_phy *phy =
400 container_of(work, struct hisi_sas_phy, phyup_ws);
401 struct hisi_hba *hisi_hba = phy->hisi_hba;
402 struct asd_sas_phy *sas_phy = &phy->sas_phy;
403 int phy_no = sas_phy->id;
404
405 hisi_hba->hw->sl_notify(hisi_hba, phy_no); /* This requires a sleep */
406 hisi_sas_bytes_dmaed(hisi_hba, phy_no);
407}
John Garry976867e2015-11-18 00:50:42 +0800408
409static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no)
410{
411 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
412 struct asd_sas_phy *sas_phy = &phy->sas_phy;
413
414 phy->hisi_hba = hisi_hba;
415 phy->port = NULL;
416 init_timer(&phy->timer);
417 sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0;
418 sas_phy->class = SAS;
419 sas_phy->iproto = SAS_PROTOCOL_ALL;
420 sas_phy->tproto = 0;
421 sas_phy->type = PHY_TYPE_PHYSICAL;
422 sas_phy->role = PHY_ROLE_INITIATOR;
423 sas_phy->oob_mode = OOB_NOT_CONNECTED;
424 sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
425 sas_phy->id = phy_no;
426 sas_phy->sas_addr = &hisi_hba->sas_addr[0];
427 sas_phy->frame_rcvd = &phy->frame_rcvd[0];
428 sas_phy->ha = (struct sas_ha_struct *)hisi_hba->shost->hostdata;
429 sas_phy->lldd_phy = phy;
John Garry66139922015-11-18 00:50:48 +0800430
431 INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work);
John Garry976867e2015-11-18 00:50:42 +0800432}
433
John Garryabda97c2015-11-18 00:50:51 +0800434static void hisi_sas_dev_gone(struct domain_device *device)
435{
436 struct hisi_sas_device *sas_dev = device->lldd_dev;
437 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
438 struct device *dev = &hisi_hba->pdev->dev;
439 u64 dev_id = sas_dev->device_id;
440
441 dev_info(dev, "found dev[%lld:%x] is gone\n",
442 sas_dev->device_id, sas_dev->dev_type);
443
444 hisi_hba->hw->free_device(hisi_hba, sas_dev);
445 device->lldd_dev = NULL;
446 memset(sas_dev, 0, sizeof(*sas_dev));
447 sas_dev->device_id = dev_id;
448 sas_dev->dev_type = SAS_PHY_UNUSED;
449 sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
450}
John Garry42e7a692015-11-18 00:50:49 +0800451
452static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags)
453{
454 return hisi_sas_task_exec(task, gfp_flags, 0, NULL);
455}
456
John Garrye8899fa2015-11-18 00:50:30 +0800457static struct scsi_transport_template *hisi_sas_stt;
458
John Garry7eb78692015-11-18 00:50:31 +0800459static struct scsi_host_template hisi_sas_sht = {
460 .module = THIS_MODULE,
461 .name = DRV_NAME,
462 .queuecommand = sas_queuecommand,
463 .target_alloc = sas_target_alloc,
464 .slave_configure = sas_slave_configure,
465 .change_queue_depth = sas_change_queue_depth,
466 .bios_param = sas_bios_param,
467 .can_queue = 1,
468 .this_id = -1,
469 .sg_tablesize = SG_ALL,
470 .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
471 .use_clustering = ENABLE_CLUSTERING,
472 .eh_device_reset_handler = sas_eh_device_reset_handler,
473 .eh_bus_reset_handler = sas_eh_bus_reset_handler,
474 .target_destroy = sas_target_destroy,
475 .ioctl = sas_ioctl,
476};
477
John Garrye8899fa2015-11-18 00:50:30 +0800478static struct sas_domain_function_template hisi_sas_transport_ops = {
John Garryabda97c2015-11-18 00:50:51 +0800479 .lldd_dev_found = hisi_sas_dev_found,
480 .lldd_dev_gone = hisi_sas_dev_gone,
John Garry42e7a692015-11-18 00:50:49 +0800481 .lldd_execute_task = hisi_sas_queue_command,
John Garrye8899fa2015-11-18 00:50:30 +0800482};
483
John Garry6be6de12015-11-18 00:50:34 +0800484static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
485{
486 int i, s;
487 struct platform_device *pdev = hisi_hba->pdev;
488 struct device *dev = &pdev->dev;
489
John Garryfa42d802015-11-18 00:50:43 +0800490 spin_lock_init(&hisi_hba->lock);
John Garry976867e2015-11-18 00:50:42 +0800491 for (i = 0; i < hisi_hba->n_phy; i++) {
492 hisi_sas_phy_init(hisi_hba, i);
493 hisi_hba->port[i].port_attached = 0;
494 hisi_hba->port[i].id = -1;
495 INIT_LIST_HEAD(&hisi_hba->port[i].list);
496 }
497
John Garryaf740db2015-11-18 00:50:41 +0800498 for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
499 hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED;
500 hisi_hba->devices[i].device_id = i;
501 hisi_hba->devices[i].dev_status = HISI_SAS_DEV_NORMAL;
502 }
503
John Garry6be6de12015-11-18 00:50:34 +0800504 for (i = 0; i < hisi_hba->queue_count; i++) {
John Garry9101a072015-11-18 00:50:37 +0800505 struct hisi_sas_cq *cq = &hisi_hba->cq[i];
506
507 /* Completion queue structure */
508 cq->id = i;
509 cq->hisi_hba = hisi_hba;
510
John Garry6be6de12015-11-18 00:50:34 +0800511 /* Delivery queue */
512 s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS;
513 hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s,
514 &hisi_hba->cmd_hdr_dma[i], GFP_KERNEL);
515 if (!hisi_hba->cmd_hdr[i])
516 goto err_out;
517 memset(hisi_hba->cmd_hdr[i], 0, s);
518
519 /* Completion queue */
520 s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
521 hisi_hba->complete_hdr[i] = dma_alloc_coherent(dev, s,
522 &hisi_hba->complete_hdr_dma[i], GFP_KERNEL);
523 if (!hisi_hba->complete_hdr[i])
524 goto err_out;
525 memset(hisi_hba->complete_hdr[i], 0, s);
526 }
527
528 s = HISI_SAS_STATUS_BUF_SZ;
529 hisi_hba->status_buffer_pool = dma_pool_create("status_buffer",
530 dev, s, 16, 0);
531 if (!hisi_hba->status_buffer_pool)
532 goto err_out;
533
534 s = HISI_SAS_COMMAND_TABLE_SZ;
535 hisi_hba->command_table_pool = dma_pool_create("command_table",
536 dev, s, 16, 0);
537 if (!hisi_hba->command_table_pool)
538 goto err_out;
539
540 s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
541 hisi_hba->itct = dma_alloc_coherent(dev, s, &hisi_hba->itct_dma,
542 GFP_KERNEL);
543 if (!hisi_hba->itct)
544 goto err_out;
545
546 memset(hisi_hba->itct, 0, s);
547
548 hisi_hba->slot_info = devm_kcalloc(dev, HISI_SAS_COMMAND_ENTRIES,
549 sizeof(struct hisi_sas_slot),
550 GFP_KERNEL);
551 if (!hisi_hba->slot_info)
552 goto err_out;
553
554 s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost);
555 hisi_hba->iost = dma_alloc_coherent(dev, s, &hisi_hba->iost_dma,
556 GFP_KERNEL);
557 if (!hisi_hba->iost)
558 goto err_out;
559
560 memset(hisi_hba->iost, 0, s);
561
562 s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint);
563 hisi_hba->breakpoint = dma_alloc_coherent(dev, s,
564 &hisi_hba->breakpoint_dma, GFP_KERNEL);
565 if (!hisi_hba->breakpoint)
566 goto err_out;
567
568 memset(hisi_hba->breakpoint, 0, s);
569
John Garry257efd12015-11-18 00:50:36 +0800570 hisi_hba->slot_index_count = HISI_SAS_COMMAND_ENTRIES;
571 s = hisi_hba->slot_index_count / sizeof(unsigned long);
572 hisi_hba->slot_index_tags = devm_kzalloc(dev, s, GFP_KERNEL);
573 if (!hisi_hba->slot_index_tags)
574 goto err_out;
575
John Garry6be6de12015-11-18 00:50:34 +0800576 hisi_hba->sge_page_pool = dma_pool_create("status_sge", dev,
577 sizeof(struct hisi_sas_sge_page), 16, 0);
578 if (!hisi_hba->sge_page_pool)
579 goto err_out;
580
581 s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS;
582 hisi_hba->initial_fis = dma_alloc_coherent(dev, s,
583 &hisi_hba->initial_fis_dma, GFP_KERNEL);
584 if (!hisi_hba->initial_fis)
585 goto err_out;
586 memset(hisi_hba->initial_fis, 0, s);
587
588 s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2;
589 hisi_hba->sata_breakpoint = dma_alloc_coherent(dev, s,
590 &hisi_hba->sata_breakpoint_dma, GFP_KERNEL);
591 if (!hisi_hba->sata_breakpoint)
592 goto err_out;
593 memset(hisi_hba->sata_breakpoint, 0, s);
594
John Garry257efd12015-11-18 00:50:36 +0800595 hisi_sas_slot_index_init(hisi_hba);
596
John Garry7e9080e2015-11-18 00:50:40 +0800597 hisi_hba->wq = create_singlethread_workqueue(dev_name(dev));
598 if (!hisi_hba->wq) {
599 dev_err(dev, "sas_alloc: failed to create workqueue\n");
600 goto err_out;
601 }
602
John Garry6be6de12015-11-18 00:50:34 +0800603 return 0;
604err_out:
605 return -ENOMEM;
606}
607
John Garry89d53322015-11-18 00:50:35 +0800608static void hisi_sas_free(struct hisi_hba *hisi_hba)
609{
610 struct device *dev = &hisi_hba->pdev->dev;
611 int i, s;
612
613 for (i = 0; i < hisi_hba->queue_count; i++) {
614 s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS;
615 if (hisi_hba->cmd_hdr[i])
616 dma_free_coherent(dev, s,
617 hisi_hba->cmd_hdr[i],
618 hisi_hba->cmd_hdr_dma[i]);
619
620 s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
621 if (hisi_hba->complete_hdr[i])
622 dma_free_coherent(dev, s,
623 hisi_hba->complete_hdr[i],
624 hisi_hba->complete_hdr_dma[i]);
625 }
626
627 dma_pool_destroy(hisi_hba->status_buffer_pool);
628 dma_pool_destroy(hisi_hba->command_table_pool);
629 dma_pool_destroy(hisi_hba->sge_page_pool);
630
631 s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
632 if (hisi_hba->itct)
633 dma_free_coherent(dev, s,
634 hisi_hba->itct, hisi_hba->itct_dma);
635
636 s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost);
637 if (hisi_hba->iost)
638 dma_free_coherent(dev, s,
639 hisi_hba->iost, hisi_hba->iost_dma);
640
641 s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint);
642 if (hisi_hba->breakpoint)
643 dma_free_coherent(dev, s,
644 hisi_hba->breakpoint,
645 hisi_hba->breakpoint_dma);
646
647
648 s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS;
649 if (hisi_hba->initial_fis)
650 dma_free_coherent(dev, s,
651 hisi_hba->initial_fis,
652 hisi_hba->initial_fis_dma);
653
654 s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2;
655 if (hisi_hba->sata_breakpoint)
656 dma_free_coherent(dev, s,
657 hisi_hba->sata_breakpoint,
658 hisi_hba->sata_breakpoint_dma);
659
John Garry7e9080e2015-11-18 00:50:40 +0800660 if (hisi_hba->wq)
661 destroy_workqueue(hisi_hba->wq);
John Garry89d53322015-11-18 00:50:35 +0800662}
John Garry6be6de12015-11-18 00:50:34 +0800663
John Garry7eb78692015-11-18 00:50:31 +0800664static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
665 const struct hisi_sas_hw *hw)
666{
John Garrye26b2f42015-11-18 00:50:32 +0800667 struct resource *res;
John Garry7eb78692015-11-18 00:50:31 +0800668 struct Scsi_Host *shost;
669 struct hisi_hba *hisi_hba;
670 struct device *dev = &pdev->dev;
John Garrye26b2f42015-11-18 00:50:32 +0800671 struct device_node *np = pdev->dev.of_node;
672 struct property *sas_addr_prop;
673 int num;
John Garry7eb78692015-11-18 00:50:31 +0800674
675 shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba));
676 if (!shost)
677 goto err_out;
678 hisi_hba = shost_priv(shost);
679
680 hisi_hba->hw = hw;
681 hisi_hba->pdev = pdev;
682 hisi_hba->shost = shost;
683 SHOST_TO_SAS_HA(shost) = &hisi_hba->sha;
684
John Garryfa42d802015-11-18 00:50:43 +0800685 init_timer(&hisi_hba->timer);
686
John Garrye26b2f42015-11-18 00:50:32 +0800687 sas_addr_prop = of_find_property(np, "sas-addr", NULL);
688 if (!sas_addr_prop || (sas_addr_prop->length != SAS_ADDR_SIZE))
689 goto err_out;
690 memcpy(hisi_hba->sas_addr, sas_addr_prop->value, SAS_ADDR_SIZE);
691
692 if (of_property_read_u32(np, "ctrl-reset-reg",
693 &hisi_hba->ctrl_reset_reg))
694 goto err_out;
695
696 if (of_property_read_u32(np, "ctrl-reset-sts-reg",
697 &hisi_hba->ctrl_reset_sts_reg))
698 goto err_out;
699
700 if (of_property_read_u32(np, "ctrl-clock-ena-reg",
701 &hisi_hba->ctrl_clock_ena_reg))
702 goto err_out;
703
704 if (of_property_read_u32(np, "phy-count", &hisi_hba->n_phy))
705 goto err_out;
706
707 if (of_property_read_u32(np, "queue-count", &hisi_hba->queue_count))
708 goto err_out;
709
710 num = of_irq_count(np);
711 hisi_hba->int_names = devm_kcalloc(dev, num,
712 HISI_SAS_NAME_LEN,
713 GFP_KERNEL);
714 if (!hisi_hba->int_names)
715 goto err_out;
716
717 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
718 hisi_hba->regs = devm_ioremap_resource(dev, res);
719 if (IS_ERR(hisi_hba->regs))
720 goto err_out;
721
722 hisi_hba->ctrl = syscon_regmap_lookup_by_phandle(
723 np, "hisilicon,sas-syscon");
724 if (IS_ERR(hisi_hba->ctrl))
725 goto err_out;
726
John Garry89d53322015-11-18 00:50:35 +0800727 if (hisi_sas_alloc(hisi_hba, shost)) {
728 hisi_sas_free(hisi_hba);
John Garry6be6de12015-11-18 00:50:34 +0800729 goto err_out;
John Garry89d53322015-11-18 00:50:35 +0800730 }
John Garry6be6de12015-11-18 00:50:34 +0800731
John Garry7eb78692015-11-18 00:50:31 +0800732 return shost;
733err_out:
734 dev_err(dev, "shost alloc failed\n");
735 return NULL;
736}
737
John Garry5d742422015-11-18 00:50:38 +0800738static void hisi_sas_init_add(struct hisi_hba *hisi_hba)
739{
740 int i;
741
742 for (i = 0; i < hisi_hba->n_phy; i++)
743 memcpy(&hisi_hba->phy[i].dev_sas_addr,
744 hisi_hba->sas_addr,
745 SAS_ADDR_SIZE);
746}
747
John Garry7eb78692015-11-18 00:50:31 +0800748int hisi_sas_probe(struct platform_device *pdev,
749 const struct hisi_sas_hw *hw)
750{
751 struct Scsi_Host *shost;
752 struct hisi_hba *hisi_hba;
753 struct device *dev = &pdev->dev;
754 struct asd_sas_phy **arr_phy;
755 struct asd_sas_port **arr_port;
756 struct sas_ha_struct *sha;
757 int rc, phy_nr, port_nr, i;
758
759 shost = hisi_sas_shost_alloc(pdev, hw);
760 if (!shost) {
761 rc = -ENOMEM;
762 goto err_out_ha;
763 }
764
765 sha = SHOST_TO_SAS_HA(shost);
766 hisi_hba = shost_priv(shost);
767 platform_set_drvdata(pdev, sha);
John Garry50cb9162015-11-18 00:50:39 +0800768
769 if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) &&
770 dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
771 dev_err(dev, "No usable DMA addressing method\n");
772 rc = -EIO;
773 goto err_out_ha;
774 }
775
John Garry7eb78692015-11-18 00:50:31 +0800776 phy_nr = port_nr = hisi_hba->n_phy;
777
778 arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL);
779 arr_port = devm_kcalloc(dev, port_nr, sizeof(void *), GFP_KERNEL);
780 if (!arr_phy || !arr_port)
781 return -ENOMEM;
782
783 sha->sas_phy = arr_phy;
784 sha->sas_port = arr_port;
785 sha->core.shost = shost;
786 sha->lldd_ha = hisi_hba;
787
788 shost->transportt = hisi_sas_stt;
789 shost->max_id = HISI_SAS_MAX_DEVICES;
790 shost->max_lun = ~0;
791 shost->max_channel = 1;
792 shost->max_cmd_len = 16;
793 shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
794 shost->can_queue = HISI_SAS_COMMAND_ENTRIES;
795 shost->cmd_per_lun = HISI_SAS_COMMAND_ENTRIES;
796
797 sha->sas_ha_name = DRV_NAME;
798 sha->dev = &hisi_hba->pdev->dev;
799 sha->lldd_module = THIS_MODULE;
800 sha->sas_addr = &hisi_hba->sas_addr[0];
801 sha->num_phys = hisi_hba->n_phy;
802 sha->core.shost = hisi_hba->shost;
803
804 for (i = 0; i < hisi_hba->n_phy; i++) {
805 sha->sas_phy[i] = &hisi_hba->phy[i].sas_phy;
806 sha->sas_port[i] = &hisi_hba->port[i].sas_port;
807 }
808
John Garry5d742422015-11-18 00:50:38 +0800809 hisi_sas_init_add(hisi_hba);
810
John Garry8ff1d572015-11-18 00:50:46 +0800811 rc = hisi_hba->hw->hw_init(hisi_hba);
812 if (rc)
813 goto err_out_ha;
814
John Garry7eb78692015-11-18 00:50:31 +0800815 rc = scsi_add_host(shost, &pdev->dev);
816 if (rc)
817 goto err_out_ha;
818
819 rc = sas_register_ha(sha);
820 if (rc)
821 goto err_out_register_ha;
822
823 scsi_scan_host(shost);
824
825 return 0;
826
827err_out_register_ha:
828 scsi_remove_host(shost);
829err_out_ha:
830 kfree(shost);
831 return rc;
832}
833EXPORT_SYMBOL_GPL(hisi_sas_probe);
834
John Garry89d53322015-11-18 00:50:35 +0800835int hisi_sas_remove(struct platform_device *pdev)
836{
837 struct sas_ha_struct *sha = platform_get_drvdata(pdev);
838 struct hisi_hba *hisi_hba = sha->lldd_ha;
839
840 scsi_remove_host(sha->core.shost);
841 sas_unregister_ha(sha);
842 sas_remove_host(sha->core.shost);
843
844 hisi_sas_free(hisi_hba);
845 return 0;
846}
847EXPORT_SYMBOL_GPL(hisi_sas_remove);
848
John Garrye8899fa2015-11-18 00:50:30 +0800849static __init int hisi_sas_init(void)
850{
851 pr_info("hisi_sas: driver version %s\n", DRV_VERSION);
852
853 hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops);
854 if (!hisi_sas_stt)
855 return -ENOMEM;
856
857 return 0;
858}
859
860static __exit void hisi_sas_exit(void)
861{
862 sas_release_transport(hisi_sas_stt);
863}
864
865module_init(hisi_sas_init);
866module_exit(hisi_sas_exit);
867
868MODULE_VERSION(DRV_VERSION);
869MODULE_LICENSE("GPL");
870MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
871MODULE_DESCRIPTION("HISILICON SAS controller driver");
872MODULE_ALIAS("platform:" DRV_NAME);