hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/scsi/hisi_sas/hisi_sas_main.c
....@@ -1,16 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (c) 2015 Linaro Ltd.
34 * 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
- *
105 */
116
127 #include "hisi_sas.h"
13
-#include "../libsas/sas_internal.h"
148 #define DRV_NAME "hisi_sas"
159
1610 #define DEV_IS_GONE(dev) \
....@@ -124,28 +118,13 @@
124118 }
125119 EXPORT_SYMBOL_GPL(hisi_sas_sata_done);
126120
127
-int hisi_sas_get_ncq_tag(struct sas_task *task, u32 *tag)
128
-{
129
- struct ata_queued_cmd *qc = task->uldd_task;
130
-
131
- if (qc) {
132
- if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
133
- qc->tf.command == ATA_CMD_FPDMA_READ) {
134
- *tag = qc->tag;
135
- return 1;
136
- }
137
- }
138
- return 0;
139
-}
140
-EXPORT_SYMBOL_GPL(hisi_sas_get_ncq_tag);
141
-
142121 /*
143122 * This function assumes linkrate mask fits in 8 bits, which it
144123 * does for all HW versions supported.
145124 */
146125 u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max)
147126 {
148
- u16 rate = 0;
127
+ u8 rate = 0;
149128 int i;
150129
151130 max -= SAS_LINK_RATE_1_5_GBPS;
....@@ -171,7 +150,7 @@
171150 int phy_no;
172151
173152 for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++)
174
- hisi_hba->hw->phy_disable(hisi_hba, phy_no);
153
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
175154 }
176155 EXPORT_SYMBOL_GPL(hisi_sas_stop_phys);
177156
....@@ -184,7 +163,12 @@
184163
185164 static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx)
186165 {
187
- hisi_sas_slot_index_clear(hisi_hba, slot_idx);
166
+ if (hisi_hba->hw->slot_index_alloc ||
167
+ slot_idx >= HISI_SAS_UNRESERVED_IPTT) {
168
+ spin_lock(&hisi_hba->lock);
169
+ hisi_sas_slot_index_clear(hisi_hba, slot_idx);
170
+ spin_unlock(&hisi_hba->lock);
171
+ }
188172 }
189173
190174 static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx)
....@@ -194,24 +178,32 @@
194178 set_bit(slot_idx, bitmap);
195179 }
196180
197
-static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx)
181
+static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba,
182
+ struct scsi_cmnd *scsi_cmnd)
198183 {
199
- unsigned int index;
184
+ int index;
200185 void *bitmap = hisi_hba->slot_index_tags;
201186
187
+ if (scsi_cmnd)
188
+ return scsi_cmnd->request->tag;
189
+
190
+ spin_lock(&hisi_hba->lock);
202191 index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
203
- hisi_hba->last_slot_index + 1);
192
+ hisi_hba->last_slot_index + 1);
204193 if (index >= hisi_hba->slot_index_count) {
205
- index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
206
- 0);
207
- if (index >= hisi_hba->slot_index_count)
194
+ index = find_next_zero_bit(bitmap,
195
+ hisi_hba->slot_index_count,
196
+ HISI_SAS_UNRESERVED_IPTT);
197
+ if (index >= hisi_hba->slot_index_count) {
198
+ spin_unlock(&hisi_hba->lock);
208199 return -SAS_QUEUE_FULL;
200
+ }
209201 }
210202 hisi_sas_slot_index_set(hisi_hba, index);
211
- *slot_idx = index;
212203 hisi_hba->last_slot_index = index;
204
+ spin_unlock(&hisi_hba->lock);
213205
214
- return 0;
206
+ return index;
215207 }
216208
217209 static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba)
....@@ -225,8 +217,8 @@
225217 void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
226218 struct hisi_sas_slot *slot)
227219 {
228
- struct hisi_sas_dq *dq = &hisi_hba->dq[slot->dlvry_queue];
229
- unsigned long flags;
220
+ int device_id = slot->device_id;
221
+ struct hisi_sas_device *sas_dev = &hisi_hba->devices[device_id];
230222
231223 if (task) {
232224 struct device *dev = hisi_hba->dev;
....@@ -236,23 +228,29 @@
236228
237229 task->lldd_task = NULL;
238230
239
- if (!sas_protocol_ata(task->task_proto))
231
+ if (!sas_protocol_ata(task->task_proto)) {
240232 if (slot->n_elem)
241233 dma_unmap_sg(dev, task->scatter,
242234 task->num_scatter,
243235 task->data_dir);
236
+ if (slot->n_elem_dif) {
237
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
238
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
239
+
240
+ dma_unmap_sg(dev, scsi_prot_sglist(scsi_cmnd),
241
+ scsi_prot_sg_count(scsi_cmnd),
242
+ task->data_dir);
243
+ }
244
+ }
244245 }
245246
246
-
247
- spin_lock_irqsave(&dq->lock, flags);
247
+ spin_lock(&sas_dev->lock);
248248 list_del_init(&slot->entry);
249
- spin_unlock_irqrestore(&dq->lock, flags);
249
+ spin_unlock(&sas_dev->lock);
250250
251251 memset(slot, 0, offsetof(struct hisi_sas_slot, buf));
252252
253
- spin_lock_irqsave(&hisi_hba->lock, flags);
254253 hisi_sas_slot_index_free(hisi_hba, slot->idx);
255
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
256254 }
257255 EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free);
258256
....@@ -282,6 +280,129 @@
282280 device_id, abort_flag, tag_to_abort);
283281 }
284282
283
+static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba,
284
+ struct sas_task *task, int n_elem,
285
+ int n_elem_req)
286
+{
287
+ struct device *dev = hisi_hba->dev;
288
+
289
+ if (!sas_protocol_ata(task->task_proto)) {
290
+ if (task->num_scatter) {
291
+ if (n_elem)
292
+ dma_unmap_sg(dev, task->scatter,
293
+ task->num_scatter,
294
+ task->data_dir);
295
+ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
296
+ if (n_elem_req)
297
+ dma_unmap_sg(dev, &task->smp_task.smp_req,
298
+ 1, DMA_TO_DEVICE);
299
+ }
300
+ }
301
+}
302
+
303
+static int hisi_sas_dma_map(struct hisi_hba *hisi_hba,
304
+ struct sas_task *task, int *n_elem,
305
+ int *n_elem_req)
306
+{
307
+ struct device *dev = hisi_hba->dev;
308
+ int rc;
309
+
310
+ if (sas_protocol_ata(task->task_proto)) {
311
+ *n_elem = task->num_scatter;
312
+ } else {
313
+ unsigned int req_len;
314
+
315
+ if (task->num_scatter) {
316
+ *n_elem = dma_map_sg(dev, task->scatter,
317
+ task->num_scatter, task->data_dir);
318
+ if (!*n_elem) {
319
+ rc = -ENOMEM;
320
+ goto prep_out;
321
+ }
322
+ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
323
+ *n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
324
+ 1, DMA_TO_DEVICE);
325
+ if (!*n_elem_req) {
326
+ rc = -ENOMEM;
327
+ goto prep_out;
328
+ }
329
+ req_len = sg_dma_len(&task->smp_task.smp_req);
330
+ if (req_len & 0x3) {
331
+ rc = -EINVAL;
332
+ goto err_out_dma_unmap;
333
+ }
334
+ }
335
+ }
336
+
337
+ if (*n_elem > HISI_SAS_SGE_PAGE_CNT) {
338
+ dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT\n",
339
+ *n_elem);
340
+ rc = -EINVAL;
341
+ goto err_out_dma_unmap;
342
+ }
343
+ return 0;
344
+
345
+err_out_dma_unmap:
346
+ /* It would be better to call dma_unmap_sg() here, but it's messy */
347
+ hisi_sas_dma_unmap(hisi_hba, task, *n_elem,
348
+ *n_elem_req);
349
+prep_out:
350
+ return rc;
351
+}
352
+
353
+static void hisi_sas_dif_dma_unmap(struct hisi_hba *hisi_hba,
354
+ struct sas_task *task, int n_elem_dif)
355
+{
356
+ struct device *dev = hisi_hba->dev;
357
+
358
+ if (n_elem_dif) {
359
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
360
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
361
+
362
+ dma_unmap_sg(dev, scsi_prot_sglist(scsi_cmnd),
363
+ scsi_prot_sg_count(scsi_cmnd),
364
+ task->data_dir);
365
+ }
366
+}
367
+
368
+static int hisi_sas_dif_dma_map(struct hisi_hba *hisi_hba,
369
+ int *n_elem_dif, struct sas_task *task)
370
+{
371
+ struct device *dev = hisi_hba->dev;
372
+ struct sas_ssp_task *ssp_task;
373
+ struct scsi_cmnd *scsi_cmnd;
374
+ int rc;
375
+
376
+ if (task->num_scatter) {
377
+ ssp_task = &task->ssp_task;
378
+ scsi_cmnd = ssp_task->cmd;
379
+
380
+ if (scsi_prot_sg_count(scsi_cmnd)) {
381
+ *n_elem_dif = dma_map_sg(dev,
382
+ scsi_prot_sglist(scsi_cmnd),
383
+ scsi_prot_sg_count(scsi_cmnd),
384
+ task->data_dir);
385
+
386
+ if (!*n_elem_dif)
387
+ return -ENOMEM;
388
+
389
+ if (*n_elem_dif > HISI_SAS_SGE_DIF_PAGE_CNT) {
390
+ dev_err(dev, "task prep: n_elem_dif(%d) too large\n",
391
+ *n_elem_dif);
392
+ rc = -EINVAL;
393
+ goto err_out_dif_dma_unmap;
394
+ }
395
+ }
396
+ }
397
+
398
+ return 0;
399
+
400
+err_out_dif_dma_unmap:
401
+ dma_unmap_sg(dev, scsi_prot_sglist(scsi_cmnd),
402
+ scsi_prot_sg_count(scsi_cmnd), task->data_dir);
403
+ return rc;
404
+}
405
+
285406 static int hisi_sas_task_prep(struct sas_task *task,
286407 struct hisi_sas_dq **dq_pointer,
287408 bool is_tmf, struct hisi_sas_tmf_task *tmf,
....@@ -296,24 +417,11 @@
296417 struct asd_sas_port *sas_port = device->port;
297418 struct device *dev = hisi_hba->dev;
298419 int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
299
- int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
420
+ int n_elem = 0, n_elem_dif = 0, n_elem_req = 0;
421
+ struct scsi_cmnd *scmd = NULL;
300422 struct hisi_sas_dq *dq;
301423 unsigned long flags;
302424 int wr_q_index;
303
-
304
- if (!sas_port) {
305
- struct task_status_struct *ts = &task->task_status;
306
-
307
- ts->resp = SAS_TASK_UNDELIVERED;
308
- ts->stat = SAS_PHY_DOWN;
309
- /*
310
- * libsas will use dev->port, should
311
- * not call task_done for sata
312
- */
313
- if (device->dev_type != SAS_SATA_DEV)
314
- task->task_done(task);
315
- return -ECOMM;
316
- }
317425
318426 if (DEV_IS_GONE(sas_dev)) {
319427 if (sas_dev)
....@@ -326,7 +434,33 @@
326434 return -ECOMM;
327435 }
328436
329
- *dq_pointer = dq = sas_dev->dq;
437
+ if (task->uldd_task) {
438
+ struct ata_queued_cmd *qc;
439
+
440
+ if (dev_is_sata(device)) {
441
+ qc = task->uldd_task;
442
+ scmd = qc->scsicmd;
443
+ } else {
444
+ scmd = task->uldd_task;
445
+ }
446
+ }
447
+
448
+ if (scmd && hisi_hba->shost->nr_hw_queues) {
449
+ unsigned int dq_index;
450
+ u32 blk_tag;
451
+
452
+ blk_tag = blk_mq_unique_tag(scmd->request);
453
+ dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
454
+ *dq_pointer = dq = &hisi_hba->dq[dq_index];
455
+ } else if (hisi_hba->shost->nr_hw_queues) {
456
+ struct Scsi_Host *shost = hisi_hba->shost;
457
+ struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
458
+ int queue = qmap->mq_map[raw_smp_processor_id()];
459
+
460
+ *dq_pointer = dq = &hisi_hba->dq[queue];
461
+ } else {
462
+ *dq_pointer = dq = sas_dev->dq;
463
+ }
330464
331465 port = to_hisi_sas_port(sas_port);
332466 if (port && !port->port_attached) {
....@@ -338,78 +472,43 @@
338472 return -ECOMM;
339473 }
340474
475
+ rc = hisi_sas_dma_map(hisi_hba, task, &n_elem,
476
+ &n_elem_req);
477
+ if (rc < 0)
478
+ goto prep_out;
479
+
341480 if (!sas_protocol_ata(task->task_proto)) {
342
- unsigned int req_len, resp_len;
343
-
344
- if (task->num_scatter) {
345
- n_elem = dma_map_sg(dev, task->scatter,
346
- task->num_scatter, task->data_dir);
347
- if (!n_elem) {
348
- rc = -ENOMEM;
349
- goto prep_out;
350
- }
351
- } else if (task->task_proto & SAS_PROTOCOL_SMP) {
352
- n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
353
- 1, DMA_TO_DEVICE);
354
- if (!n_elem_req) {
355
- rc = -ENOMEM;
356
- goto prep_out;
357
- }
358
- req_len = sg_dma_len(&task->smp_task.smp_req);
359
- if (req_len & 0x3) {
360
- rc = -EINVAL;
361
- goto err_out_dma_unmap;
362
- }
363
- n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
364
- 1, DMA_FROM_DEVICE);
365
- if (!n_elem_resp) {
366
- rc = -ENOMEM;
367
- goto err_out_dma_unmap;
368
- }
369
- resp_len = sg_dma_len(&task->smp_task.smp_resp);
370
- if (resp_len & 0x3) {
371
- rc = -EINVAL;
372
- goto err_out_dma_unmap;
373
- }
374
- }
375
- } else
376
- n_elem = task->num_scatter;
377
-
378
- if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
379
- dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
380
- n_elem);
381
- rc = -EINVAL;
382
- goto err_out_dma_unmap;
481
+ rc = hisi_sas_dif_dma_map(hisi_hba, &n_elem_dif, task);
482
+ if (rc < 0)
483
+ goto err_out_dma_unmap;
383484 }
384485
385
- spin_lock_irqsave(&hisi_hba->lock, flags);
386486 if (hisi_hba->hw->slot_index_alloc)
387
- rc = hisi_hba->hw->slot_index_alloc(hisi_hba, &slot_idx,
388
- device);
487
+ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
389488 else
390
- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
391
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
392
- if (rc)
393
- goto err_out_dma_unmap;
489
+ rc = hisi_sas_slot_index_alloc(hisi_hba, scmd);
394490
491
+ if (rc < 0)
492
+ goto err_out_dif_dma_unmap;
493
+
494
+ slot_idx = rc;
395495 slot = &hisi_hba->slot_info[slot_idx];
396496
397
- spin_lock_irqsave(&dq->lock, flags);
398
- wr_q_index = hisi_hba->hw->get_free_slot(hisi_hba, dq);
399
- if (wr_q_index < 0) {
400
- spin_unlock_irqrestore(&dq->lock, flags);
401
- rc = -EAGAIN;
402
- goto err_out_tag;
403
- }
404
-
497
+ spin_lock(&dq->lock);
498
+ wr_q_index = dq->wr_point;
499
+ dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS;
405500 list_add_tail(&slot->delivery, &dq->list);
501
+ spin_unlock(&dq->lock);
502
+ spin_lock(&sas_dev->lock);
406503 list_add_tail(&slot->entry, &sas_dev->list);
407
- spin_unlock_irqrestore(&dq->lock, flags);
504
+ spin_unlock(&sas_dev->lock);
408505
409506 dlvry_queue = dq->id;
410507 dlvry_queue_slot = wr_q_index;
411508
509
+ slot->device_id = sas_dev->device_id;
412510 slot->n_elem = n_elem;
511
+ slot->n_elem_dif = n_elem_dif;
413512 slot->dlvry_queue = dlvry_queue;
414513 slot->dlvry_queue_slot = dlvry_queue_slot;
415514 cmd_hdr_base = hisi_hba->cmd_hdr[dlvry_queue];
....@@ -422,7 +521,8 @@
422521
423522 memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
424523 memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
425
- memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
524
+ memset(hisi_sas_status_buf_addr_mem(slot), 0,
525
+ sizeof(struct hisi_sas_err_record));
426526
427527 switch (task->task_proto) {
428528 case SAS_PROTOCOL_SMP:
....@@ -451,24 +551,12 @@
451551
452552 return 0;
453553
454
-err_out_tag:
455
- spin_lock_irqsave(&hisi_hba->lock, flags);
456
- hisi_sas_slot_index_free(hisi_hba, slot_idx);
457
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
554
+err_out_dif_dma_unmap:
555
+ if (!sas_protocol_ata(task->task_proto))
556
+ hisi_sas_dif_dma_unmap(hisi_hba, task, n_elem_dif);
458557 err_out_dma_unmap:
459
- if (!sas_protocol_ata(task->task_proto)) {
460
- if (task->num_scatter) {
461
- dma_unmap_sg(dev, task->scatter, task->num_scatter,
462
- task->data_dir);
463
- } else if (task->task_proto & SAS_PROTOCOL_SMP) {
464
- if (n_elem_req)
465
- dma_unmap_sg(dev, &task->smp_task.smp_req,
466
- 1, DMA_TO_DEVICE);
467
- if (n_elem_resp)
468
- dma_unmap_sg(dev, &task->smp_task.smp_resp,
469
- 1, DMA_FROM_DEVICE);
470
- }
471
- }
558
+ hisi_sas_dma_unmap(hisi_hba, task, n_elem,
559
+ n_elem_req);
472560 prep_out:
473561 dev_err(dev, "task prep: failed[%d]!\n", rc);
474562 return rc;
....@@ -479,10 +567,28 @@
479567 {
480568 u32 rc;
481569 u32 pass = 0;
482
- unsigned long flags;
483
- struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev);
484
- struct device *dev = hisi_hba->dev;
570
+ struct hisi_hba *hisi_hba;
571
+ struct device *dev;
572
+ struct domain_device *device = task->dev;
573
+ struct asd_sas_port *sas_port = device->port;
485574 struct hisi_sas_dq *dq = NULL;
575
+
576
+ if (!sas_port) {
577
+ struct task_status_struct *ts = &task->task_status;
578
+
579
+ ts->resp = SAS_TASK_UNDELIVERED;
580
+ ts->stat = SAS_PHY_DOWN;
581
+ /*
582
+ * libsas will use dev->port, should
583
+ * not call task_done for sata
584
+ */
585
+ if (device->dev_type != SAS_SATA_DEV)
586
+ task->task_done(task);
587
+ return -ECOMM;
588
+ }
589
+
590
+ hisi_hba = dev_to_hisi_hba(device);
591
+ dev = hisi_hba->dev;
486592
487593 if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
488594 /*
....@@ -504,9 +610,9 @@
504610 dev_err(dev, "task exec: failed[%d]!\n", rc);
505611
506612 if (likely(pass)) {
507
- spin_lock_irqsave(&dq->lock, flags);
613
+ spin_lock(&dq->lock);
508614 hisi_hba->hw->start_delivery(dq);
509
- spin_unlock_irqrestore(&dq->lock, flags);
615
+ spin_unlock(&dq->lock);
510616 }
511617
512618 return rc;
....@@ -516,13 +622,17 @@
516622 {
517623 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
518624 struct asd_sas_phy *sas_phy = &phy->sas_phy;
519
- struct sas_ha_struct *sas_ha;
520625
521626 if (!phy->phy_attached)
522627 return;
523628
524
- sas_ha = &hisi_hba->sha;
525
- sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE);
629
+ if (test_bit(HISI_SAS_PM_BIT, &hisi_hba->flags) &&
630
+ !sas_phy->suspended) {
631
+ dev_warn(hisi_hba->dev, "phy%d during suspend filtered out\n", phy_no);
632
+ return;
633
+ }
634
+
635
+ sas_notify_phy_event(sas_phy, PHYE_OOB_DONE);
526636
527637 if (sas_phy->phy) {
528638 struct sas_phy *sphy = sas_phy->phy;
....@@ -546,23 +656,22 @@
546656 id->initiator_bits = SAS_PROTOCOL_ALL;
547657 id->target_bits = phy->identify.target_port_protocols;
548658 } else if (phy->phy_type & PORT_TYPE_SATA) {
549
- /*Nothing*/
659
+ /* Nothing */
550660 }
551661
552662 sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
553
- sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED);
663
+ sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED);
554664 }
555665
556666 static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
557667 {
558668 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
559669 struct hisi_sas_device *sas_dev = NULL;
560
- unsigned long flags;
561670 int last = hisi_hba->last_dev_id;
562671 int first = (hisi_hba->last_dev_id + 1) % HISI_SAS_MAX_DEVICES;
563672 int i;
564673
565
- spin_lock_irqsave(&hisi_hba->lock, flags);
674
+ spin_lock(&hisi_hba->lock);
566675 for (i = first; i != last; i %= HISI_SAS_MAX_DEVICES) {
567676 if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) {
568677 int queue = i % hisi_hba->queue_count;
....@@ -570,45 +679,77 @@
570679
571680 hisi_hba->devices[i].device_id = i;
572681 sas_dev = &hisi_hba->devices[i];
573
- sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
682
+ sas_dev->dev_status = HISI_SAS_DEV_INIT;
574683 sas_dev->dev_type = device->dev_type;
575684 sas_dev->hisi_hba = hisi_hba;
576685 sas_dev->sas_device = device;
577686 sas_dev->dq = dq;
687
+ spin_lock_init(&sas_dev->lock);
578688 INIT_LIST_HEAD(&hisi_hba->devices[i].list);
579689 break;
580690 }
581691 i++;
582692 }
583693 hisi_hba->last_dev_id = i;
584
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
694
+ spin_unlock(&hisi_hba->lock);
585695
586696 return sas_dev;
587697 }
588698
589
-#define HISI_SAS_SRST_ATA_DISK_CNT 3
699
+#define HISI_SAS_DISK_RECOVER_CNT 3
590700 static int hisi_sas_init_device(struct domain_device *device)
591701 {
592702 int rc = TMF_RESP_FUNC_COMPLETE;
593703 struct scsi_lun lun;
594704 struct hisi_sas_tmf_task tmf_task;
595
- int retry = HISI_SAS_SRST_ATA_DISK_CNT;
705
+ int retry = HISI_SAS_DISK_RECOVER_CNT;
596706 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
707
+ struct device *dev = hisi_hba->dev;
708
+ struct sas_phy *local_phy;
597709
598710 switch (device->dev_type) {
599711 case SAS_END_DEVICE:
600712 int_to_scsilun(0, &lun);
601713
602714 tmf_task.tmf = TMF_CLEAR_TASK_SET;
603
- rc = hisi_sas_debug_issue_ssp_tmf(device, lun.scsi_lun,
604
- &tmf_task);
605
- if (rc == TMF_RESP_FUNC_COMPLETE)
606
- hisi_sas_release_task(hisi_hba, device);
715
+ while (retry-- > 0) {
716
+ rc = hisi_sas_debug_issue_ssp_tmf(device, lun.scsi_lun,
717
+ &tmf_task);
718
+ if (rc == TMF_RESP_FUNC_COMPLETE) {
719
+ hisi_sas_release_task(hisi_hba, device);
720
+ break;
721
+ }
722
+ }
607723 break;
608724 case SAS_SATA_DEV:
609725 case SAS_SATA_PM:
610726 case SAS_SATA_PM_PORT:
611727 case SAS_SATA_PENDING:
728
+ /*
729
+ * send HARD RESET to clear previous affiliation of
730
+ * STP target port
731
+ */
732
+ local_phy = sas_get_local_phy(device);
733
+ if (!scsi_is_sas_phy_local(local_phy) &&
734
+ !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) {
735
+ unsigned long deadline = ata_deadline(jiffies, 20000);
736
+ struct sata_device *sata_dev = &device->sata_dev;
737
+ struct ata_host *ata_host = sata_dev->ata_host;
738
+ struct ata_port_operations *ops = ata_host->ops;
739
+ struct ata_port *ap = sata_dev->ap;
740
+ struct ata_link *link;
741
+ unsigned int classes;
742
+
743
+ ata_for_each_link(link, ap, EDGE)
744
+ rc = ops->hardreset(link, &classes,
745
+ deadline);
746
+ }
747
+ sas_put_local_phy(local_phy);
748
+ if (rc) {
749
+ dev_warn(dev, "SATA disk hardreset fail: %d\n", rc);
750
+ return rc;
751
+ }
752
+
612753 while (retry-- > 0) {
613754 rc = hisi_sas_softreset_ata_disk(device);
614755 if (!rc)
....@@ -643,7 +784,7 @@
643784 device->lldd_dev = sas_dev;
644785 hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
645786
646
- if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) {
787
+ if (parent_dev && dev_is_expander(parent_dev->dev_type)) {
647788 int phy_no;
648789 u8 phy_num = parent_dev->ex_dev.num_phys;
649790 struct ex_phy *phy;
....@@ -671,6 +812,7 @@
671812 rc = hisi_sas_init_device(device);
672813 if (rc)
673814 goto err_out;
815
+ sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
674816 return 0;
675817
676818 err_out:
....@@ -753,6 +895,33 @@
753895 }
754896 EXPORT_SYMBOL_GPL(hisi_sas_notify_phy_event);
755897
898
+static void hisi_sas_wait_phyup_timedout(struct timer_list *t)
899
+{
900
+ struct hisi_sas_phy *phy = from_timer(phy, t, timer);
901
+ struct hisi_hba *hisi_hba = phy->hisi_hba;
902
+ struct device *dev = hisi_hba->dev;
903
+ int phy_no = phy->sas_phy.id;
904
+
905
+ dev_warn(dev, "phy%d wait phyup timeout, issuing link reset\n", phy_no);
906
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
907
+}
908
+
909
+void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no)
910
+{
911
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
912
+ struct device *dev = hisi_hba->dev;
913
+
914
+ dev_dbg(dev, "phy%d OOB ready\n", phy_no);
915
+ if (phy->phy_attached)
916
+ return;
917
+
918
+ if (!timer_pending(&phy->timer)) {
919
+ phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ;
920
+ add_timer(&phy->timer);
921
+ }
922
+}
923
+EXPORT_SYMBOL_GPL(hisi_sas_phy_oob_ready);
924
+
756925 static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no)
757926 {
758927 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
....@@ -781,7 +950,33 @@
781950 INIT_WORK(&phy->works[i], hisi_sas_phye_fns[i]);
782951
783952 spin_lock_init(&phy->lock);
953
+
954
+ timer_setup(&phy->timer, hisi_sas_wait_phyup_timedout, 0);
784955 }
956
+
957
+/* Wrapper to ensure we track hisi_sas_phy.enable properly */
958
+void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no, int enable)
959
+{
960
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
961
+ struct asd_sas_phy *aphy = &phy->sas_phy;
962
+ struct sas_phy *sphy = aphy->phy;
963
+ unsigned long flags;
964
+
965
+ spin_lock_irqsave(&phy->lock, flags);
966
+
967
+ if (enable) {
968
+ /* We may have been enabled already; if so, don't touch */
969
+ if (!phy->enable)
970
+ sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
971
+ hisi_hba->hw->phy_start(hisi_hba, phy_no);
972
+ } else {
973
+ sphy->negotiated_linkrate = SAS_PHY_DISABLED;
974
+ hisi_hba->hw->phy_disable(hisi_hba, phy_no);
975
+ }
976
+ phy->enable = enable;
977
+ spin_unlock_irqrestore(&phy->lock, flags);
978
+}
979
+EXPORT_SYMBOL_GPL(hisi_sas_phy_enable);
785980
786981 static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy)
787982 {
....@@ -867,25 +1062,30 @@
8671062 struct hisi_sas_device *sas_dev = device->lldd_dev;
8681063 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
8691064 struct device *dev = hisi_hba->dev;
1065
+ int ret = 0;
8701066
8711067 dev_info(dev, "dev[%d:%x] is gone\n",
8721068 sas_dev->device_id, sas_dev->dev_type);
8731069
1070
+ down(&hisi_hba->sem);
8741071 if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) {
8751072 hisi_sas_internal_task_abort(hisi_hba, device,
876
- HISI_SAS_INT_ABT_DEV, 0);
1073
+ HISI_SAS_INT_ABT_DEV, 0);
8771074
8781075 hisi_sas_dereg_device(hisi_hba, device);
8791076
880
- down(&hisi_hba->sem);
881
- hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
882
- up(&hisi_hba->sem);
1077
+ ret = hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
8831078 device->lldd_dev = NULL;
8841079 }
8851080
8861081 if (hisi_hba->hw->free_device)
8871082 hisi_hba->hw->free_device(sas_dev);
888
- sas_dev->dev_type = SAS_PHY_UNUSED;
1083
+
1084
+ /* Don't mark it as SAS_PHY_UNUSED if failed to clear ITCT */
1085
+ if (!ret)
1086
+ sas_dev->dev_type = SAS_PHY_UNUSED;
1087
+ sas_dev->sas_device = NULL;
1088
+ up(&hisi_hba->sem);
8891089 }
8901090
8911091 static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags)
....@@ -920,10 +1120,10 @@
9201120 sas_phy->phy->maximum_linkrate = max;
9211121 sas_phy->phy->minimum_linkrate = min;
9221122
923
- hisi_hba->hw->phy_disable(hisi_hba, phy_no);
1123
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
9241124 msleep(100);
9251125 hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
926
- hisi_hba->hw->phy_start(hisi_hba, phy_no);
1126
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
9271127
9281128 return 0;
9291129 }
....@@ -941,13 +1141,13 @@
9411141 break;
9421142
9431143 case PHY_FUNC_LINK_RESET:
944
- hisi_hba->hw->phy_disable(hisi_hba, phy_no);
1144
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
9451145 msleep(100);
946
- hisi_hba->hw->phy_start(hisi_hba, phy_no);
1146
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
9471147 break;
9481148
9491149 case PHY_FUNC_DISABLE:
950
- hisi_hba->hw->phy_disable(hisi_hba, phy_no);
1150
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
9511151 break;
9521152
9531153 case PHY_FUNC_SET_LINK_RATE:
....@@ -957,7 +1157,7 @@
9571157 hisi_hba->hw->get_events(hisi_hba, phy_no);
9581158 break;
9591159 }
960
- /* fallthru */
1160
+ fallthrough;
9611161 case PHY_FUNC_RELEASE_SPINUP_HOLD:
9621162 default:
9631163 return -EOPNOTSUPP;
....@@ -1019,7 +1219,7 @@
10191219 task->task_done = hisi_sas_task_done;
10201220
10211221 task->slow_task->timer.function = hisi_sas_tmf_timedout;
1022
- task->slow_task->timer.expires = jiffies + TASK_TIMEOUT*HZ;
1222
+ task->slow_task->timer.expires = jiffies + TASK_TIMEOUT * HZ;
10231223 add_timer(&task->slow_task->timer);
10241224
10251225 res = hisi_sas_task_exec(task, GFP_KERNEL, 1, tmf);
....@@ -1043,10 +1243,10 @@
10431243 struct hisi_sas_cq *cq =
10441244 &hisi_hba->cq[slot->dlvry_queue];
10451245 /*
1046
- * flush tasklet to avoid free'ing task
1246
+ * sync irq to avoid free'ing task
10471247 * before using task in IO completion
10481248 */
1049
- tasklet_kill(&cq->tasklet);
1249
+ synchronize_irq(cq->irq_no);
10501250 slot->task = NULL;
10511251 }
10521252
....@@ -1072,8 +1272,7 @@
10721272 /* no error, but return the number of bytes of
10731273 * underrun
10741274 */
1075
- dev_warn(dev, "abort tmf: task to dev %016llx "
1076
- "resp: 0x%x sts 0x%x underrun\n",
1275
+ dev_warn(dev, "abort tmf: task to dev %016llx resp: 0x%x sts 0x%x underrun\n",
10771276 SAS_ADDR(device->sas_addr),
10781277 task->task_status.resp,
10791278 task->task_status.stat);
....@@ -1088,10 +1287,16 @@
10881287 break;
10891288 }
10901289
1091
- dev_warn(dev, "abort tmf: task to dev "
1092
- "%016llx resp: 0x%x status 0x%x\n",
1093
- SAS_ADDR(device->sas_addr), task->task_status.resp,
1094
- task->task_status.stat);
1290
+ if (task->task_status.resp == SAS_TASK_COMPLETE &&
1291
+ task->task_status.stat == SAS_OPEN_REJECT) {
1292
+ dev_warn(dev, "abort tmf: open reject failed\n");
1293
+ res = -EIO;
1294
+ } else {
1295
+ dev_warn(dev, "abort tmf: task to dev %016llx resp: 0x%x status 0x%x\n",
1296
+ SAS_ADDR(device->sas_addr),
1297
+ task->task_status.resp,
1298
+ task->task_status.stat);
1299
+ }
10951300 sas_free_task(task);
10961301 task = NULL;
10971302 }
....@@ -1203,15 +1408,13 @@
12031408 device->linkrate = phy->sas_phy.linkrate;
12041409
12051410 hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
1206
- } else
1411
+ } else if (!port->port_attached)
12071412 port->id = 0xff;
12081413 }
12091414 }
12101415
1211
-static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state,
1212
- u32 state)
1416
+static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
12131417 {
1214
- struct sas_ha_struct *sas_ha = &hisi_hba->sha;
12151418 struct asd_sas_port *_sas_port = NULL;
12161419 int phy_no;
12171420
....@@ -1219,7 +1422,7 @@
12191422 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
12201423 struct asd_sas_phy *sas_phy = &phy->sas_phy;
12211424 struct asd_sas_port *sas_port = sas_phy->port;
1222
- bool do_port_check = !!(_sas_port != sas_port);
1425
+ bool do_port_check = _sas_port != sas_port;
12231426
12241427 if (!sas_phy->phy->enabled)
12251428 continue;
....@@ -1231,14 +1434,13 @@
12311434
12321435 _sas_port = sas_port;
12331436
1234
- if (DEV_IS_EXPANDER(dev->dev_type))
1235
- sas_ha->notify_port_event(sas_phy,
1437
+ if (dev_is_expander(dev->dev_type))
1438
+ sas_notify_port_event(sas_phy,
12361439 PORTE_BROADCAST_RCVD);
12371440 }
1238
- } else if (old_state & (1 << phy_no))
1239
- /* PHY down but was up before */
1441
+ } else {
12401442 hisi_sas_phy_down(hisi_hba, phy_no, 0);
1241
-
1443
+ }
12421444 }
12431445 }
12441446
....@@ -1318,7 +1520,7 @@
13181520 struct domain_device *port_dev = sas_port->port_dev;
13191521 struct domain_device *device;
13201522
1321
- if (!port_dev || !DEV_IS_EXPANDER(port_dev->dev_type))
1523
+ if (!port_dev || !dev_is_expander(port_dev->dev_type))
13221524 continue;
13231525
13241526 /* Try to find a SATA device */
....@@ -1354,23 +1556,21 @@
13541556 void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
13551557 {
13561558 struct Scsi_Host *shost = hisi_hba->shost;
1357
- u32 state;
13581559
13591560 /* Init and wait for PHYs to come up and all libsas event finished. */
13601561 hisi_hba->hw->phys_init(hisi_hba);
13611562 msleep(1000);
13621563 hisi_sas_refresh_port_id(hisi_hba);
13631564 clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
1364
- up(&hisi_hba->sem);
13651565
13661566 if (hisi_hba->reject_stp_links_msk)
13671567 hisi_sas_terminate_stp_reject(hisi_hba);
13681568 hisi_sas_reset_init_all_devices(hisi_hba);
1569
+ up(&hisi_hba->sem);
13691570 scsi_unblock_requests(shost);
13701571 clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
13711572
1372
- state = hisi_hba->hw->get_phys_state(hisi_hba);
1373
- hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state, state);
1573
+ hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state);
13741574 }
13751575 EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done);
13761576
....@@ -1379,6 +1579,9 @@
13791579 struct device *dev = hisi_hba->dev;
13801580 struct Scsi_Host *shost = hisi_hba->shost;
13811581 int rc;
1582
+
1583
+ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct)
1584
+ queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
13821585
13831586 if (!hisi_hba->hw->soft_reset)
13841587 return -1;
....@@ -1429,11 +1632,11 @@
14291632
14301633 if (slot) {
14311634 /*
1432
- * flush tasklet to avoid free'ing task
1635
+ * sync irq to avoid free'ing task
14331636 * before using task in IO completion
14341637 */
14351638 cq = &hisi_hba->cq[slot->dlvry_queue];
1436
- tasklet_kill(&cq->tasklet);
1639
+ synchronize_irq(cq->irq_no);
14371640 }
14381641 spin_unlock_irqrestore(&task->task_state_lock, flags);
14391642 rc = TMF_RESP_FUNC_COMPLETE;
....@@ -1442,16 +1645,15 @@
14421645 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
14431646 spin_unlock_irqrestore(&task->task_state_lock, flags);
14441647
1445
- sas_dev->dev_status = HISI_SAS_DEV_EH;
14461648 if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
14471649 struct scsi_cmnd *cmnd = task->uldd_task;
14481650 struct hisi_sas_slot *slot = task->lldd_task;
1449
- u32 tag = slot->idx;
1651
+ u16 tag = slot->idx;
14501652 int rc2;
14511653
14521654 int_to_scsilun(cmnd->device->lun, &lun);
14531655 tmf_task.tmf = TMF_ABORT_TASK;
1454
- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
1656
+ tmf_task.tag_of_task_to_be_managed = tag;
14551657
14561658 rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun,
14571659 &tmf_task);
....@@ -1478,7 +1680,8 @@
14781680 task->task_proto & SAS_PROTOCOL_STP) {
14791681 if (task->dev->dev_type == SAS_SATA_DEV) {
14801682 rc = hisi_sas_internal_task_abort(hisi_hba, device,
1481
- HISI_SAS_INT_ABT_DEV, 0);
1683
+ HISI_SAS_INT_ABT_DEV,
1684
+ 0);
14821685 if (rc < 0) {
14831686 dev_err(dev, "abort task: internal abort failed\n");
14841687 goto out;
....@@ -1493,14 +1696,14 @@
14931696 struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue];
14941697
14951698 rc = hisi_sas_internal_task_abort(hisi_hba, device,
1496
- HISI_SAS_INT_ABT_CMD, tag);
1699
+ HISI_SAS_INT_ABT_CMD, tag);
14971700 if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) &&
14981701 task->lldd_task) {
14991702 /*
1500
- * flush tasklet to avoid free'ing task
1703
+ * sync irq to avoid free'ing task
15011704 * before using task in IO completion
15021705 */
1503
- tasklet_kill(&cq->tasklet);
1706
+ synchronize_irq(cq->irq_no);
15041707 slot->task = NULL;
15051708 }
15061709 }
....@@ -1516,10 +1719,10 @@
15161719 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
15171720 struct device *dev = hisi_hba->dev;
15181721 struct hisi_sas_tmf_task tmf_task;
1519
- int rc = TMF_RESP_FUNC_FAILED;
1722
+ int rc;
15201723
15211724 rc = hisi_sas_internal_task_abort(hisi_hba, device,
1522
- HISI_SAS_INT_ABT_DEV, 0);
1725
+ HISI_SAS_INT_ABT_DEV, 0);
15231726 if (rc < 0) {
15241727 dev_err(dev, "abort task set: internal abort rc=%d\n", rc);
15251728 return TMF_RESP_FUNC_FAILED;
....@@ -1537,8 +1740,8 @@
15371740
15381741 static int hisi_sas_clear_aca(struct domain_device *device, u8 *lun)
15391742 {
1540
- int rc = TMF_RESP_FUNC_FAILED;
15411743 struct hisi_sas_tmf_task tmf_task;
1744
+ int rc;
15421745
15431746 tmf_task.tmf = TMF_CLEAR_ACA;
15441747 rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task);
....@@ -1549,24 +1752,37 @@
15491752 static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
15501753 {
15511754 struct sas_phy *local_phy = sas_get_local_phy(device);
1552
- int rc, reset_type = (device->dev_type == SAS_SATA_DEV ||
1553
- (device->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
1755
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
15541756 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
15551757 struct sas_ha_struct *sas_ha = &hisi_hba->sha;
1556
- struct asd_sas_phy *sas_phy = sas_ha->sas_phy[local_phy->number];
1557
- struct hisi_sas_phy *phy = container_of(sas_phy,
1558
- struct hisi_sas_phy, sas_phy);
15591758 DECLARE_COMPLETION_ONSTACK(phyreset);
1759
+ int rc, reset_type;
1760
+
1761
+ if (!local_phy->enabled) {
1762
+ sas_put_local_phy(local_phy);
1763
+ return -ENODEV;
1764
+ }
15601765
15611766 if (scsi_is_sas_phy_local(local_phy)) {
1767
+ struct asd_sas_phy *sas_phy =
1768
+ sas_ha->sas_phy[local_phy->number];
1769
+ struct hisi_sas_phy *phy =
1770
+ container_of(sas_phy, struct hisi_sas_phy, sas_phy);
15621771 phy->in_reset = 1;
15631772 phy->reset_completion = &phyreset;
15641773 }
1774
+
1775
+ reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT ||
1776
+ !dev_is_sata(device)) ? true : false;
15651777
15661778 rc = sas_phy_reset(local_phy, reset_type);
15671779 sas_put_local_phy(local_phy);
15681780
15691781 if (scsi_is_sas_phy_local(local_phy)) {
1782
+ struct asd_sas_phy *sas_phy =
1783
+ sas_ha->sas_phy[local_phy->number];
1784
+ struct hisi_sas_phy *phy =
1785
+ container_of(sas_phy, struct hisi_sas_phy, sas_phy);
15701786 int ret = wait_for_completion_timeout(&phyreset, 2 * HZ);
15711787 unsigned long flags;
15721788
....@@ -1578,30 +1794,37 @@
15781794 /* report PHY down if timed out */
15791795 if (!ret)
15801796 hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
1581
- } else
1582
- msleep(2000);
1797
+ } else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) {
1798
+ /*
1799
+ * If in init state, we rely on caller to wait for link to be
1800
+ * ready; otherwise, except phy reset is fail, delay.
1801
+ */
1802
+ if (!rc)
1803
+ msleep(2000);
1804
+ }
15831805
15841806 return rc;
15851807 }
15861808
15871809 static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
15881810 {
1589
- struct hisi_sas_device *sas_dev = device->lldd_dev;
15901811 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
15911812 struct device *dev = hisi_hba->dev;
1592
- int rc = TMF_RESP_FUNC_FAILED;
1593
-
1594
- if (sas_dev->dev_status != HISI_SAS_DEV_EH)
1595
- return TMF_RESP_FUNC_FAILED;
1596
- sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
1813
+ int rc;
15971814
15981815 rc = hisi_sas_internal_task_abort(hisi_hba, device,
1599
- HISI_SAS_INT_ABT_DEV, 0);
1816
+ HISI_SAS_INT_ABT_DEV, 0);
16001817 if (rc < 0) {
16011818 dev_err(dev, "I_T nexus reset: internal abort (%d)\n", rc);
16021819 return TMF_RESP_FUNC_FAILED;
16031820 }
16041821 hisi_sas_dereg_device(hisi_hba, device);
1822
+
1823
+ if (dev_is_sata(device)) {
1824
+ rc = hisi_sas_softreset_ata_disk(device);
1825
+ if (rc == TMF_RESP_FUNC_FAILED)
1826
+ return TMF_RESP_FUNC_FAILED;
1827
+ }
16051828
16061829 rc = hisi_sas_debug_I_T_nexus_reset(device);
16071830
....@@ -1618,36 +1841,27 @@
16181841 struct device *dev = hisi_hba->dev;
16191842 int rc = TMF_RESP_FUNC_FAILED;
16201843
1621
- sas_dev->dev_status = HISI_SAS_DEV_EH;
1844
+ /* Clear internal IO and then lu reset */
1845
+ rc = hisi_sas_internal_task_abort(hisi_hba, device,
1846
+ HISI_SAS_INT_ABT_DEV, 0);
1847
+ if (rc < 0) {
1848
+ dev_err(dev, "lu_reset: internal abort failed\n");
1849
+ goto out;
1850
+ }
1851
+ hisi_sas_dereg_device(hisi_hba, device);
1852
+
16221853 if (dev_is_sata(device)) {
16231854 struct sas_phy *phy;
16241855
1625
- /* Clear internal IO and then hardreset */
1626
- rc = hisi_sas_internal_task_abort(hisi_hba, device,
1627
- HISI_SAS_INT_ABT_DEV, 0);
1628
- if (rc < 0) {
1629
- dev_err(dev, "lu_reset: internal abort failed\n");
1630
- goto out;
1631
- }
1632
- hisi_sas_dereg_device(hisi_hba, device);
1633
-
16341856 phy = sas_get_local_phy(device);
16351857
1636
- rc = sas_phy_reset(phy, 1);
1858
+ rc = sas_phy_reset(phy, true);
16371859
16381860 if (rc == 0)
16391861 hisi_sas_release_task(hisi_hba, device);
16401862 sas_put_local_phy(phy);
16411863 } else {
16421864 struct hisi_sas_tmf_task tmf_task = { .tmf = TMF_LU_RESET };
1643
-
1644
- rc = hisi_sas_internal_task_abort(hisi_hba, device,
1645
- HISI_SAS_INT_ABT_DEV, 0);
1646
- if (rc < 0) {
1647
- dev_err(dev, "lu_reset: internal abort failed\n");
1648
- goto out;
1649
- }
1650
- hisi_sas_dereg_device(hisi_hba, device);
16511865
16521866 rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task);
16531867 if (rc == TMF_RESP_FUNC_COMPLETE)
....@@ -1677,7 +1891,7 @@
16771891 struct domain_device *device = sas_dev->sas_device;
16781892
16791893 if ((sas_dev->dev_type == SAS_PHY_UNUSED) || !device ||
1680
- DEV_IS_EXPANDER(device->dev_type))
1894
+ dev_is_expander(device->dev_type))
16811895 continue;
16821896
16831897 rc = hisi_sas_debug_I_T_nexus_reset(device);
....@@ -1705,7 +1919,7 @@
17051919
17061920 int_to_scsilun(cmnd->device->lun, &lun);
17071921 tmf_task.tmf = TMF_QUERY_TASK;
1708
- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
1922
+ tmf_task.tag_of_task_to_be_managed = tag;
17091923
17101924 rc = hisi_sas_debug_issue_ssp_tmf(device,
17111925 lun.scsi_lun,
....@@ -1728,7 +1942,7 @@
17281942 static int
17291943 hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
17301944 struct sas_task *task, int abort_flag,
1731
- int task_tag)
1945
+ int task_tag, struct hisi_sas_dq *dq)
17321946 {
17331947 struct domain_device *device = task->dev;
17341948 struct hisi_sas_device *sas_dev = device->lldd_dev;
....@@ -1737,9 +1951,8 @@
17371951 struct hisi_sas_slot *slot;
17381952 struct asd_sas_port *sas_port = device->port;
17391953 struct hisi_sas_cmd_hdr *cmd_hdr_base;
1740
- struct hisi_sas_dq *dq = sas_dev->dq;
17411954 int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
1742
- unsigned long flags, flags_dq = 0;
1955
+ unsigned long flags;
17431956 int wr_q_index;
17441957
17451958 if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags)))
....@@ -1751,29 +1964,26 @@
17511964 port = to_hisi_sas_port(sas_port);
17521965
17531966 /* simply get a slot and send abort command */
1754
- spin_lock_irqsave(&hisi_hba->lock, flags);
1755
- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
1756
- if (rc) {
1757
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
1967
+ rc = hisi_sas_slot_index_alloc(hisi_hba, NULL);
1968
+ if (rc < 0)
17581969 goto err_out;
1759
- }
1760
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
17611970
1971
+ slot_idx = rc;
17621972 slot = &hisi_hba->slot_info[slot_idx];
17631973
1764
- spin_lock_irqsave(&dq->lock, flags_dq);
1765
- wr_q_index = hisi_hba->hw->get_free_slot(hisi_hba, dq);
1766
- if (wr_q_index < 0) {
1767
- spin_unlock_irqrestore(&dq->lock, flags_dq);
1768
- rc = -EAGAIN;
1769
- goto err_out_tag;
1770
- }
1974
+ spin_lock(&dq->lock);
1975
+ wr_q_index = dq->wr_point;
1976
+ dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS;
17711977 list_add_tail(&slot->delivery, &dq->list);
1772
- spin_unlock_irqrestore(&dq->lock, flags_dq);
1978
+ spin_unlock(&dq->lock);
1979
+ spin_lock(&sas_dev->lock);
1980
+ list_add_tail(&slot->entry, &sas_dev->list);
1981
+ spin_unlock(&sas_dev->lock);
17731982
17741983 dlvry_queue = dq->id;
17751984 dlvry_queue_slot = wr_q_index;
17761985
1986
+ slot->device_id = sas_dev->device_id;
17771987 slot->n_elem = n_elem;
17781988 slot->dlvry_queue = dlvry_queue;
17791989 slot->dlvry_queue_slot = dlvry_queue_slot;
....@@ -1786,7 +1996,8 @@
17861996
17871997 memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
17881998 memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
1789
- memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
1999
+ memset(hisi_sas_status_buf_addr_mem(slot), 0,
2000
+ sizeof(struct hisi_sas_err_record));
17902001
17912002 hisi_sas_task_prep_abort(hisi_hba, slot, device_id,
17922003 abort_flag, task_tag);
....@@ -1794,20 +2005,14 @@
17942005 spin_lock_irqsave(&task->task_state_lock, flags);
17952006 task->task_state_flags |= SAS_TASK_AT_INITIATOR;
17962007 spin_unlock_irqrestore(&task->task_state_lock, flags);
1797
-
17982008 WRITE_ONCE(slot->ready, 1);
17992009 /* send abort command to the chip */
1800
- spin_lock_irqsave(&dq->lock, flags);
1801
- list_add_tail(&slot->entry, &sas_dev->list);
2010
+ spin_lock(&dq->lock);
18022011 hisi_hba->hw->start_delivery(dq);
1803
- spin_unlock_irqrestore(&dq->lock, flags);
2012
+ spin_unlock(&dq->lock);
18042013
18052014 return 0;
18062015
1807
-err_out_tag:
1808
- spin_lock_irqsave(&hisi_hba->lock, flags);
1809
- hisi_sas_slot_index_free(hisi_hba, slot_idx);
1810
- spin_unlock_irqrestore(&hisi_hba->lock, flags);
18112016 err_out:
18122017 dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);
18132018
....@@ -1815,18 +2020,19 @@
18152020 }
18162021
18172022 /**
1818
- * hisi_sas_internal_task_abort -- execute an internal
2023
+ * _hisi_sas_internal_task_abort -- execute an internal
18192024 * abort command for single IO command or a device
18202025 * @hisi_hba: host controller struct
18212026 * @device: domain device
18222027 * @abort_flag: mode of operation, device or single IO
18232028 * @tag: tag of IO to be aborted (only relevant to single
18242029 * IO mode)
2030
+ * @dq: delivery queue for this internal abort command
18252031 */
18262032 static int
1827
-hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
1828
- struct domain_device *device,
1829
- int abort_flag, int tag)
2033
+_hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
2034
+ struct domain_device *device, int abort_flag,
2035
+ int tag, struct hisi_sas_dq *dq)
18302036 {
18312037 struct sas_task *task;
18322038 struct hisi_sas_device *sas_dev = device->lldd_dev;
....@@ -1850,11 +2056,11 @@
18502056 task->task_proto = device->tproto;
18512057 task->task_done = hisi_sas_task_done;
18522058 task->slow_task->timer.function = hisi_sas_tmf_timedout;
1853
- task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT*HZ;
2059
+ task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT * HZ;
18542060 add_timer(&task->slow_task->timer);
18552061
18562062 res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id,
1857
- task, abort_flag, tag);
2063
+ task, abort_flag, tag, dq);
18582064 if (res) {
18592065 del_timer(&task->slow_task->timer);
18602066 dev_err(dev, "internal task abort: executing internal task failed: %d\n",
....@@ -1866,6 +2072,9 @@
18662072
18672073 /* Internal abort timed out */
18682074 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
2075
+ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct)
2076
+ queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
2077
+
18692078 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
18702079 struct hisi_sas_slot *slot = task->lldd_task;
18712080
....@@ -1873,13 +2082,14 @@
18732082 struct hisi_sas_cq *cq =
18742083 &hisi_hba->cq[slot->dlvry_queue];
18752084 /*
1876
- * flush tasklet to avoid free'ing task
2085
+ * sync irq to avoid free'ing task
18772086 * before using task in IO completion
18782087 */
1879
- tasklet_kill(&cq->tasklet);
2088
+ synchronize_irq(cq->irq_no);
18802089 slot->task = NULL;
18812090 }
18822091 dev_err(dev, "internal task abort: timeout and not done.\n");
2092
+
18832093 res = -EIO;
18842094 goto exit;
18852095 } else
....@@ -1899,10 +2109,8 @@
18992109 }
19002110
19012111 exit:
1902
- dev_dbg(dev, "internal task abort: task to dev %016llx task=%p "
1903
- "resp: 0x%x sts 0x%x\n",
1904
- SAS_ADDR(device->sas_addr),
1905
- task,
2112
+ dev_dbg(dev, "internal task abort: task to dev %016llx task=%pK resp: 0x%x sts 0x%x\n",
2113
+ SAS_ADDR(device->sas_addr), task,
19062114 task->task_status.resp, /* 0 is complete, -1 is undelivered */
19072115 task->task_status.stat);
19082116 sas_free_task(task);
....@@ -1910,13 +2118,49 @@
19102118 return res;
19112119 }
19122120
2121
+static int
2122
+hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
2123
+ struct domain_device *device,
2124
+ int abort_flag, int tag)
2125
+{
2126
+ struct hisi_sas_slot *slot;
2127
+ struct device *dev = hisi_hba->dev;
2128
+ struct hisi_sas_dq *dq;
2129
+ int i, rc;
2130
+
2131
+ switch (abort_flag) {
2132
+ case HISI_SAS_INT_ABT_CMD:
2133
+ slot = &hisi_hba->slot_info[tag];
2134
+ dq = &hisi_hba->dq[slot->dlvry_queue];
2135
+ return _hisi_sas_internal_task_abort(hisi_hba, device,
2136
+ abort_flag, tag, dq);
2137
+ case HISI_SAS_INT_ABT_DEV:
2138
+ for (i = 0; i < hisi_hba->cq_nvecs; i++) {
2139
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
2140
+ const struct cpumask *mask = cq->irq_mask;
2141
+
2142
+ if (mask && !cpumask_intersects(cpu_online_mask, mask))
2143
+ continue;
2144
+ dq = &hisi_hba->dq[i];
2145
+ rc = _hisi_sas_internal_task_abort(hisi_hba, device,
2146
+ abort_flag, tag,
2147
+ dq);
2148
+ if (rc)
2149
+ return rc;
2150
+ }
2151
+ break;
2152
+ default:
2153
+ dev_err(dev, "Unrecognised internal abort flag (%d)\n",
2154
+ abort_flag);
2155
+ return -EINVAL;
2156
+ }
2157
+
2158
+ return 0;
2159
+}
2160
+
19132161 static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy)
19142162 {
19152163 hisi_sas_port_notify_formed(sas_phy);
1916
-}
1917
-
1918
-static void hisi_sas_port_deformed(struct asd_sas_phy *sas_phy)
1919
-{
19202164 }
19212165
19222166 static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type,
....@@ -1935,23 +2179,24 @@
19352179 {
19362180 struct asd_sas_phy *sas_phy = &phy->sas_phy;
19372181 struct sas_phy *sphy = sas_phy->phy;
1938
- struct sas_phy_data *d = sphy->hostdata;
2182
+ unsigned long flags;
19392183
19402184 phy->phy_attached = 0;
19412185 phy->phy_type = 0;
19422186 phy->port = NULL;
19432187
1944
- if (d->enable)
2188
+ spin_lock_irqsave(&phy->lock, flags);
2189
+ if (phy->enable)
19452190 sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
19462191 else
19472192 sphy->negotiated_linkrate = SAS_PHY_DISABLED;
2193
+ spin_unlock_irqrestore(&phy->lock, flags);
19482194 }
19492195
19502196 void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
19512197 {
19522198 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
19532199 struct asd_sas_phy *sas_phy = &phy->sas_phy;
1954
- struct sas_ha_struct *sas_ha = &hisi_hba->sha;
19552200 struct device *dev = hisi_hba->dev;
19562201
19572202 if (rdy) {
....@@ -1967,7 +2212,7 @@
19672212 return;
19682213 }
19692214 /* Phy down and not ready */
1970
- sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
2215
+ sas_notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
19712216 sas_phy_disconnected(sas_phy);
19722217
19732218 if (port) {
....@@ -1985,26 +2230,33 @@
19852230 }
19862231 EXPORT_SYMBOL_GPL(hisi_sas_phy_down);
19872232
1988
-void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba)
2233
+void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba)
19892234 {
19902235 int i;
19912236
1992
- for (i = 0; i < hisi_hba->queue_count; i++) {
2237
+ for (i = 0; i < hisi_hba->cq_nvecs; i++) {
19932238 struct hisi_sas_cq *cq = &hisi_hba->cq[i];
19942239
1995
- tasklet_kill(&cq->tasklet);
2240
+ synchronize_irq(cq->irq_no);
19962241 }
19972242 }
1998
-EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets);
2243
+EXPORT_SYMBOL_GPL(hisi_sas_sync_irqs);
2244
+
2245
+int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type)
2246
+{
2247
+ struct hisi_hba *hisi_hba = shost_priv(shost);
2248
+
2249
+ if (reset_type != SCSI_ADAPTER_RESET)
2250
+ return -EOPNOTSUPP;
2251
+
2252
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
2253
+
2254
+ return 0;
2255
+}
2256
+EXPORT_SYMBOL_GPL(hisi_sas_host_reset);
19992257
20002258 struct scsi_transport_template *hisi_sas_stt;
20012259 EXPORT_SYMBOL_GPL(hisi_sas_stt);
2002
-
2003
-struct device_attribute *host_attrs[] = {
2004
- &dev_attr_phy_event_threshold,
2005
- NULL,
2006
-};
2007
-EXPORT_SYMBOL_GPL(host_attrs);
20082260
20092261 static struct sas_domain_function_template hisi_sas_transport_ops = {
20102262 .lldd_dev_found = hisi_sas_dev_found,
....@@ -2017,22 +2269,25 @@
20172269 .lldd_I_T_nexus_reset = hisi_sas_I_T_nexus_reset,
20182270 .lldd_lu_reset = hisi_sas_lu_reset,
20192271 .lldd_query_task = hisi_sas_query_task,
2020
- .lldd_clear_nexus_ha = hisi_sas_clear_nexus_ha,
2272
+ .lldd_clear_nexus_ha = hisi_sas_clear_nexus_ha,
20212273 .lldd_port_formed = hisi_sas_port_formed,
2022
- .lldd_port_deformed = hisi_sas_port_deformed,
2023
- .lldd_write_gpio = hisi_sas_write_gpio,
2274
+ .lldd_write_gpio = hisi_sas_write_gpio,
20242275 };
20252276
20262277 void hisi_sas_init_mem(struct hisi_hba *hisi_hba)
20272278 {
2028
- int i, s, max_command_entries = hisi_hba->hw->max_command_entries;
2279
+ int i, s, j, max_command_entries = HISI_SAS_MAX_COMMANDS;
2280
+ struct hisi_sas_breakpoint *sata_breakpoint = hisi_hba->sata_breakpoint;
20292281
20302282 for (i = 0; i < hisi_hba->queue_count; i++) {
20312283 struct hisi_sas_cq *cq = &hisi_hba->cq[i];
20322284 struct hisi_sas_dq *dq = &hisi_hba->dq[i];
2285
+ struct hisi_sas_cmd_hdr *cmd_hdr = hisi_hba->cmd_hdr[i];
20332286
2034
- s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS;
2035
- memset(hisi_hba->cmd_hdr[i], 0, s);
2287
+ s = sizeof(struct hisi_sas_cmd_hdr);
2288
+ for (j = 0; j < HISI_SAS_QUEUE_SLOTS; j++)
2289
+ memset(&cmd_hdr[j], 0, s);
2290
+
20362291 dq->wr_point = 0;
20372292
20382293 s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
....@@ -2049,15 +2304,16 @@
20492304 s = max_command_entries * sizeof(struct hisi_sas_breakpoint);
20502305 memset(hisi_hba->breakpoint, 0, s);
20512306
2052
- s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_sata_breakpoint);
2053
- memset(hisi_hba->sata_breakpoint, 0, s);
2307
+ s = sizeof(struct hisi_sas_sata_breakpoint);
2308
+ for (j = 0; j < HISI_SAS_MAX_ITCT_ENTRIES; j++)
2309
+ memset(&sata_breakpoint[j], 0, s);
20542310 }
20552311 EXPORT_SYMBOL_GPL(hisi_sas_init_mem);
20562312
2057
-int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
2313
+int hisi_sas_alloc(struct hisi_hba *hisi_hba)
20582314 {
20592315 struct device *dev = hisi_hba->dev;
2060
- int i, j, s, max_command_entries = hisi_hba->hw->max_command_entries;
2316
+ int i, j, s, max_command_entries = HISI_SAS_MAX_COMMANDS;
20612317 int max_command_entries_ru, sz_slot_buf_ru;
20622318 int blk_cnt, slots_per_blk;
20632319
....@@ -2072,7 +2328,7 @@
20722328 for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
20732329 hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED;
20742330 hisi_hba->devices[i].device_id = i;
2075
- hisi_hba->devices[i].dev_status = HISI_SAS_DEV_NORMAL;
2331
+ hisi_hba->devices[i].dev_status = HISI_SAS_DEV_INIT;
20762332 }
20772333
20782334 for (i = 0; i < hisi_hba->queue_count; i++) {
....@@ -2111,7 +2367,6 @@
21112367 GFP_KERNEL);
21122368 if (!hisi_hba->itct)
21132369 goto err_out;
2114
- memset(hisi_hba->itct, 0, s);
21152370
21162371 hisi_hba->slot_info = devm_kcalloc(dev, max_command_entries,
21172372 sizeof(struct hisi_sas_slot),
....@@ -2121,19 +2376,24 @@
21212376
21222377 /* roundup to avoid overly large block size */
21232378 max_command_entries_ru = roundup(max_command_entries, 64);
2124
- sz_slot_buf_ru = roundup(sizeof(struct hisi_sas_slot_buf_table), 64);
2125
- s = lcm(max_command_entries_ru, sz_slot_buf_ru);
2379
+ if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK)
2380
+ sz_slot_buf_ru = sizeof(struct hisi_sas_slot_dif_buf_table);
2381
+ else
2382
+ sz_slot_buf_ru = sizeof(struct hisi_sas_slot_buf_table);
2383
+ sz_slot_buf_ru = roundup(sz_slot_buf_ru, 64);
2384
+ s = max(lcm(max_command_entries_ru, sz_slot_buf_ru), PAGE_SIZE);
21262385 blk_cnt = (max_command_entries_ru * sz_slot_buf_ru) / s;
21272386 slots_per_blk = s / sz_slot_buf_ru;
2128
- for (i = 0; i < blk_cnt; i++) {
2129
- struct hisi_sas_slot_buf_table *buf;
2130
- dma_addr_t buf_dma;
2131
- int slot_index = i * slots_per_blk;
21322387
2133
- buf = dmam_alloc_coherent(dev, s, &buf_dma, GFP_KERNEL);
2388
+ for (i = 0; i < blk_cnt; i++) {
2389
+ int slot_index = i * slots_per_blk;
2390
+ dma_addr_t buf_dma;
2391
+ void *buf;
2392
+
2393
+ buf = dmam_alloc_coherent(dev, s, &buf_dma,
2394
+ GFP_KERNEL);
21342395 if (!buf)
21352396 goto err_out;
2136
- memset(buf, 0, s);
21372397
21382398 for (j = 0; j < slots_per_blk; j++, slot_index++) {
21392399 struct hisi_sas_slot *slot;
....@@ -2143,8 +2403,8 @@
21432403 slot->buf_dma = buf_dma;
21442404 slot->idx = slot_index;
21452405
2146
- buf++;
2147
- buf_dma += sizeof(*buf);
2406
+ buf += sz_slot_buf_ru;
2407
+ buf_dma += sz_slot_buf_ru;
21482408 }
21492409 }
21502410
....@@ -2180,9 +2440,9 @@
21802440 GFP_KERNEL);
21812441 if (!hisi_hba->sata_breakpoint)
21822442 goto err_out;
2183
- hisi_sas_init_mem(hisi_hba);
21842443
21852444 hisi_sas_slot_index_init(hisi_hba);
2445
+ hisi_hba->last_slot_index = HISI_SAS_UNRESERVED_IPTT;
21862446
21872447 hisi_hba->wq = create_singlethread_workqueue(dev_name(dev));
21882448 if (!hisi_hba->wq) {
....@@ -2198,6 +2458,14 @@
21982458
21992459 void hisi_sas_free(struct hisi_hba *hisi_hba)
22002460 {
2461
+ int i;
2462
+
2463
+ for (i = 0; i < hisi_hba->n_phy; i++) {
2464
+ struct hisi_sas_phy *phy = &hisi_hba->phy[i];
2465
+
2466
+ del_timer_sync(&phy->timer);
2467
+ }
2468
+
22012469 if (hisi_hba->wq)
22022470 destroy_workqueue(hisi_hba->wq);
22032471 }
....@@ -2250,22 +2518,19 @@
22502518
22512519 if (device_property_read_u32(dev, "ctrl-reset-reg",
22522520 &hisi_hba->ctrl_reset_reg)) {
2253
- dev_err(dev,
2254
- "could not get property ctrl-reset-reg\n");
2521
+ dev_err(dev, "could not get property ctrl-reset-reg\n");
22552522 return -ENOENT;
22562523 }
22572524
22582525 if (device_property_read_u32(dev, "ctrl-reset-sts-reg",
22592526 &hisi_hba->ctrl_reset_sts_reg)) {
2260
- dev_err(dev,
2261
- "could not get property ctrl-reset-sts-reg\n");
2527
+ dev_err(dev, "could not get property ctrl-reset-sts-reg\n");
22622528 return -ENOENT;
22632529 }
22642530
22652531 if (device_property_read_u32(dev, "ctrl-clock-ena-reg",
22662532 &hisi_hba->ctrl_clock_ena_reg)) {
2267
- dev_err(dev,
2268
- "could not get property ctrl-clock-ena-reg\n");
2533
+ dev_err(dev, "could not get property ctrl-clock-ena-reg\n");
22692534 return -ENOENT;
22702535 }
22712536 }
....@@ -2298,6 +2563,7 @@
22982563 struct Scsi_Host *shost;
22992564 struct hisi_hba *hisi_hba;
23002565 struct device *dev = &pdev->dev;
2566
+ int error;
23012567
23022568 shost = scsi_host_alloc(hw->sht, sizeof(*hisi_hba));
23032569 if (!shost) {
....@@ -2318,14 +2584,16 @@
23182584 if (hisi_sas_get_fw_info(hisi_hba) < 0)
23192585 goto err_out;
23202586
2321
- if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) &&
2322
- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
2587
+ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
2588
+ if (error)
2589
+ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
2590
+
2591
+ if (error) {
23232592 dev_err(dev, "No usable DMA addressing method\n");
23242593 goto err_out;
23252594 }
23262595
2327
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2328
- hisi_hba->regs = devm_ioremap_resource(dev, res);
2596
+ hisi_hba->regs = devm_platform_ioremap_resource(pdev, 0);
23292597 if (IS_ERR(hisi_hba->regs))
23302598 goto err_out;
23312599
....@@ -2336,7 +2604,7 @@
23362604 goto err_out;
23372605 }
23382606
2339
- if (hisi_sas_alloc(hisi_hba, shost)) {
2607
+ if (hisi_sas_alloc(hisi_hba)) {
23402608 hisi_sas_free(hisi_hba);
23412609 goto err_out;
23422610 }
....@@ -2385,9 +2653,13 @@
23852653 shost->max_lun = ~0;
23862654 shost->max_channel = 1;
23872655 shost->max_cmd_len = 16;
2388
- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
2389
- shost->can_queue = hisi_hba->hw->max_command_entries;
2390
- shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
2656
+ if (hisi_hba->hw->slot_index_alloc) {
2657
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
2658
+ shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
2659
+ } else {
2660
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
2661
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
2662
+ }
23912663
23922664 sha->sas_ha_name = DRV_NAME;
23932665 sha->dev = hisi_hba->dev;
....@@ -2420,11 +2692,1354 @@
24202692 err_out_register_ha:
24212693 scsi_remove_host(shost);
24222694 err_out_ha:
2695
+ hisi_sas_debugfs_exit(hisi_hba);
24232696 hisi_sas_free(hisi_hba);
24242697 scsi_host_put(shost);
24252698 return rc;
24262699 }
24272700 EXPORT_SYMBOL_GPL(hisi_sas_probe);
2701
+
2702
+struct dentry *hisi_sas_debugfs_dir;
2703
+
2704
+static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba)
2705
+{
2706
+ int queue_entry_size = hisi_hba->hw->complete_hdr_size;
2707
+ int dump_index = hisi_hba->debugfs_dump_index;
2708
+ int i;
2709
+
2710
+ for (i = 0; i < hisi_hba->queue_count; i++)
2711
+ memcpy(hisi_hba->debugfs_cq[dump_index][i].complete_hdr,
2712
+ hisi_hba->complete_hdr[i],
2713
+ HISI_SAS_QUEUE_SLOTS * queue_entry_size);
2714
+}
2715
+
2716
+static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba)
2717
+{
2718
+ int queue_entry_size = sizeof(struct hisi_sas_cmd_hdr);
2719
+ int dump_index = hisi_hba->debugfs_dump_index;
2720
+ int i;
2721
+
2722
+ for (i = 0; i < hisi_hba->queue_count; i++) {
2723
+ struct hisi_sas_cmd_hdr *debugfs_cmd_hdr, *cmd_hdr;
2724
+ int j;
2725
+
2726
+ debugfs_cmd_hdr = hisi_hba->debugfs_dq[dump_index][i].hdr;
2727
+ cmd_hdr = hisi_hba->cmd_hdr[i];
2728
+
2729
+ for (j = 0; j < HISI_SAS_QUEUE_SLOTS; j++)
2730
+ memcpy(&debugfs_cmd_hdr[j], &cmd_hdr[j],
2731
+ queue_entry_size);
2732
+ }
2733
+}
2734
+
2735
+static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba)
2736
+{
2737
+ int dump_index = hisi_hba->debugfs_dump_index;
2738
+ const struct hisi_sas_debugfs_reg *port =
2739
+ hisi_hba->hw->debugfs_reg_port;
2740
+ int i, phy_cnt;
2741
+ u32 offset;
2742
+ u32 *databuf;
2743
+
2744
+ for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) {
2745
+ databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data;
2746
+ for (i = 0; i < port->count; i++, databuf++) {
2747
+ offset = port->base_off + 4 * i;
2748
+ *databuf = port->read_port_reg(hisi_hba, phy_cnt,
2749
+ offset);
2750
+ }
2751
+ }
2752
+}
2753
+
2754
+static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba)
2755
+{
2756
+ int dump_index = hisi_hba->debugfs_dump_index;
2757
+ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data;
2758
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2759
+ const struct hisi_sas_debugfs_reg *global =
2760
+ hw->debugfs_reg_array[DEBUGFS_GLOBAL];
2761
+ int i;
2762
+
2763
+ for (i = 0; i < global->count; i++, databuf++)
2764
+ *databuf = global->read_global_reg(hisi_hba, 4 * i);
2765
+}
2766
+
2767
+static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba)
2768
+{
2769
+ int dump_index = hisi_hba->debugfs_dump_index;
2770
+ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI].data;
2771
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2772
+ const struct hisi_sas_debugfs_reg *axi =
2773
+ hw->debugfs_reg_array[DEBUGFS_AXI];
2774
+ int i;
2775
+
2776
+ for (i = 0; i < axi->count; i++, databuf++)
2777
+ *databuf = axi->read_global_reg(hisi_hba,
2778
+ 4 * i + axi->base_off);
2779
+}
2780
+
2781
+static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba)
2782
+{
2783
+ int dump_index = hisi_hba->debugfs_dump_index;
2784
+ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS].data;
2785
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2786
+ const struct hisi_sas_debugfs_reg *ras =
2787
+ hw->debugfs_reg_array[DEBUGFS_RAS];
2788
+ int i;
2789
+
2790
+ for (i = 0; i < ras->count; i++, databuf++)
2791
+ *databuf = ras->read_global_reg(hisi_hba,
2792
+ 4 * i + ras->base_off);
2793
+}
2794
+
2795
+static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba)
2796
+{
2797
+ int dump_index = hisi_hba->debugfs_dump_index;
2798
+ void *cachebuf = hisi_hba->debugfs_itct_cache[dump_index].cache;
2799
+ void *databuf = hisi_hba->debugfs_itct[dump_index].itct;
2800
+ struct hisi_sas_itct *itct;
2801
+ int i;
2802
+
2803
+ hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_ITCT_CACHE,
2804
+ cachebuf);
2805
+
2806
+ itct = hisi_hba->itct;
2807
+
2808
+ for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
2809
+ memcpy(databuf, itct, sizeof(struct hisi_sas_itct));
2810
+ databuf += sizeof(struct hisi_sas_itct);
2811
+ }
2812
+}
2813
+
2814
+static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba)
2815
+{
2816
+ int dump_index = hisi_hba->debugfs_dump_index;
2817
+ int max_command_entries = HISI_SAS_MAX_COMMANDS;
2818
+ void *cachebuf = hisi_hba->debugfs_iost_cache[dump_index].cache;
2819
+ void *databuf = hisi_hba->debugfs_iost[dump_index].iost;
2820
+ struct hisi_sas_iost *iost;
2821
+ int i;
2822
+
2823
+ hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_IOST_CACHE,
2824
+ cachebuf);
2825
+
2826
+ iost = hisi_hba->iost;
2827
+
2828
+ for (i = 0; i < max_command_entries; i++, iost++) {
2829
+ memcpy(databuf, iost, sizeof(struct hisi_sas_iost));
2830
+ databuf += sizeof(struct hisi_sas_iost);
2831
+ }
2832
+}
2833
+
2834
+static const char *
2835
+hisi_sas_debugfs_to_reg_name(int off, int base_off,
2836
+ const struct hisi_sas_debugfs_reg_lu *lu)
2837
+{
2838
+ for (; lu->name; lu++) {
2839
+ if (off == lu->off - base_off)
2840
+ return lu->name;
2841
+ }
2842
+
2843
+ return NULL;
2844
+}
2845
+
2846
+static void hisi_sas_debugfs_print_reg(u32 *regs_val, const void *ptr,
2847
+ struct seq_file *s)
2848
+{
2849
+ const struct hisi_sas_debugfs_reg *reg = ptr;
2850
+ int i;
2851
+
2852
+ for (i = 0; i < reg->count; i++) {
2853
+ int off = i * 4;
2854
+ const char *name;
2855
+
2856
+ name = hisi_sas_debugfs_to_reg_name(off, reg->base_off,
2857
+ reg->lu);
2858
+
2859
+ if (name)
2860
+ seq_printf(s, "0x%08x 0x%08x %s\n", off,
2861
+ regs_val[i], name);
2862
+ else
2863
+ seq_printf(s, "0x%08x 0x%08x\n", off,
2864
+ regs_val[i]);
2865
+ }
2866
+}
2867
+
2868
+static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p)
2869
+{
2870
+ struct hisi_sas_debugfs_regs *global = s->private;
2871
+ struct hisi_hba *hisi_hba = global->hisi_hba;
2872
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2873
+ const void *reg_global = hw->debugfs_reg_array[DEBUGFS_GLOBAL];
2874
+
2875
+ hisi_sas_debugfs_print_reg(global->data,
2876
+ reg_global, s);
2877
+
2878
+ return 0;
2879
+}
2880
+
2881
+static int hisi_sas_debugfs_global_open(struct inode *inode, struct file *filp)
2882
+{
2883
+ return single_open(filp, hisi_sas_debugfs_global_show,
2884
+ inode->i_private);
2885
+}
2886
+
2887
+static const struct file_operations hisi_sas_debugfs_global_fops = {
2888
+ .open = hisi_sas_debugfs_global_open,
2889
+ .read = seq_read,
2890
+ .llseek = seq_lseek,
2891
+ .release = single_release,
2892
+ .owner = THIS_MODULE,
2893
+};
2894
+
2895
+static int hisi_sas_debugfs_axi_show(struct seq_file *s, void *p)
2896
+{
2897
+ struct hisi_sas_debugfs_regs *axi = s->private;
2898
+ struct hisi_hba *hisi_hba = axi->hisi_hba;
2899
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2900
+ const void *reg_axi = hw->debugfs_reg_array[DEBUGFS_AXI];
2901
+
2902
+ hisi_sas_debugfs_print_reg(axi->data,
2903
+ reg_axi, s);
2904
+
2905
+ return 0;
2906
+}
2907
+
2908
+static int hisi_sas_debugfs_axi_open(struct inode *inode, struct file *filp)
2909
+{
2910
+ return single_open(filp, hisi_sas_debugfs_axi_show,
2911
+ inode->i_private);
2912
+}
2913
+
2914
+static const struct file_operations hisi_sas_debugfs_axi_fops = {
2915
+ .open = hisi_sas_debugfs_axi_open,
2916
+ .read = seq_read,
2917
+ .llseek = seq_lseek,
2918
+ .release = single_release,
2919
+ .owner = THIS_MODULE,
2920
+};
2921
+
2922
+static int hisi_sas_debugfs_ras_show(struct seq_file *s, void *p)
2923
+{
2924
+ struct hisi_sas_debugfs_regs *ras = s->private;
2925
+ struct hisi_hba *hisi_hba = ras->hisi_hba;
2926
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2927
+ const void *reg_ras = hw->debugfs_reg_array[DEBUGFS_RAS];
2928
+
2929
+ hisi_sas_debugfs_print_reg(ras->data,
2930
+ reg_ras, s);
2931
+
2932
+ return 0;
2933
+}
2934
+
2935
+static int hisi_sas_debugfs_ras_open(struct inode *inode, struct file *filp)
2936
+{
2937
+ return single_open(filp, hisi_sas_debugfs_ras_show,
2938
+ inode->i_private);
2939
+}
2940
+
2941
+static const struct file_operations hisi_sas_debugfs_ras_fops = {
2942
+ .open = hisi_sas_debugfs_ras_open,
2943
+ .read = seq_read,
2944
+ .llseek = seq_lseek,
2945
+ .release = single_release,
2946
+ .owner = THIS_MODULE,
2947
+};
2948
+
2949
+static int hisi_sas_debugfs_port_show(struct seq_file *s, void *p)
2950
+{
2951
+ struct hisi_sas_debugfs_port *port = s->private;
2952
+ struct hisi_sas_phy *phy = port->phy;
2953
+ struct hisi_hba *hisi_hba = phy->hisi_hba;
2954
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
2955
+ const struct hisi_sas_debugfs_reg *reg_port = hw->debugfs_reg_port;
2956
+
2957
+ hisi_sas_debugfs_print_reg(port->data, reg_port, s);
2958
+
2959
+ return 0;
2960
+}
2961
+
2962
+static int hisi_sas_debugfs_port_open(struct inode *inode, struct file *filp)
2963
+{
2964
+ return single_open(filp, hisi_sas_debugfs_port_show, inode->i_private);
2965
+}
2966
+
2967
+static const struct file_operations hisi_sas_debugfs_port_fops = {
2968
+ .open = hisi_sas_debugfs_port_open,
2969
+ .read = seq_read,
2970
+ .llseek = seq_lseek,
2971
+ .release = single_release,
2972
+ .owner = THIS_MODULE,
2973
+};
2974
+
2975
+static void hisi_sas_show_row_64(struct seq_file *s, int index,
2976
+ int sz, __le64 *ptr)
2977
+{
2978
+ int i;
2979
+
2980
+ /* completion header size not fixed per HW version */
2981
+ seq_printf(s, "index %04d:\n\t", index);
2982
+ for (i = 1; i <= sz / 8; i++, ptr++) {
2983
+ seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr));
2984
+ if (!(i % 2))
2985
+ seq_puts(s, "\n\t");
2986
+ }
2987
+
2988
+ seq_puts(s, "\n");
2989
+}
2990
+
2991
+static void hisi_sas_show_row_32(struct seq_file *s, int index,
2992
+ int sz, __le32 *ptr)
2993
+{
2994
+ int i;
2995
+
2996
+ /* completion header size not fixed per HW version */
2997
+ seq_printf(s, "index %04d:\n\t", index);
2998
+ for (i = 1; i <= sz / 4; i++, ptr++) {
2999
+ seq_printf(s, " 0x%08x", le32_to_cpu(*ptr));
3000
+ if (!(i % 4))
3001
+ seq_puts(s, "\n\t");
3002
+ }
3003
+ seq_puts(s, "\n");
3004
+}
3005
+
3006
+static void hisi_sas_cq_show_slot(struct seq_file *s, int slot,
3007
+ struct hisi_sas_debugfs_cq *debugfs_cq)
3008
+{
3009
+ struct hisi_sas_cq *cq = debugfs_cq->cq;
3010
+ struct hisi_hba *hisi_hba = cq->hisi_hba;
3011
+ __le32 *complete_hdr = debugfs_cq->complete_hdr +
3012
+ (hisi_hba->hw->complete_hdr_size * slot);
3013
+
3014
+ hisi_sas_show_row_32(s, slot,
3015
+ hisi_hba->hw->complete_hdr_size,
3016
+ complete_hdr);
3017
+}
3018
+
3019
+static int hisi_sas_debugfs_cq_show(struct seq_file *s, void *p)
3020
+{
3021
+ struct hisi_sas_debugfs_cq *debugfs_cq = s->private;
3022
+ int slot;
3023
+
3024
+ for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) {
3025
+ hisi_sas_cq_show_slot(s, slot, debugfs_cq);
3026
+ }
3027
+ return 0;
3028
+}
3029
+
3030
+static int hisi_sas_debugfs_cq_open(struct inode *inode, struct file *filp)
3031
+{
3032
+ return single_open(filp, hisi_sas_debugfs_cq_show, inode->i_private);
3033
+}
3034
+
3035
+static const struct file_operations hisi_sas_debugfs_cq_fops = {
3036
+ .open = hisi_sas_debugfs_cq_open,
3037
+ .read = seq_read,
3038
+ .llseek = seq_lseek,
3039
+ .release = single_release,
3040
+ .owner = THIS_MODULE,
3041
+};
3042
+
3043
+static void hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr)
3044
+{
3045
+ struct hisi_sas_debugfs_dq *debugfs_dq = dq_ptr;
3046
+ void *cmd_queue = debugfs_dq->hdr;
3047
+ __le32 *cmd_hdr = cmd_queue +
3048
+ sizeof(struct hisi_sas_cmd_hdr) * slot;
3049
+
3050
+ hisi_sas_show_row_32(s, slot, sizeof(struct hisi_sas_cmd_hdr), cmd_hdr);
3051
+}
3052
+
3053
+static int hisi_sas_debugfs_dq_show(struct seq_file *s, void *p)
3054
+{
3055
+ int slot;
3056
+
3057
+ for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) {
3058
+ hisi_sas_dq_show_slot(s, slot, s->private);
3059
+ }
3060
+ return 0;
3061
+}
3062
+
3063
+static int hisi_sas_debugfs_dq_open(struct inode *inode, struct file *filp)
3064
+{
3065
+ return single_open(filp, hisi_sas_debugfs_dq_show, inode->i_private);
3066
+}
3067
+
3068
+static const struct file_operations hisi_sas_debugfs_dq_fops = {
3069
+ .open = hisi_sas_debugfs_dq_open,
3070
+ .read = seq_read,
3071
+ .llseek = seq_lseek,
3072
+ .release = single_release,
3073
+ .owner = THIS_MODULE,
3074
+};
3075
+
3076
+static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p)
3077
+{
3078
+ struct hisi_sas_debugfs_iost *debugfs_iost = s->private;
3079
+ struct hisi_sas_iost *iost = debugfs_iost->iost;
3080
+ int i, max_command_entries = HISI_SAS_MAX_COMMANDS;
3081
+
3082
+ for (i = 0; i < max_command_entries; i++, iost++) {
3083
+ __le64 *data = &iost->qw0;
3084
+
3085
+ hisi_sas_show_row_64(s, i, sizeof(*iost), data);
3086
+ }
3087
+
3088
+ return 0;
3089
+}
3090
+
3091
+static int hisi_sas_debugfs_iost_open(struct inode *inode, struct file *filp)
3092
+{
3093
+ return single_open(filp, hisi_sas_debugfs_iost_show, inode->i_private);
3094
+}
3095
+
3096
+static const struct file_operations hisi_sas_debugfs_iost_fops = {
3097
+ .open = hisi_sas_debugfs_iost_open,
3098
+ .read = seq_read,
3099
+ .llseek = seq_lseek,
3100
+ .release = single_release,
3101
+ .owner = THIS_MODULE,
3102
+};
3103
+
3104
+static int hisi_sas_debugfs_iost_cache_show(struct seq_file *s, void *p)
3105
+{
3106
+ struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private;
3107
+ struct hisi_sas_iost_itct_cache *iost_cache = debugfs_iost_cache->cache;
3108
+ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
3109
+ int i, tab_idx;
3110
+ __le64 *iost;
3111
+
3112
+ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) {
3113
+ /*
3114
+ * Data struct of IOST cache:
3115
+ * Data[1]: BIT0~15: Table index
3116
+ * Bit16: Valid mask
3117
+ * Data[2]~[9]: IOST table
3118
+ */
3119
+ tab_idx = (iost_cache->data[1] & 0xffff);
3120
+ iost = (__le64 *)iost_cache;
3121
+
3122
+ hisi_sas_show_row_64(s, tab_idx, cache_size, iost);
3123
+ }
3124
+
3125
+ return 0;
3126
+}
3127
+
3128
+static int hisi_sas_debugfs_iost_cache_open(struct inode *inode,
3129
+ struct file *filp)
3130
+{
3131
+ return single_open(filp, hisi_sas_debugfs_iost_cache_show,
3132
+ inode->i_private);
3133
+}
3134
+
3135
+static const struct file_operations hisi_sas_debugfs_iost_cache_fops = {
3136
+ .open = hisi_sas_debugfs_iost_cache_open,
3137
+ .read = seq_read,
3138
+ .llseek = seq_lseek,
3139
+ .release = single_release,
3140
+ .owner = THIS_MODULE,
3141
+};
3142
+
3143
+static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p)
3144
+{
3145
+ int i;
3146
+ struct hisi_sas_debugfs_itct *debugfs_itct = s->private;
3147
+ struct hisi_sas_itct *itct = debugfs_itct->itct;
3148
+
3149
+ for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
3150
+ __le64 *data = &itct->qw0;
3151
+
3152
+ hisi_sas_show_row_64(s, i, sizeof(*itct), data);
3153
+ }
3154
+
3155
+ return 0;
3156
+}
3157
+
3158
+static int hisi_sas_debugfs_itct_open(struct inode *inode, struct file *filp)
3159
+{
3160
+ return single_open(filp, hisi_sas_debugfs_itct_show, inode->i_private);
3161
+}
3162
+
3163
+static const struct file_operations hisi_sas_debugfs_itct_fops = {
3164
+ .open = hisi_sas_debugfs_itct_open,
3165
+ .read = seq_read,
3166
+ .llseek = seq_lseek,
3167
+ .release = single_release,
3168
+ .owner = THIS_MODULE,
3169
+};
3170
+
3171
+static int hisi_sas_debugfs_itct_cache_show(struct seq_file *s, void *p)
3172
+{
3173
+ struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private;
3174
+ struct hisi_sas_iost_itct_cache *itct_cache = debugfs_itct_cache->cache;
3175
+ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
3176
+ int i, tab_idx;
3177
+ __le64 *itct;
3178
+
3179
+ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) {
3180
+ /*
3181
+ * Data struct of ITCT cache:
3182
+ * Data[1]: BIT0~15: Table index
3183
+ * Bit16: Valid mask
3184
+ * Data[2]~[9]: ITCT table
3185
+ */
3186
+ tab_idx = itct_cache->data[1] & 0xffff;
3187
+ itct = (__le64 *)itct_cache;
3188
+
3189
+ hisi_sas_show_row_64(s, tab_idx, cache_size, itct);
3190
+ }
3191
+
3192
+ return 0;
3193
+}
3194
+
3195
+static int hisi_sas_debugfs_itct_cache_open(struct inode *inode,
3196
+ struct file *filp)
3197
+{
3198
+ return single_open(filp, hisi_sas_debugfs_itct_cache_show,
3199
+ inode->i_private);
3200
+}
3201
+
3202
+static const struct file_operations hisi_sas_debugfs_itct_cache_fops = {
3203
+ .open = hisi_sas_debugfs_itct_cache_open,
3204
+ .read = seq_read,
3205
+ .llseek = seq_lseek,
3206
+ .release = single_release,
3207
+ .owner = THIS_MODULE,
3208
+};
3209
+
3210
+static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
3211
+{
3212
+ u64 *debugfs_timestamp;
3213
+ int dump_index = hisi_hba->debugfs_dump_index;
3214
+ struct dentry *dump_dentry;
3215
+ struct dentry *dentry;
3216
+ char name[256];
3217
+ int p;
3218
+ int c;
3219
+ int d;
3220
+
3221
+ snprintf(name, 256, "%d", dump_index);
3222
+
3223
+ dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);
3224
+
3225
+ debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index];
3226
+
3227
+ debugfs_create_u64("timestamp", 0400, dump_dentry,
3228
+ debugfs_timestamp);
3229
+
3230
+ debugfs_create_file("global", 0400, dump_dentry,
3231
+ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL],
3232
+ &hisi_sas_debugfs_global_fops);
3233
+
3234
+ /* Create port dir and files */
3235
+ dentry = debugfs_create_dir("port", dump_dentry);
3236
+ for (p = 0; p < hisi_hba->n_phy; p++) {
3237
+ snprintf(name, 256, "%d", p);
3238
+
3239
+ debugfs_create_file(name, 0400, dentry,
3240
+ &hisi_hba->debugfs_port_reg[dump_index][p],
3241
+ &hisi_sas_debugfs_port_fops);
3242
+ }
3243
+
3244
+ /* Create CQ dir and files */
3245
+ dentry = debugfs_create_dir("cq", dump_dentry);
3246
+ for (c = 0; c < hisi_hba->queue_count; c++) {
3247
+ snprintf(name, 256, "%d", c);
3248
+
3249
+ debugfs_create_file(name, 0400, dentry,
3250
+ &hisi_hba->debugfs_cq[dump_index][c],
3251
+ &hisi_sas_debugfs_cq_fops);
3252
+ }
3253
+
3254
+ /* Create DQ dir and files */
3255
+ dentry = debugfs_create_dir("dq", dump_dentry);
3256
+ for (d = 0; d < hisi_hba->queue_count; d++) {
3257
+ snprintf(name, 256, "%d", d);
3258
+
3259
+ debugfs_create_file(name, 0400, dentry,
3260
+ &hisi_hba->debugfs_dq[dump_index][d],
3261
+ &hisi_sas_debugfs_dq_fops);
3262
+ }
3263
+
3264
+ debugfs_create_file("iost", 0400, dump_dentry,
3265
+ &hisi_hba->debugfs_iost[dump_index],
3266
+ &hisi_sas_debugfs_iost_fops);
3267
+
3268
+ debugfs_create_file("iost_cache", 0400, dump_dentry,
3269
+ &hisi_hba->debugfs_iost_cache[dump_index],
3270
+ &hisi_sas_debugfs_iost_cache_fops);
3271
+
3272
+ debugfs_create_file("itct", 0400, dump_dentry,
3273
+ &hisi_hba->debugfs_itct[dump_index],
3274
+ &hisi_sas_debugfs_itct_fops);
3275
+
3276
+ debugfs_create_file("itct_cache", 0400, dump_dentry,
3277
+ &hisi_hba->debugfs_itct_cache[dump_index],
3278
+ &hisi_sas_debugfs_itct_cache_fops);
3279
+
3280
+ debugfs_create_file("axi", 0400, dump_dentry,
3281
+ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI],
3282
+ &hisi_sas_debugfs_axi_fops);
3283
+
3284
+ debugfs_create_file("ras", 0400, dump_dentry,
3285
+ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS],
3286
+ &hisi_sas_debugfs_ras_fops);
3287
+
3288
+ return;
3289
+}
3290
+
3291
+static void hisi_sas_debugfs_snapshot_regs(struct hisi_hba *hisi_hba)
3292
+{
3293
+ hisi_hba->hw->snapshot_prepare(hisi_hba);
3294
+
3295
+ hisi_sas_debugfs_snapshot_global_reg(hisi_hba);
3296
+ hisi_sas_debugfs_snapshot_port_reg(hisi_hba);
3297
+ hisi_sas_debugfs_snapshot_axi_reg(hisi_hba);
3298
+ hisi_sas_debugfs_snapshot_ras_reg(hisi_hba);
3299
+ hisi_sas_debugfs_snapshot_cq_reg(hisi_hba);
3300
+ hisi_sas_debugfs_snapshot_dq_reg(hisi_hba);
3301
+ hisi_sas_debugfs_snapshot_itct_reg(hisi_hba);
3302
+ hisi_sas_debugfs_snapshot_iost_reg(hisi_hba);
3303
+
3304
+ hisi_sas_debugfs_create_files(hisi_hba);
3305
+
3306
+ hisi_hba->hw->snapshot_restore(hisi_hba);
3307
+}
3308
+
3309
+static ssize_t hisi_sas_debugfs_trigger_dump_write(struct file *file,
3310
+ const char __user *user_buf,
3311
+ size_t count, loff_t *ppos)
3312
+{
3313
+ struct hisi_hba *hisi_hba = file->f_inode->i_private;
3314
+ char buf[8];
3315
+
3316
+ if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count)
3317
+ return -EFAULT;
3318
+
3319
+ if (count > 8)
3320
+ return -EFAULT;
3321
+
3322
+ if (copy_from_user(buf, user_buf, count))
3323
+ return -EFAULT;
3324
+
3325
+ if (buf[0] != '1')
3326
+ return -EFAULT;
3327
+
3328
+ queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
3329
+
3330
+ return count;
3331
+}
3332
+
3333
+static const struct file_operations hisi_sas_debugfs_trigger_dump_fops = {
3334
+ .write = &hisi_sas_debugfs_trigger_dump_write,
3335
+ .owner = THIS_MODULE,
3336
+};
3337
+
3338
+enum {
3339
+ HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL = 0,
3340
+ HISI_SAS_BIST_LOOPBACK_MODE_SERDES,
3341
+ HISI_SAS_BIST_LOOPBACK_MODE_REMOTE,
3342
+};
3343
+
3344
+static const struct {
3345
+ int value;
3346
+ char *name;
3347
+} hisi_sas_debugfs_loop_linkrate[] = {
3348
+ { SAS_LINK_RATE_1_5_GBPS, "1.5 Gbit" },
3349
+ { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" },
3350
+ { SAS_LINK_RATE_6_0_GBPS, "6.0 Gbit" },
3351
+ { SAS_LINK_RATE_12_0_GBPS, "12.0 Gbit" },
3352
+};
3353
+
3354
+static int hisi_sas_debugfs_bist_linkrate_show(struct seq_file *s, void *p)
3355
+{
3356
+ struct hisi_hba *hisi_hba = s->private;
3357
+ int i;
3358
+
3359
+ for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_linkrate); i++) {
3360
+ int match = (hisi_hba->debugfs_bist_linkrate ==
3361
+ hisi_sas_debugfs_loop_linkrate[i].value);
3362
+
3363
+ seq_printf(s, "%s%s%s ", match ? "[" : "",
3364
+ hisi_sas_debugfs_loop_linkrate[i].name,
3365
+ match ? "]" : "");
3366
+ }
3367
+ seq_puts(s, "\n");
3368
+
3369
+ return 0;
3370
+}
3371
+
3372
+static ssize_t hisi_sas_debugfs_bist_linkrate_write(struct file *filp,
3373
+ const char __user *buf,
3374
+ size_t count, loff_t *ppos)
3375
+{
3376
+ struct seq_file *m = filp->private_data;
3377
+ struct hisi_hba *hisi_hba = m->private;
3378
+ char kbuf[16] = {}, *pkbuf;
3379
+ bool found = false;
3380
+ int i;
3381
+
3382
+ if (hisi_hba->debugfs_bist_enable)
3383
+ return -EPERM;
3384
+
3385
+ if (count >= sizeof(kbuf))
3386
+ return -EOVERFLOW;
3387
+
3388
+ if (copy_from_user(kbuf, buf, count))
3389
+ return -EINVAL;
3390
+
3391
+ pkbuf = strstrip(kbuf);
3392
+
3393
+ for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_linkrate); i++) {
3394
+ if (!strncmp(hisi_sas_debugfs_loop_linkrate[i].name,
3395
+ pkbuf, 16)) {
3396
+ hisi_hba->debugfs_bist_linkrate =
3397
+ hisi_sas_debugfs_loop_linkrate[i].value;
3398
+ found = true;
3399
+ break;
3400
+ }
3401
+ }
3402
+
3403
+ if (!found)
3404
+ return -EINVAL;
3405
+
3406
+ return count;
3407
+}
3408
+
3409
+static int hisi_sas_debugfs_bist_linkrate_open(struct inode *inode,
3410
+ struct file *filp)
3411
+{
3412
+ return single_open(filp, hisi_sas_debugfs_bist_linkrate_show,
3413
+ inode->i_private);
3414
+}
3415
+
3416
+static const struct file_operations hisi_sas_debugfs_bist_linkrate_ops = {
3417
+ .open = hisi_sas_debugfs_bist_linkrate_open,
3418
+ .read = seq_read,
3419
+ .write = hisi_sas_debugfs_bist_linkrate_write,
3420
+ .llseek = seq_lseek,
3421
+ .release = single_release,
3422
+ .owner = THIS_MODULE,
3423
+};
3424
+
3425
+static const struct {
3426
+ int value;
3427
+ char *name;
3428
+} hisi_sas_debugfs_loop_code_mode[] = {
3429
+ { HISI_SAS_BIST_CODE_MODE_PRBS7, "PRBS7" },
3430
+ { HISI_SAS_BIST_CODE_MODE_PRBS23, "PRBS23" },
3431
+ { HISI_SAS_BIST_CODE_MODE_PRBS31, "PRBS31" },
3432
+ { HISI_SAS_BIST_CODE_MODE_JTPAT, "JTPAT" },
3433
+ { HISI_SAS_BIST_CODE_MODE_CJTPAT, "CJTPAT" },
3434
+ { HISI_SAS_BIST_CODE_MODE_SCRAMBED_0, "SCRAMBED_0" },
3435
+ { HISI_SAS_BIST_CODE_MODE_TRAIN, "TRAIN" },
3436
+ { HISI_SAS_BIST_CODE_MODE_TRAIN_DONE, "TRAIN_DONE" },
3437
+ { HISI_SAS_BIST_CODE_MODE_HFTP, "HFTP" },
3438
+ { HISI_SAS_BIST_CODE_MODE_MFTP, "MFTP" },
3439
+ { HISI_SAS_BIST_CODE_MODE_LFTP, "LFTP" },
3440
+ { HISI_SAS_BIST_CODE_MODE_FIXED_DATA, "FIXED_DATA" },
3441
+};
3442
+
3443
+static int hisi_sas_debugfs_bist_code_mode_show(struct seq_file *s, void *p)
3444
+{
3445
+ struct hisi_hba *hisi_hba = s->private;
3446
+ int i;
3447
+
3448
+ for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_code_mode); i++) {
3449
+ int match = (hisi_hba->debugfs_bist_code_mode ==
3450
+ hisi_sas_debugfs_loop_code_mode[i].value);
3451
+
3452
+ seq_printf(s, "%s%s%s ", match ? "[" : "",
3453
+ hisi_sas_debugfs_loop_code_mode[i].name,
3454
+ match ? "]" : "");
3455
+ }
3456
+ seq_puts(s, "\n");
3457
+
3458
+ return 0;
3459
+}
3460
+
3461
+static ssize_t hisi_sas_debugfs_bist_code_mode_write(struct file *filp,
3462
+ const char __user *buf,
3463
+ size_t count,
3464
+ loff_t *ppos)
3465
+{
3466
+ struct seq_file *m = filp->private_data;
3467
+ struct hisi_hba *hisi_hba = m->private;
3468
+ char kbuf[16] = {}, *pkbuf;
3469
+ bool found = false;
3470
+ int i;
3471
+
3472
+ if (hisi_hba->debugfs_bist_enable)
3473
+ return -EPERM;
3474
+
3475
+ if (count >= sizeof(kbuf))
3476
+ return -EINVAL;
3477
+
3478
+ if (copy_from_user(kbuf, buf, count))
3479
+ return -EOVERFLOW;
3480
+
3481
+ pkbuf = strstrip(kbuf);
3482
+
3483
+ for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_code_mode); i++) {
3484
+ if (!strncmp(hisi_sas_debugfs_loop_code_mode[i].name,
3485
+ pkbuf, 16)) {
3486
+ hisi_hba->debugfs_bist_code_mode =
3487
+ hisi_sas_debugfs_loop_code_mode[i].value;
3488
+ found = true;
3489
+ break;
3490
+ }
3491
+ }
3492
+
3493
+ if (!found)
3494
+ return -EINVAL;
3495
+
3496
+ return count;
3497
+}
3498
+
3499
+static int hisi_sas_debugfs_bist_code_mode_open(struct inode *inode,
3500
+ struct file *filp)
3501
+{
3502
+ return single_open(filp, hisi_sas_debugfs_bist_code_mode_show,
3503
+ inode->i_private);
3504
+}
3505
+
3506
+static const struct file_operations hisi_sas_debugfs_bist_code_mode_ops = {
3507
+ .open = hisi_sas_debugfs_bist_code_mode_open,
3508
+ .read = seq_read,
3509
+ .write = hisi_sas_debugfs_bist_code_mode_write,
3510
+ .llseek = seq_lseek,
3511
+ .release = single_release,
3512
+ .owner = THIS_MODULE,
3513
+};
3514
+
3515
+static ssize_t hisi_sas_debugfs_bist_phy_write(struct file *filp,
3516
+ const char __user *buf,
3517
+ size_t count, loff_t *ppos)
3518
+{
3519
+ struct seq_file *m = filp->private_data;
3520
+ struct hisi_hba *hisi_hba = m->private;
3521
+ unsigned int phy_no;
3522
+ int val;
3523
+
3524
+ if (hisi_hba->debugfs_bist_enable)
3525
+ return -EPERM;
3526
+
3527
+ val = kstrtouint_from_user(buf, count, 0, &phy_no);
3528
+ if (val)
3529
+ return val;
3530
+
3531
+ if (phy_no >= hisi_hba->n_phy)
3532
+ return -EINVAL;
3533
+
3534
+ hisi_hba->debugfs_bist_phy_no = phy_no;
3535
+
3536
+ return count;
3537
+}
3538
+
3539
+static int hisi_sas_debugfs_bist_phy_show(struct seq_file *s, void *p)
3540
+{
3541
+ struct hisi_hba *hisi_hba = s->private;
3542
+
3543
+ seq_printf(s, "%d\n", hisi_hba->debugfs_bist_phy_no);
3544
+
3545
+ return 0;
3546
+}
3547
+
3548
+static int hisi_sas_debugfs_bist_phy_open(struct inode *inode,
3549
+ struct file *filp)
3550
+{
3551
+ return single_open(filp, hisi_sas_debugfs_bist_phy_show,
3552
+ inode->i_private);
3553
+}
3554
+
3555
+static const struct file_operations hisi_sas_debugfs_bist_phy_ops = {
3556
+ .open = hisi_sas_debugfs_bist_phy_open,
3557
+ .read = seq_read,
3558
+ .write = hisi_sas_debugfs_bist_phy_write,
3559
+ .llseek = seq_lseek,
3560
+ .release = single_release,
3561
+ .owner = THIS_MODULE,
3562
+};
3563
+
3564
+static const struct {
3565
+ int value;
3566
+ char *name;
3567
+} hisi_sas_debugfs_loop_modes[] = {
3568
+ { HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL, "digital" },
3569
+ { HISI_SAS_BIST_LOOPBACK_MODE_SERDES, "serdes" },
3570
+ { HISI_SAS_BIST_LOOPBACK_MODE_REMOTE, "remote" },
3571
+};
3572
+
3573
+static int hisi_sas_debugfs_bist_mode_show(struct seq_file *s, void *p)
3574
+{
3575
+ struct hisi_hba *hisi_hba = s->private;
3576
+ int i;
3577
+
3578
+ for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_modes); i++) {
3579
+ int match = (hisi_hba->debugfs_bist_mode ==
3580
+ hisi_sas_debugfs_loop_modes[i].value);
3581
+
3582
+ seq_printf(s, "%s%s%s ", match ? "[" : "",
3583
+ hisi_sas_debugfs_loop_modes[i].name,
3584
+ match ? "]" : "");
3585
+ }
3586
+ seq_puts(s, "\n");
3587
+
3588
+ return 0;
3589
+}
3590
+
3591
+static ssize_t hisi_sas_debugfs_bist_mode_write(struct file *filp,
3592
+ const char __user *buf,
3593
+ size_t count, loff_t *ppos)
3594
+{
3595
+ struct seq_file *m = filp->private_data;
3596
+ struct hisi_hba *hisi_hba = m->private;
3597
+ char kbuf[16] = {}, *pkbuf;
3598
+ bool found = false;
3599
+ int i;
3600
+
3601
+ if (hisi_hba->debugfs_bist_enable)
3602
+ return -EPERM;
3603
+
3604
+ if (count >= sizeof(kbuf))
3605
+ return -EINVAL;
3606
+
3607
+ if (copy_from_user(kbuf, buf, count))
3608
+ return -EOVERFLOW;
3609
+
3610
+ pkbuf = strstrip(kbuf);
3611
+
3612
+ for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_modes); i++) {
3613
+ if (!strncmp(hisi_sas_debugfs_loop_modes[i].name, pkbuf, 16)) {
3614
+ hisi_hba->debugfs_bist_mode =
3615
+ hisi_sas_debugfs_loop_modes[i].value;
3616
+ found = true;
3617
+ break;
3618
+ }
3619
+ }
3620
+
3621
+ if (!found)
3622
+ return -EINVAL;
3623
+
3624
+ return count;
3625
+}
3626
+
3627
+static int hisi_sas_debugfs_bist_mode_open(struct inode *inode,
3628
+ struct file *filp)
3629
+{
3630
+ return single_open(filp, hisi_sas_debugfs_bist_mode_show,
3631
+ inode->i_private);
3632
+}
3633
+
3634
+static const struct file_operations hisi_sas_debugfs_bist_mode_ops = {
3635
+ .open = hisi_sas_debugfs_bist_mode_open,
3636
+ .read = seq_read,
3637
+ .write = hisi_sas_debugfs_bist_mode_write,
3638
+ .llseek = seq_lseek,
3639
+ .release = single_release,
3640
+ .owner = THIS_MODULE,
3641
+};
3642
+
3643
+static ssize_t hisi_sas_debugfs_bist_enable_write(struct file *filp,
3644
+ const char __user *buf,
3645
+ size_t count, loff_t *ppos)
3646
+{
3647
+ struct seq_file *m = filp->private_data;
3648
+ struct hisi_hba *hisi_hba = m->private;
3649
+ unsigned int enable;
3650
+ int val;
3651
+
3652
+ val = kstrtouint_from_user(buf, count, 0, &enable);
3653
+ if (val)
3654
+ return val;
3655
+
3656
+ if (enable > 1)
3657
+ return -EINVAL;
3658
+
3659
+ if (enable == hisi_hba->debugfs_bist_enable)
3660
+ return count;
3661
+
3662
+ if (!hisi_hba->hw->set_bist)
3663
+ return -EPERM;
3664
+
3665
+ val = hisi_hba->hw->set_bist(hisi_hba, enable);
3666
+ if (val < 0)
3667
+ return val;
3668
+
3669
+ hisi_hba->debugfs_bist_enable = enable;
3670
+
3671
+ return count;
3672
+}
3673
+
3674
+static int hisi_sas_debugfs_bist_enable_show(struct seq_file *s, void *p)
3675
+{
3676
+ struct hisi_hba *hisi_hba = s->private;
3677
+
3678
+ seq_printf(s, "%d\n", hisi_hba->debugfs_bist_enable);
3679
+
3680
+ return 0;
3681
+}
3682
+
3683
+static int hisi_sas_debugfs_bist_enable_open(struct inode *inode,
3684
+ struct file *filp)
3685
+{
3686
+ return single_open(filp, hisi_sas_debugfs_bist_enable_show,
3687
+ inode->i_private);
3688
+}
3689
+
3690
+static const struct file_operations hisi_sas_debugfs_bist_enable_ops = {
3691
+ .open = hisi_sas_debugfs_bist_enable_open,
3692
+ .read = seq_read,
3693
+ .write = hisi_sas_debugfs_bist_enable_write,
3694
+ .llseek = seq_lseek,
3695
+ .release = single_release,
3696
+ .owner = THIS_MODULE,
3697
+};
3698
+
3699
+static const struct {
3700
+ char *name;
3701
+} hisi_sas_debugfs_ffe_name[FFE_CFG_MAX] = {
3702
+ { "SAS_1_5_GBPS" },
3703
+ { "SAS_3_0_GBPS" },
3704
+ { "SAS_6_0_GBPS" },
3705
+ { "SAS_12_0_GBPS" },
3706
+ { "FFE_RESV" },
3707
+ { "SATA_1_5_GBPS" },
3708
+ { "SATA_3_0_GBPS" },
3709
+ { "SATA_6_0_GBPS" },
3710
+};
3711
+
3712
+static ssize_t hisi_sas_debugfs_write(struct file *filp,
3713
+ const char __user *buf,
3714
+ size_t count, loff_t *ppos)
3715
+{
3716
+ struct seq_file *m = filp->private_data;
3717
+ u32 *val = m->private;
3718
+ int res;
3719
+
3720
+ res = kstrtouint_from_user(buf, count, 0, val);
3721
+ if (res)
3722
+ return res;
3723
+
3724
+ return count;
3725
+}
3726
+
3727
+static int hisi_sas_debugfs_show(struct seq_file *s, void *p)
3728
+{
3729
+ u32 *val = s->private;
3730
+
3731
+ seq_printf(s, "0x%x\n", *val);
3732
+
3733
+ return 0;
3734
+}
3735
+
3736
+static int hisi_sas_debugfs_open(struct inode *inode, struct file *filp)
3737
+{
3738
+ return single_open(filp, hisi_sas_debugfs_show,
3739
+ inode->i_private);
3740
+}
3741
+
3742
+static const struct file_operations hisi_sas_debugfs_ops = {
3743
+ .open = hisi_sas_debugfs_open,
3744
+ .read = seq_read,
3745
+ .write = hisi_sas_debugfs_write,
3746
+ .llseek = seq_lseek,
3747
+ .release = single_release,
3748
+ .owner = THIS_MODULE,
3749
+};
3750
+
3751
+static ssize_t hisi_sas_debugfs_phy_down_cnt_write(struct file *filp,
3752
+ const char __user *buf,
3753
+ size_t count, loff_t *ppos)
3754
+{
3755
+ struct seq_file *s = filp->private_data;
3756
+ struct hisi_sas_phy *phy = s->private;
3757
+ unsigned int set_val;
3758
+ int res;
3759
+
3760
+ res = kstrtouint_from_user(buf, count, 0, &set_val);
3761
+ if (res)
3762
+ return res;
3763
+
3764
+ if (set_val > 0)
3765
+ return -EINVAL;
3766
+
3767
+ atomic_set(&phy->down_cnt, 0);
3768
+
3769
+ return count;
3770
+}
3771
+
3772
+static int hisi_sas_debugfs_phy_down_cnt_show(struct seq_file *s, void *p)
3773
+{
3774
+ struct hisi_sas_phy *phy = s->private;
3775
+
3776
+ seq_printf(s, "%d\n", atomic_read(&phy->down_cnt));
3777
+
3778
+ return 0;
3779
+}
3780
+
3781
+static int hisi_sas_debugfs_phy_down_cnt_open(struct inode *inode,
3782
+ struct file *filp)
3783
+{
3784
+ return single_open(filp, hisi_sas_debugfs_phy_down_cnt_show,
3785
+ inode->i_private);
3786
+}
3787
+
3788
+static const struct file_operations hisi_sas_debugfs_phy_down_cnt_ops = {
3789
+ .open = hisi_sas_debugfs_phy_down_cnt_open,
3790
+ .read = seq_read,
3791
+ .write = hisi_sas_debugfs_phy_down_cnt_write,
3792
+ .llseek = seq_lseek,
3793
+ .release = single_release,
3794
+ .owner = THIS_MODULE,
3795
+};
3796
+
3797
+void hisi_sas_debugfs_work_handler(struct work_struct *work)
3798
+{
3799
+ struct hisi_hba *hisi_hba =
3800
+ container_of(work, struct hisi_hba, debugfs_work);
3801
+ int debugfs_dump_index = hisi_hba->debugfs_dump_index;
3802
+ struct device *dev = hisi_hba->dev;
3803
+ u64 timestamp = local_clock();
3804
+
3805
+ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
3806
+ dev_warn(dev, "dump count exceeded!\n");
3807
+ return;
3808
+ }
3809
+
3810
+ do_div(timestamp, NSEC_PER_MSEC);
3811
+ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
3812
+
3813
+ hisi_sas_debugfs_snapshot_regs(hisi_hba);
3814
+ hisi_hba->debugfs_dump_index++;
3815
+}
3816
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler);
3817
+
3818
+static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba, int dump_index)
3819
+{
3820
+ struct device *dev = hisi_hba->dev;
3821
+ int i;
3822
+
3823
+ devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache);
3824
+ devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache);
3825
+ devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost);
3826
+ devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct);
3827
+
3828
+ for (i = 0; i < hisi_hba->queue_count; i++)
3829
+ devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr);
3830
+
3831
+ for (i = 0; i < hisi_hba->queue_count; i++)
3832
+ devm_kfree(dev,
3833
+ hisi_hba->debugfs_cq[dump_index][i].complete_hdr);
3834
+
3835
+ for (i = 0; i < DEBUGFS_REGS_NUM; i++)
3836
+ devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data);
3837
+
3838
+ for (i = 0; i < hisi_hba->n_phy; i++)
3839
+ devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data);
3840
+}
3841
+
3842
+static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index)
3843
+{
3844
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
3845
+ struct device *dev = hisi_hba->dev;
3846
+ int p, c, d, r, i;
3847
+ size_t sz;
3848
+
3849
+ for (r = 0; r < DEBUGFS_REGS_NUM; r++) {
3850
+ struct hisi_sas_debugfs_regs *regs =
3851
+ &hisi_hba->debugfs_regs[dump_index][r];
3852
+
3853
+ sz = hw->debugfs_reg_array[r]->count * 4;
3854
+ regs->data = devm_kmalloc(dev, sz, GFP_KERNEL);
3855
+ if (!regs->data)
3856
+ goto fail;
3857
+ regs->hisi_hba = hisi_hba;
3858
+ }
3859
+
3860
+ sz = hw->debugfs_reg_port->count * 4;
3861
+ for (p = 0; p < hisi_hba->n_phy; p++) {
3862
+ struct hisi_sas_debugfs_port *port =
3863
+ &hisi_hba->debugfs_port_reg[dump_index][p];
3864
+
3865
+ port->data = devm_kmalloc(dev, sz, GFP_KERNEL);
3866
+ if (!port->data)
3867
+ goto fail;
3868
+ port->phy = &hisi_hba->phy[p];
3869
+ }
3870
+
3871
+ sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
3872
+ for (c = 0; c < hisi_hba->queue_count; c++) {
3873
+ struct hisi_sas_debugfs_cq *cq =
3874
+ &hisi_hba->debugfs_cq[dump_index][c];
3875
+
3876
+ cq->complete_hdr = devm_kmalloc(dev, sz, GFP_KERNEL);
3877
+ if (!cq->complete_hdr)
3878
+ goto fail;
3879
+ cq->cq = &hisi_hba->cq[c];
3880
+ }
3881
+
3882
+ sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS;
3883
+ for (d = 0; d < hisi_hba->queue_count; d++) {
3884
+ struct hisi_sas_debugfs_dq *dq =
3885
+ &hisi_hba->debugfs_dq[dump_index][d];
3886
+
3887
+ dq->hdr = devm_kmalloc(dev, sz, GFP_KERNEL);
3888
+ if (!dq->hdr)
3889
+ goto fail;
3890
+ dq->dq = &hisi_hba->dq[d];
3891
+ }
3892
+
3893
+ sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost);
3894
+
3895
+ hisi_hba->debugfs_iost[dump_index].iost =
3896
+ devm_kmalloc(dev, sz, GFP_KERNEL);
3897
+ if (!hisi_hba->debugfs_iost[dump_index].iost)
3898
+ goto fail;
3899
+
3900
+ sz = HISI_SAS_IOST_ITCT_CACHE_NUM *
3901
+ sizeof(struct hisi_sas_iost_itct_cache);
3902
+
3903
+ hisi_hba->debugfs_iost_cache[dump_index].cache =
3904
+ devm_kmalloc(dev, sz, GFP_KERNEL);
3905
+ if (!hisi_hba->debugfs_iost_cache[dump_index].cache)
3906
+ goto fail;
3907
+
3908
+ sz = HISI_SAS_IOST_ITCT_CACHE_NUM *
3909
+ sizeof(struct hisi_sas_iost_itct_cache);
3910
+
3911
+ hisi_hba->debugfs_itct_cache[dump_index].cache =
3912
+ devm_kmalloc(dev, sz, GFP_KERNEL);
3913
+ if (!hisi_hba->debugfs_itct_cache[dump_index].cache)
3914
+ goto fail;
3915
+
3916
+ /* New memory allocation must be locate before itct */
3917
+ sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
3918
+
3919
+ hisi_hba->debugfs_itct[dump_index].itct =
3920
+ devm_kmalloc(dev, sz, GFP_KERNEL);
3921
+ if (!hisi_hba->debugfs_itct[dump_index].itct)
3922
+ goto fail;
3923
+
3924
+ return 0;
3925
+fail:
3926
+ for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
3927
+ hisi_sas_debugfs_release(hisi_hba, i);
3928
+ return -ENOMEM;
3929
+}
3930
+
3931
+static void hisi_sas_debugfs_phy_down_cnt_init(struct hisi_hba *hisi_hba)
3932
+{
3933
+ struct dentry *dir = debugfs_create_dir("phy_down_cnt",
3934
+ hisi_hba->debugfs_dir);
3935
+ char name[16];
3936
+ int phy_no;
3937
+
3938
+ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
3939
+ snprintf(name, 16, "%d", phy_no);
3940
+ debugfs_create_file(name, 0600, dir,
3941
+ &hisi_hba->phy[phy_no],
3942
+ &hisi_sas_debugfs_phy_down_cnt_ops);
3943
+ }
3944
+}
3945
+
3946
+static void hisi_sas_debugfs_bist_init(struct hisi_hba *hisi_hba)
3947
+{
3948
+ struct dentry *ports_dentry;
3949
+ int phy_no;
3950
+
3951
+ hisi_hba->debugfs_bist_dentry =
3952
+ debugfs_create_dir("bist", hisi_hba->debugfs_dir);
3953
+ debugfs_create_file("link_rate", 0600,
3954
+ hisi_hba->debugfs_bist_dentry, hisi_hba,
3955
+ &hisi_sas_debugfs_bist_linkrate_ops);
3956
+
3957
+ debugfs_create_file("code_mode", 0600,
3958
+ hisi_hba->debugfs_bist_dentry, hisi_hba,
3959
+ &hisi_sas_debugfs_bist_code_mode_ops);
3960
+
3961
+ debugfs_create_file("fixed_code", 0600,
3962
+ hisi_hba->debugfs_bist_dentry,
3963
+ &hisi_hba->debugfs_bist_fixed_code[0],
3964
+ &hisi_sas_debugfs_ops);
3965
+
3966
+ debugfs_create_file("fixed_code_1", 0600,
3967
+ hisi_hba->debugfs_bist_dentry,
3968
+ &hisi_hba->debugfs_bist_fixed_code[1],
3969
+ &hisi_sas_debugfs_ops);
3970
+
3971
+ debugfs_create_file("phy_id", 0600, hisi_hba->debugfs_bist_dentry,
3972
+ hisi_hba, &hisi_sas_debugfs_bist_phy_ops);
3973
+
3974
+ debugfs_create_u32("cnt", 0600, hisi_hba->debugfs_bist_dentry,
3975
+ &hisi_hba->debugfs_bist_cnt);
3976
+
3977
+ debugfs_create_file("loopback_mode", 0600,
3978
+ hisi_hba->debugfs_bist_dentry,
3979
+ hisi_hba, &hisi_sas_debugfs_bist_mode_ops);
3980
+
3981
+ debugfs_create_file("enable", 0600, hisi_hba->debugfs_bist_dentry,
3982
+ hisi_hba, &hisi_sas_debugfs_bist_enable_ops);
3983
+
3984
+ ports_dentry = debugfs_create_dir("port", hisi_hba->debugfs_bist_dentry);
3985
+
3986
+ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
3987
+ struct dentry *port_dentry;
3988
+ struct dentry *ffe_dentry;
3989
+ char name[256];
3990
+ int i;
3991
+
3992
+ snprintf(name, 256, "%d", phy_no);
3993
+ port_dentry = debugfs_create_dir(name, ports_dentry);
3994
+ ffe_dentry = debugfs_create_dir("ffe", port_dentry);
3995
+ for (i = 0; i < FFE_CFG_MAX; i++) {
3996
+ if (i == FFE_RESV)
3997
+ continue;
3998
+ debugfs_create_file(hisi_sas_debugfs_ffe_name[i].name,
3999
+ 0600, ffe_dentry,
4000
+ &hisi_hba->debugfs_bist_ffe[phy_no][i],
4001
+ &hisi_sas_debugfs_ops);
4002
+ }
4003
+ }
4004
+
4005
+ hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS;
4006
+}
4007
+
4008
+void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba)
4009
+{
4010
+ struct device *dev = hisi_hba->dev;
4011
+ int i;
4012
+
4013
+ hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
4014
+ hisi_sas_debugfs_dir);
4015
+ debugfs_create_file("trigger_dump", 0200,
4016
+ hisi_hba->debugfs_dir,
4017
+ hisi_hba,
4018
+ &hisi_sas_debugfs_trigger_dump_fops);
4019
+
4020
+ /* create bist structures */
4021
+ hisi_sas_debugfs_bist_init(hisi_hba);
4022
+
4023
+ hisi_hba->debugfs_dump_dentry =
4024
+ debugfs_create_dir("dump", hisi_hba->debugfs_dir);
4025
+
4026
+ hisi_sas_debugfs_phy_down_cnt_init(hisi_hba);
4027
+
4028
+ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
4029
+ if (hisi_sas_debugfs_alloc(hisi_hba, i)) {
4030
+ debugfs_remove_recursive(hisi_hba->debugfs_dir);
4031
+ dev_dbg(dev, "failed to init debugfs!\n");
4032
+ break;
4033
+ }
4034
+ }
4035
+}
4036
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init);
4037
+
4038
+void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba)
4039
+{
4040
+ debugfs_remove_recursive(hisi_hba->debugfs_dir);
4041
+}
4042
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_exit);
24284043
24294044 int hisi_sas_remove(struct platform_device *pdev)
24304045 {
....@@ -2444,11 +4059,29 @@
24444059 }
24454060 EXPORT_SYMBOL_GPL(hisi_sas_remove);
24464061
4062
+bool hisi_sas_debugfs_enable;
4063
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable);
4064
+module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444);
4065
+MODULE_PARM_DESC(hisi_sas_debugfs_enable, "Enable driver debugfs (default disabled)");
4066
+
4067
+u32 hisi_sas_debugfs_dump_count = 1;
4068
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count);
4069
+module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444);
4070
+MODULE_PARM_DESC(hisi_sas_debugfs_dump_count, "Number of debugfs dumps to allow");
4071
+
24474072 static __init int hisi_sas_init(void)
24484073 {
24494074 hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops);
24504075 if (!hisi_sas_stt)
24514076 return -ENOMEM;
4077
+
4078
+ if (hisi_sas_debugfs_enable) {
4079
+ hisi_sas_debugfs_dir = debugfs_create_dir("hisi_sas", NULL);
4080
+ if (hisi_sas_debugfs_dump_count > HISI_SAS_MAX_DEBUGFS_DUMP) {
4081
+ pr_info("hisi_sas: Limiting debugfs dump count\n");
4082
+ hisi_sas_debugfs_dump_count = HISI_SAS_MAX_DEBUGFS_DUMP;
4083
+ }
4084
+ }
24524085
24534086 return 0;
24544087 }
....@@ -2456,6 +4089,8 @@
24564089 static __exit void hisi_sas_exit(void)
24574090 {
24584091 sas_release_transport(hisi_sas_stt);
4092
+
4093
+ debugfs_remove(hisi_sas_debugfs_dir);
24594094 }
24604095
24614096 module_init(hisi_sas_init);