@@ -1707,6 +1707,123 @@ int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data,
1707
1707
return ret ;
1708
1708
}
1709
1709
1710
+ static void pm8001_send_abort_all (struct pm8001_hba_info * pm8001_ha ,
1711
+ struct pm8001_device * pm8001_ha_dev )
1712
+ {
1713
+ int res ;
1714
+ u32 ccb_tag ;
1715
+ struct pm8001_ccb_info * ccb ;
1716
+ struct sas_task * task = NULL ;
1717
+ struct task_abort_req task_abort ;
1718
+ struct inbound_queue_table * circularQ ;
1719
+ u32 opc = OPC_INB_SATA_ABORT ;
1720
+ int ret ;
1721
+
1722
+ if (!pm8001_ha_dev ) {
1723
+ PM8001_FAIL_DBG (pm8001_ha , pm8001_printk ("dev is null\n" ));
1724
+ return ;
1725
+ }
1726
+
1727
+ task = sas_alloc_slow_task (GFP_ATOMIC );
1728
+
1729
+ if (!task ) {
1730
+ PM8001_FAIL_DBG (pm8001_ha , pm8001_printk ("cannot "
1731
+ "allocate task\n" ));
1732
+ return ;
1733
+ }
1734
+
1735
+ task -> task_done = pm8001_task_done ;
1736
+
1737
+ res = pm8001_tag_alloc (pm8001_ha , & ccb_tag );
1738
+ if (res )
1739
+ return ;
1740
+
1741
+ ccb = & pm8001_ha -> ccb_info [ccb_tag ];
1742
+ ccb -> device = pm8001_ha_dev ;
1743
+ ccb -> ccb_tag = ccb_tag ;
1744
+ ccb -> task = task ;
1745
+
1746
+ circularQ = & pm8001_ha -> inbnd_q_tbl [0 ];
1747
+
1748
+ memset (& task_abort , 0 , sizeof (task_abort ));
1749
+ task_abort .abort_all = cpu_to_le32 (1 );
1750
+ task_abort .device_id = cpu_to_le32 (pm8001_ha_dev -> device_id );
1751
+ task_abort .tag = cpu_to_le32 (ccb_tag );
1752
+
1753
+ ret = pm8001_mpi_build_cmd (pm8001_ha , circularQ , opc , & task_abort , 0 );
1754
+
1755
+ }
1756
+
1757
+ static void pm8001_send_read_log (struct pm8001_hba_info * pm8001_ha ,
1758
+ struct pm8001_device * pm8001_ha_dev )
1759
+ {
1760
+ struct sata_start_req sata_cmd ;
1761
+ int res ;
1762
+ u32 ccb_tag ;
1763
+ struct pm8001_ccb_info * ccb ;
1764
+ struct sas_task * task = NULL ;
1765
+ struct host_to_dev_fis fis ;
1766
+ struct domain_device * dev ;
1767
+ struct inbound_queue_table * circularQ ;
1768
+ u32 opc = OPC_INB_SATA_HOST_OPSTART ;
1769
+
1770
+ task = sas_alloc_slow_task (GFP_ATOMIC );
1771
+
1772
+ if (!task ) {
1773
+ PM8001_FAIL_DBG (pm8001_ha ,
1774
+ pm8001_printk ("cannot allocate task !!!\n" ));
1775
+ return ;
1776
+ }
1777
+ task -> task_done = pm8001_task_done ;
1778
+
1779
+ res = pm8001_tag_alloc (pm8001_ha , & ccb_tag );
1780
+ if (res ) {
1781
+ PM8001_FAIL_DBG (pm8001_ha ,
1782
+ pm8001_printk ("cannot allocate tag !!!\n" ));
1783
+ return ;
1784
+ }
1785
+
1786
+ /* allocate domain device by ourselves as libsas
1787
+ * is not going to provide any
1788
+ */
1789
+ dev = kzalloc (sizeof (struct domain_device ), GFP_ATOMIC );
1790
+ if (!dev ) {
1791
+ PM8001_FAIL_DBG (pm8001_ha ,
1792
+ pm8001_printk ("Domain device cannot be allocated\n" ));
1793
+ sas_free_task (task );
1794
+ return ;
1795
+ } else {
1796
+ task -> dev = dev ;
1797
+ task -> dev -> lldd_dev = pm8001_ha_dev ;
1798
+ }
1799
+
1800
+ ccb = & pm8001_ha -> ccb_info [ccb_tag ];
1801
+ ccb -> device = pm8001_ha_dev ;
1802
+ ccb -> ccb_tag = ccb_tag ;
1803
+ ccb -> task = task ;
1804
+ pm8001_ha_dev -> id |= NCQ_READ_LOG_FLAG ;
1805
+ pm8001_ha_dev -> id |= NCQ_2ND_RLE_FLAG ;
1806
+
1807
+ memset (& sata_cmd , 0 , sizeof (sata_cmd ));
1808
+ circularQ = & pm8001_ha -> inbnd_q_tbl [0 ];
1809
+
1810
+ /* construct read log FIS */
1811
+ memset (& fis , 0 , sizeof (struct host_to_dev_fis ));
1812
+ fis .fis_type = 0x27 ;
1813
+ fis .flags = 0x80 ;
1814
+ fis .command = ATA_CMD_READ_LOG_EXT ;
1815
+ fis .lbal = 0x10 ;
1816
+ fis .sector_count = 0x1 ;
1817
+
1818
+ sata_cmd .tag = cpu_to_le32 (ccb_tag );
1819
+ sata_cmd .device_id = cpu_to_le32 (pm8001_ha_dev -> device_id );
1820
+ sata_cmd .ncqtag_atap_dir_m |= ((0x1 << 7 ) | (0x5 << 9 ));
1821
+ memcpy (& sata_cmd .sata_fis , & fis , sizeof (struct host_to_dev_fis ));
1822
+
1823
+ res = pm8001_mpi_build_cmd (pm8001_ha , circularQ , opc , & sata_cmd , 0 );
1824
+
1825
+ }
1826
+
1710
1827
/**
1711
1828
* mpi_ssp_completion- process the event that FW response to the SSP request.
1712
1829
* @pm8001_ha: our hba card information
@@ -1941,7 +2058,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
1941
2058
break ;
1942
2059
}
1943
2060
PM8001_IO_DBG (pm8001_ha ,
1944
- pm8001_printk ("scsi_status = %x \n " ,
2061
+ pm8001_printk ("scsi_status = %x\n " ,
1945
2062
psspPayload -> ssp_resp_iu .status ));
1946
2063
spin_lock_irqsave (& t -> task_state_lock , flags );
1947
2064
t -> task_state_flags &= ~SAS_TASK_STATE_PENDING ;
@@ -2170,23 +2287,64 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2170
2287
status = le32_to_cpu (psataPayload -> status );
2171
2288
tag = le32_to_cpu (psataPayload -> tag );
2172
2289
2290
+ if (!tag ) {
2291
+ PM8001_FAIL_DBG (pm8001_ha ,
2292
+ pm8001_printk ("tag null\n" ));
2293
+ return ;
2294
+ }
2173
2295
ccb = & pm8001_ha -> ccb_info [tag ];
2174
2296
param = le32_to_cpu (psataPayload -> param );
2175
- t = ccb -> task ;
2297
+ if (ccb ) {
2298
+ t = ccb -> task ;
2299
+ pm8001_dev = ccb -> device ;
2300
+ } else {
2301
+ PM8001_FAIL_DBG (pm8001_ha ,
2302
+ pm8001_printk ("ccb null\n" ));
2303
+ return ;
2304
+ }
2305
+
2306
+ if (t ) {
2307
+ if (t -> dev && (t -> dev -> lldd_dev ))
2308
+ pm8001_dev = t -> dev -> lldd_dev ;
2309
+ } else {
2310
+ PM8001_FAIL_DBG (pm8001_ha ,
2311
+ pm8001_printk ("task null\n" ));
2312
+ return ;
2313
+ }
2314
+
2315
+ if ((pm8001_dev && !(pm8001_dev -> id & NCQ_READ_LOG_FLAG ))
2316
+ && unlikely (!t || !t -> lldd_task || !t -> dev )) {
2317
+ PM8001_FAIL_DBG (pm8001_ha ,
2318
+ pm8001_printk ("task or dev null\n" ));
2319
+ return ;
2320
+ }
2321
+
2176
2322
ts = & t -> task_status ;
2177
- pm8001_dev = ccb -> device ;
2178
- if (status )
2323
+ if (!ts ) {
2179
2324
PM8001_FAIL_DBG (pm8001_ha ,
2180
- pm8001_printk ("sata IO status 0x%x\n" , status ));
2181
- if (unlikely (!t || !t -> lldd_task || !t -> dev ))
2325
+ pm8001_printk ("ts null\n" ));
2182
2326
return ;
2327
+ }
2183
2328
2184
2329
switch (status ) {
2185
2330
case IO_SUCCESS :
2186
2331
PM8001_IO_DBG (pm8001_ha , pm8001_printk ("IO_SUCCESS\n" ));
2187
2332
if (param == 0 ) {
2188
2333
ts -> resp = SAS_TASK_COMPLETE ;
2189
2334
ts -> stat = SAM_STAT_GOOD ;
2335
+ /* check if response is for SEND READ LOG */
2336
+ if (pm8001_dev &&
2337
+ (pm8001_dev -> id & NCQ_READ_LOG_FLAG )) {
2338
+ /* set new bit for abort_all */
2339
+ pm8001_dev -> id |= NCQ_ABORT_ALL_FLAG ;
2340
+ /* clear bit for read log */
2341
+ pm8001_dev -> id = pm8001_dev -> id & 0x7FFFFFFF ;
2342
+ pm8001_send_abort_all (pm8001_ha , pm8001_dev );
2343
+ /* Free the tag */
2344
+ pm8001_tag_free (pm8001_ha , tag );
2345
+ sas_free_task (t );
2346
+ return ;
2347
+ }
2190
2348
} else {
2191
2349
u8 len ;
2192
2350
ts -> resp = SAS_TASK_COMPLETE ;
@@ -2497,6 +2655,29 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2497
2655
u32 dev_id = le32_to_cpu (psataPayload -> device_id );
2498
2656
unsigned long flags ;
2499
2657
2658
+ ccb = & pm8001_ha -> ccb_info [tag ];
2659
+
2660
+ if (ccb ) {
2661
+ t = ccb -> task ;
2662
+ pm8001_dev = ccb -> device ;
2663
+ } else {
2664
+ PM8001_FAIL_DBG (pm8001_ha ,
2665
+ pm8001_printk ("No CCB !!!. returning\n" ));
2666
+ }
2667
+ if (event )
2668
+ PM8001_FAIL_DBG (pm8001_ha ,
2669
+ pm8001_printk ("SATA EVENT 0x%x\n" , event ));
2670
+
2671
+ /* Check if this is NCQ error */
2672
+ if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE ) {
2673
+ /* find device using device id */
2674
+ pm8001_dev = pm8001_find_dev (pm8001_ha , dev_id );
2675
+ /* send read log extension */
2676
+ if (pm8001_dev )
2677
+ pm8001_send_read_log (pm8001_ha , pm8001_dev );
2678
+ return ;
2679
+ }
2680
+
2500
2681
ccb = & pm8001_ha -> ccb_info [tag ];
2501
2682
t = ccb -> task ;
2502
2683
pm8001_dev = ccb -> device ;
@@ -3512,19 +3693,29 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
3512
3693
u32 status ;
3513
3694
u32 tag , scp ;
3514
3695
struct task_status_struct * ts ;
3696
+ struct pm8001_device * pm8001_dev ;
3515
3697
3516
3698
struct task_abort_resp * pPayload =
3517
3699
(struct task_abort_resp * )(piomb + 4 );
3518
3700
3519
3701
status = le32_to_cpu (pPayload -> status );
3520
3702
tag = le32_to_cpu (pPayload -> tag );
3703
+ if (!tag ) {
3704
+ PM8001_FAIL_DBG (pm8001_ha ,
3705
+ pm8001_printk (" TAG NULL. RETURNING !!!" ));
3706
+ return -1 ;
3707
+ }
3708
+
3521
3709
scp = le32_to_cpu (pPayload -> scp );
3522
3710
ccb = & pm8001_ha -> ccb_info [tag ];
3523
3711
t = ccb -> task ;
3524
- PM8001_IO_DBG (pm8001_ha ,
3525
- pm8001_printk (" status = 0x%x\n" , status ));
3526
- if (t == NULL )
3712
+ pm8001_dev = ccb -> device ; /* retrieve device */
3713
+
3714
+ if (!t ) {
3715
+ PM8001_FAIL_DBG (pm8001_ha ,
3716
+ pm8001_printk (" TASK NULL. RETURNING !!!" ));
3527
3717
return -1 ;
3718
+ }
3528
3719
ts = & t -> task_status ;
3529
3720
if (status != 0 )
3530
3721
PM8001_FAIL_DBG (pm8001_ha ,
@@ -3548,7 +3739,15 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
3548
3739
spin_unlock_irqrestore (& t -> task_state_lock , flags );
3549
3740
pm8001_ccb_task_free (pm8001_ha , t , ccb , tag );
3550
3741
mb ();
3551
- t -> task_done (t );
3742
+
3743
+ if ((pm8001_dev -> id & NCQ_ABORT_ALL_FLAG ) && t ) {
3744
+ pm8001_tag_free (pm8001_ha , tag );
3745
+ sas_free_task (t );
3746
+ /* clear the flag */
3747
+ pm8001_dev -> id &= 0xBFFFFFFF ;
3748
+ } else
3749
+ t -> task_done (t );
3750
+
3552
3751
return 0 ;
3553
3752
}
3554
3753
@@ -4133,6 +4332,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
4133
4332
u32 ATAP = 0x0 ;
4134
4333
u32 dir ;
4135
4334
struct inbound_queue_table * circularQ ;
4335
+ unsigned long flags ;
4136
4336
u32 opc = OPC_INB_SATA_HOST_OPSTART ;
4137
4337
memset (& sata_cmd , 0 , sizeof (sata_cmd ));
4138
4338
circularQ = & pm8001_ha -> inbnd_q_tbl [0 ];
@@ -4153,8 +4353,10 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
4153
4353
PM8001_IO_DBG (pm8001_ha , pm8001_printk ("FPDMA\n" ));
4154
4354
}
4155
4355
}
4156
- if (task -> ata_task .use_ncq && pm8001_get_ncq_tag (task , & hdr_tag ))
4356
+ if (task -> ata_task .use_ncq && pm8001_get_ncq_tag (task , & hdr_tag )) {
4357
+ task -> ata_task .fis .sector_count |= (u8 ) (hdr_tag << 3 );
4157
4358
ncg_tag = hdr_tag ;
4359
+ }
4158
4360
dir = data_dir_flags [task -> data_dir ] << 8 ;
4159
4361
sata_cmd .tag = cpu_to_le32 (tag );
4160
4362
sata_cmd .device_id = cpu_to_le32 (pm8001_ha_dev -> device_id );
@@ -4185,6 +4387,54 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
4185
4387
sata_cmd .len = cpu_to_le32 (task -> total_xfer_len );
4186
4388
sata_cmd .esgl = 0 ;
4187
4389
}
4390
+
4391
+ /* Check for read log for failed drive and return */
4392
+ if (sata_cmd .sata_fis .command == 0x2f ) {
4393
+ if (pm8001_ha_dev && ((pm8001_ha_dev -> id & NCQ_READ_LOG_FLAG ) ||
4394
+ (pm8001_ha_dev -> id & NCQ_ABORT_ALL_FLAG ) ||
4395
+ (pm8001_ha_dev -> id & NCQ_2ND_RLE_FLAG ))) {
4396
+ struct task_status_struct * ts ;
4397
+
4398
+ pm8001_ha_dev -> id &= 0xDFFFFFFF ;
4399
+ ts = & task -> task_status ;
4400
+
4401
+ spin_lock_irqsave (& task -> task_state_lock , flags );
4402
+ ts -> resp = SAS_TASK_COMPLETE ;
4403
+ ts -> stat = SAM_STAT_GOOD ;
4404
+ task -> task_state_flags &= ~SAS_TASK_STATE_PENDING ;
4405
+ task -> task_state_flags &= ~SAS_TASK_AT_INITIATOR ;
4406
+ task -> task_state_flags |= SAS_TASK_STATE_DONE ;
4407
+ if (unlikely ((task -> task_state_flags &
4408
+ SAS_TASK_STATE_ABORTED ))) {
4409
+ spin_unlock_irqrestore (& task -> task_state_lock ,
4410
+ flags );
4411
+ PM8001_FAIL_DBG (pm8001_ha ,
4412
+ pm8001_printk ("task 0x%p resp 0x%x "
4413
+ " stat 0x%x but aborted by upper layer "
4414
+ "\n" , task , ts -> resp , ts -> stat ));
4415
+ pm8001_ccb_task_free (pm8001_ha , task , ccb , tag );
4416
+ } else if (task -> uldd_task ) {
4417
+ spin_unlock_irqrestore (& task -> task_state_lock ,
4418
+ flags );
4419
+ pm8001_ccb_task_free (pm8001_ha , task , ccb , tag );
4420
+ mb ();/* ditto */
4421
+ spin_unlock_irq (& pm8001_ha -> lock );
4422
+ task -> task_done (task );
4423
+ spin_lock_irq (& pm8001_ha -> lock );
4424
+ return 0 ;
4425
+ } else if (!task -> uldd_task ) {
4426
+ spin_unlock_irqrestore (& task -> task_state_lock ,
4427
+ flags );
4428
+ pm8001_ccb_task_free (pm8001_ha , task , ccb , tag );
4429
+ mb ();/*ditto*/
4430
+ spin_unlock_irq (& pm8001_ha -> lock );
4431
+ task -> task_done (task );
4432
+ spin_lock_irq (& pm8001_ha -> lock );
4433
+ return 0 ;
4434
+ }
4435
+ }
4436
+ }
4437
+
4188
4438
ret = pm8001_mpi_build_cmd (pm8001_ha , circularQ , opc , & sata_cmd , 0 );
4189
4439
return ret ;
4190
4440
}
0 commit comments