1 /** @file 2 3 Copyright (c) 2016 Linaro Ltd. 4 Copyright (c) 2016 Hisilicon Limited. 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include <Uefi.h> 17 18 #include <Library/BaseLib.h> 19 #include <Library/BaseMemoryLib.h> 20 #include <Library/DebugLib.h> 21 #include <Library/DevicePathLib.h> 22 #include <Library/DmaLib.h> 23 #include <Library/IoLib.h> 24 #include <Library/MemoryAllocationLib.h> 25 #include <Library/PcdLib.h> 26 #include <Library/TimerLib.h> 27 #include <Library/UefiBootServicesTableLib.h> 28 #include <Library/UefiLib.h> 29 #include <Library/UncachedMemoryAllocationLib.h> 30 31 #include <Protocol/PlatformSasProtocol.h> 32 #include <Protocol/ScsiPassThruExt.h> 33 #include <IndustryStandard/Scsi.h> 34 35 #define READ_REG32(Base, Offset) MmioRead32 ((Base) + (Offset)) 36 #define WRITE_REG32(Base, Offset, Val) MmioWrite32 ((Base) + (Offset), (Val)) 37 38 #define PHY_READ_REG32(Base, Offset, phy) MmioRead32 ((Base) + (Offset) + 0x400 * (phy)) 39 #define PHY_WRITE_REG32(Base, Offset, phy, Val) MmioWrite32 ((Base) + (Offset) + 0x400 * (phy), (Val)) 40 41 #define DLVRY_QUEUE_ENABLE 0x0 42 #define IOST_BASE_ADDR_LO 0x8 43 #define IOST_BASE_ADDR_HI 0xc 44 #define ITCT_BASE_ADDR_LO 0x10 45 #define ITCT_BASE_ADDR_HI 0x14 46 #define BROKEN_MSG_ADDR_LO 0x18 47 #define BROKEN_MSG_ADDR_HI 0x1c 48 #define PHY_CONTEXT 0x20 49 #define PHY_PORT_NUM_MA 0x28 50 #define HGC_TRANS_TASK_CNT_LIMIT 0x38 51 #define AXI_AHB_CLK_CFG 0x3c 52 #define HGC_SAS_TXFAIL_RETRY_CTRL 0x84 53 #define HGC_GET_ITV_TIME 0x90 54 #define DEVICE_MSG_WORK_MODE 0x94 55 #define I_T_NEXUS_LOSS_TIME 0xa0 56 #define BUS_INACTIVE_LIMIT_TIME 0xa8 57 #define REJECT_TO_OPEN_LIMIT_TIME 0xac 58 #define CFG_AGING_TIME 0xbc 59 #define HGC_DFX_CFG2 0xc0 60 #define FIS_LIST_BADDR_L 0xc4 61 #define CFG_1US_TIMER_TRSH 0xcc 62 #define CFG_SAS_CONFIG 0xd4 63 #define INT_COAL_EN 0x1bc 64 #define OQ_INT_COAL_TIME 0x1c0 65 #define OQ_INT_COAL_CNT 0x1c4 66 #define ENT_INT_COAL_TIME 0x1c8 67 #define ENT_INT_COAL_CNT 0x1cc 68 #define OQ_INT_SRC 0x1d0 69 #define OQ_INT_SRC_MSK 0x1d4 70 #define ENT_INT_SRC1 0x1d8 71 #define ENT_INT_SRC2 0x1dc 72 #define ENT_INT_SRC_MSK1 0x1e0 73 #define ENT_INT_SRC_MSK2 0x1e4 74 #define SAS_ECC_INTR_MSK 0x1ec 75 #define HGC_ERR_STAT_EN 0x238 76 #define DLVRY_Q_0_BASE_ADDR_LO 0x260 77 #define DLVRY_Q_0_BASE_ADDR_HI 0x264 78 #define DLVRY_Q_0_DEPTH 0x268 79 #define DLVRY_Q_0_WR_PTR 0x26c 80 #define DLVRY_Q_0_RD_PTR 0x270 81 #define COMPL_Q_0_BASE_ADDR_LO 0x4e0 82 #define COMPL_Q_0_BASE_ADDR_HI 0x4e4 83 #define COMPL_Q_0_DEPTH 0x4e8 84 #define COMPL_Q_0_WR_PTR 0x4ec 85 #define COMPL_Q_0_RD_PTR 0x4f0 86 #define AXI_CFG 0x5100 87 88 #define PORT_BASE 0x800 89 #define PHY_CFG (PORT_BASE + 0x0) 90 #define PHY_CFG_ENA_OFF 0 91 #define PHY_CFG_ENA_MSK (0x1 << PHY_CFG_ENA_OFF) 92 #define PHY_CFG_DC_OPT_OFF 2 93 #define PHY_CFG_DC_OPT_MSK (0x1 << PHY_CFG_DC_OPT_OFF) 94 #define PROG_PHY_LINK_RATE (PORT_BASE + 0xc) 95 #define PHY_CTRL (PORT_BASE + 0x14) 96 #define PHY_CTRL_RESET BIT0 97 #define PHY_RATE_NEGO (PORT_BASE + 0x30) 98 #define PHY_PCN (PORT_BASE + 0x44) 99 #define SL_TOUT_CFG (PORT_BASE + 0x8c) 100 #define SL_CONTROL (PORT_BASE + 0x94) 101 #define SL_CONTROL_NOTIFY_EN BIT0 102 #define TX_ID_DWORD0 (PORT_BASE + 0x9c) 103 #define TX_ID_DWORD1 (PORT_BASE + 0xa0) 104 #define TX_ID_DWORD2 (PORT_BASE + 0xa4) 105 #define TX_ID_DWORD3 (PORT_BASE + 0xa8) 106 #define TX_ID_DWORD4 (PORT_BASE + 0xaC) 107 #define TX_ID_DWORD5 (PORT_BASE + 0xb0) 108 #define TX_ID_DWORD6 (PORT_BASE + 0xb4) 109 #define RX_IDAF_DWORD3 (PORT_BASE + 0xd0) 110 #define RX_IDAF_DWORD4 (PORT_BASE + 0xd4) 111 #define RXOP_CHECK_CFG_H (PORT_BASE + 0xfc) 112 #define DONE_RECEIVED_TIME (PORT_BASE + 0x12c) 113 #define CON_CFG_DRIVER (PORT_BASE + 0x130) 114 #define PHY_CONFIG2 (PORT_BASE + 0x1a8) 115 #define PHY_CONFIG2_FORCE_TXDEEMPH_OFF 3 116 #define PHY_CONFIG2_FORCE_TXDEEMPH_MSK (0x1 << PHY_CONFIG2_FORCE_TXDEEMPH_OFF) 117 #define CHL_INT_COAL_EN (PORT_BASE + 0x1d0) 118 #define CHL_INT0 (PORT_BASE + 0x1b0) 119 #define CHL_INT0_PHYCTRL_NOTRDY BIT0 120 #define CHL_INT1 (PORT_BASE + 0x1b4) 121 #define CHL_INT2 (PORT_BASE + 0x1b8) 122 #define CHL_INT2_SL_PHY_ENA BIT6 123 #define CHL_INT0_MSK (PORT_BASE + 0x1bc) 124 #define CHL_INT0_MSK_PHYCTRL_NOTRDY BIT0 125 #define CHL_INT1_MSK (PORT_BASE + 0x1c0) 126 #define CHL_INT2_MSK (PORT_BASE + 0x1c4) 127 #define DMA_TX_STATUS (PORT_BASE + 0x2d0) 128 #define DMA_TX_STATUS_BUSY BIT0 129 #define DMA_RX_STATUS (PORT_BASE + 0x2e8) 130 #define DMA_RX_STATUS_BUSY BIT0 131 132 #define QUEUE_CNT 32 133 #define QUEUE_SLOTS 256 134 #define SLOT_ENTRIES 8192 135 #define PHY_CNT 8 136 #define MAX_ITCT_ENTRIES 1 137 138 // Completion header 139 #define CMPLT_HDR_IPTT_OFF 0 140 #define CMPLT_HDR_IPTT_MSK (0xffff << CMPLT_HDR_IPTT_OFF) 141 142 #define BIT(x) (1 << x) 143 144 // HW dma structures 145 // Delivery queue header 146 // dw0 147 #define CMD_HDR_RESP_REPORT_OFF 5 148 #define CMD_HDR_RESP_REPORT_MSK 0x20 149 #define CMD_HDR_TLR_CTRL_OFF 6 150 #define CMD_HDR_TLR_CTRL_MSK 0xc0 151 #define CMD_HDR_PORT_OFF 17 152 #define CMD_HDR_PORT_MSK 0xe0000 153 #define CMD_HDR_PRIORITY_OFF 27 154 #define CMD_HDR_PRIORITY_MSK 0x8000000 155 #define CMD_HDR_MODE_OFF 28 156 #define CMD_HDR_MODE_MSK 0x10000000 157 #define CMD_HDR_CMD_OFF 29 158 #define CMD_HDR_CMD_MSK 0xe0000000 159 // dw1 160 #define CMD_HDR_VERIFY_DTL_OFF 10 161 #define CMD_HDR_VERIFY_DTL_MSK 0x400 162 #define CMD_HDR_SSP_FRAME_TYPE_OFF 13 163 #define CMD_HDR_SSP_FRAME_TYPE_MSK 0xe000 164 #define CMD_HDR_DEVICE_ID_OFF 16 165 #define CMD_HDR_DEVICE_ID_MSK 0xffff0000 166 // dw2 167 #define CMD_HDR_CFL_OFF 0 168 #define CMD_HDR_CFL_MSK 0x1ff 169 #define CMD_HDR_MRFL_OFF 15 170 #define CMD_HDR_MRFL_MSK 0xff8000 171 #define CMD_HDR_FIRST_BURST_OFF 25 172 #define CMD_HDR_FIRST_BURST_MSK 0x2000000 173 // dw3 174 #define CMD_HDR_IPTT_OFF 0 175 #define CMD_HDR_IPTT_MSK 0xffff 176 // dw6 177 #define CMD_HDR_DATA_SGL_LEN_OFF 16 178 #define CMD_HDR_DATA_SGL_LEN_MSK 0xffff0000 179 180 // Completion header 181 #define CMPLT_HDR_IPTT_OFF 0 182 #define CMPLT_HDR_IPTT_MSK (0xffff << CMPLT_HDR_IPTT_OFF) 183 #define CMPLT_HDR_CMD_CMPLT_MSK BIT17 184 #define CMPLT_HDR_ERR_RCRD_XFRD_MSK BIT18 185 #define CMPLT_HDR_RSPNS_XFRD_MSK BIT19 186 #define CMPLT_HDR_IO_CFG_ERR_MSK BIT27 187 188 #define SENSE_DATA_PRES 26 189 190 #define SGE_LIMIT 0x10000 191 #define upper_32_bits(n) ((UINT32)(((n) >> 16) >> 16)) 192 #define lower_32_bits(n) ((UINT32)(n)) 193 #define MAX_TARGET_ID 4 194 195 // Generic HW DMA host memory structures 196 struct hisi_sas_cmd_hdr { 197 UINT32 dw0; 198 UINT32 dw1; 199 UINT32 dw2; 200 UINT32 transfer_tags; 201 UINT32 data_transfer_len; 202 UINT32 first_burst_num; 203 UINT32 sg_len; 204 UINT32 dw7; 205 UINT64 cmd_table_addr; 206 UINT64 sts_buffer_addr; 207 UINT64 prd_table_addr; 208 UINT64 dif_prd_table_addr; 209 }; 210 211 struct hisi_sas_complete_hdr { 212 UINT32 data; 213 }; 214 215 struct hisi_sas_iost { 216 UINT64 qw0; 217 UINT64 qw1; 218 UINT64 qw2; 219 UINT64 qw3; 220 }; 221 222 struct hisi_sas_itct { 223 UINT64 qw0; 224 UINT64 sas_addr; 225 UINT64 qw2; 226 UINT64 qw3; 227 UINT64 qw4; 228 UINT64 qw_sata_ncq0_3; 229 UINT64 qw_sata_ncq7_4; 230 UINT64 qw_sata_ncq11_8; 231 UINT64 qw_sata_ncq15_12; 232 UINT64 qw_sata_ncq19_16; 233 UINT64 qw_sata_ncq23_20; 234 UINT64 qw_sata_ncq27_24; 235 UINT64 qw_sata_ncq31_28; 236 UINT64 qw_non_ncq_iptt; 237 UINT64 qw_rsvd0; 238 UINT64 qw_rsvd1; 239 }; 240 241 struct hisi_sas_breakpoint { 242 UINT8 data[128]; 243 }; 244 245 struct hisi_sas_sge { 246 UINT64 addr; 247 UINT32 page_ctrl_0; 248 UINT32 page_ctrl_1; 249 UINT32 data_len; 250 UINT32 data_off; 251 }; 252 253 struct hisi_sas_sge_page { 254 struct hisi_sas_sge sg[512]; 255 }; 256 257 struct hisi_sas_cmd { 258 UINT8 cmd[128]; 259 }; 260 261 struct hisi_sas_sts { 262 UINT32 status[260]; 263 }; 264 265 struct hisi_sas_slot { 266 BOOLEAN used; 267 }; 268 269 struct hisi_hba { 270 struct hisi_sas_cmd_hdr *cmd_hdr[QUEUE_CNT]; 271 struct hisi_sas_complete_hdr *complete_hdr[QUEUE_CNT]; 272 struct hisi_sas_sge_page *sge[QUEUE_CNT]; 273 struct hisi_sas_sts *status_buf[QUEUE_CNT]; 274 struct hisi_sas_cmd *command_table[QUEUE_CNT]; 275 struct hisi_sas_iost *iost; 276 struct hisi_sas_itct *itct; 277 struct hisi_sas_breakpoint *breakpoint; 278 struct hisi_sas_slot *slots; 279 UINT32 base; 280 int queue; 281 int port_id; 282 UINT32 LatestTargetId; 283 UINT64 LatestLun; 284 }; 285 286 #pragma pack (1) 287 typedef struct { 288 VENDOR_DEVICE_PATH Vendor; 289 UINT64 PhysBase; 290 EFI_DEVICE_PATH_PROTOCOL End; 291 } SAS_V1_TRANSPORT_DEVICE_PATH; 292 #pragma pack () 293 294 typedef struct { 295 UINT32 Signature; 296 EFI_EXT_SCSI_PASS_THRU_MODE ExtScsiPassThruMode; 297 EFI_EXT_SCSI_PASS_THRU_PROTOCOL ExtScsiPassThru; 298 SAS_V1_TRANSPORT_DEVICE_PATH *DevicePath; 299 struct hisi_hba *hba; 300 EFI_EVENT TimerEvent; 301 } SAS_V1_INFO; 302 303 #define SAS_DEVICE_SIGNATURE SIGNATURE_32 ('S','A','S','0') 304 #define SAS_FROM_PASS_THRU(a) CR (a, SAS_V1_INFO, ExtScsiPassThru, SAS_DEVICE_SIGNATURE) 305 306 STATIC EFI_STATUS prepare_cmd ( 307 struct hisi_hba *hba, 308 EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet 309 ) 310 { 311 struct hisi_sas_slot *slot; 312 struct hisi_sas_cmd_hdr *hdr; 313 struct hisi_sas_sge_page *sge; 314 struct hisi_sas_sts *sts; 315 struct hisi_sas_cmd *cmd; 316 EFI_SCSI_SENSE_DATA *SensePtr = Packet->SenseData; 317 VOID *Buffer = NULL; 318 UINTN BufferSize = 0; 319 int queue = hba->queue; 320 UINT32 r, w = 0, slot_idx = 0; 321 UINT32 base = hba->base; 322 UINT8 *p; 323 EFI_PHYSICAL_ADDRESS BufferAddress; 324 EFI_STATUS Status = EFI_SUCCESS; 325 VOID *BufferMap = NULL; 326 DMA_MAP_OPERATION DmaOperation = MapOperationBusMasterCommonBuffer; 327 328 while (1) { 329 w = READ_REG32(base, DLVRY_Q_0_WR_PTR + (queue * 0x14)); 330 r = READ_REG32(base, DLVRY_Q_0_RD_PTR + (queue * 0x14)); 331 slot_idx = queue * QUEUE_SLOTS + w; 332 slot = &hba->slots[slot_idx]; 333 if (slot->used || (r == (w+1) % QUEUE_SLOTS)) { 334 queue = (queue + 1) % QUEUE_CNT; 335 if (queue == hba->queue) { 336 DEBUG ((EFI_D_ERROR, "could not find free slot\n")); 337 return EFI_NOT_READY; 338 } 339 continue; 340 } 341 break; 342 } 343 344 hdr = &hba->cmd_hdr[queue][w]; 345 cmd = &hba->command_table[queue][w]; 346 sts = &hba->status_buf[queue][w]; 347 sge = &hba->sge[queue][w]; 348 349 ZeroMem (cmd, sizeof (struct hisi_sas_cmd)); 350 ZeroMem (sts, sizeof (struct hisi_sas_sts)); 351 if (SensePtr) 352 ZeroMem (SensePtr, sizeof (EFI_SCSI_SENSE_DATA)); 353 354 slot->used = TRUE; 355 hba->queue = (queue + 1) % QUEUE_CNT; 356 357 // Only consider ssp 358 hdr->dw0 = (1 << CMD_HDR_RESP_REPORT_OFF) | 359 (0x2 << CMD_HDR_TLR_CTRL_OFF) | 360 (hba->port_id << CMD_HDR_PORT_OFF) | 361 (1 << CMD_HDR_MODE_OFF) | 362 (1 << CMD_HDR_CMD_OFF); 363 hdr->dw1 = 1 << CMD_HDR_VERIFY_DTL_OFF; 364 hdr->dw1 |= 0 << CMD_HDR_DEVICE_ID_OFF; 365 hdr->dw2 = 0x83000d; 366 hdr->transfer_tags = slot_idx << CMD_HDR_IPTT_OFF; 367 368 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) { 369 Buffer = Packet->InDataBuffer; 370 BufferSize = Packet->InTransferLength; 371 if (Buffer) { 372 hdr->dw1 |= 1 << CMD_HDR_SSP_FRAME_TYPE_OFF; 373 DmaOperation = MapOperationBusMasterWrite; 374 } 375 } else if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE) { 376 Buffer = Packet->OutDataBuffer; 377 BufferSize = Packet->OutTransferLength; 378 if (Buffer) { 379 DmaOperation = MapOperationBusMasterRead; 380 hdr->dw1 |= 2 << CMD_HDR_SSP_FRAME_TYPE_OFF; 381 } 382 } else { 383 hdr->dw1 |= 0 << CMD_HDR_SSP_FRAME_TYPE_OFF; 384 } 385 386 hdr->data_transfer_len = BufferSize; 387 hdr->cmd_table_addr = (UINT64)cmd; 388 hdr->sts_buffer_addr = (UINT64)sts; 389 390 CopyMem (&cmd->cmd[36], Packet->Cdb, Packet->CdbLength); 391 392 if (Buffer != NULL) { 393 struct hisi_sas_sge *sg; 394 UINT32 remain, len, pos = 0, i = 0; 395 396 Status = DmaMap (DmaOperation, Buffer, &BufferSize, &BufferAddress, &BufferMap); 397 if (EFI_ERROR (Status)) { 398 return Status; 399 } 400 remain = len = BufferSize; 401 402 while (remain) { 403 if (len > SGE_LIMIT) 404 len = SGE_LIMIT; 405 sg = &sge->sg[i]; 406 sg->addr = (UINT64)(BufferAddress + pos); 407 sg->page_ctrl_0 = sg->page_ctrl_1 = 0; 408 sg->data_len = len; 409 sg->data_off = 0; 410 remain -= len; 411 pos += len; 412 len = remain; 413 i++; 414 } 415 416 hdr->prd_table_addr = (UINT64)sge; 417 hdr->sg_len = i << CMD_HDR_DATA_SGL_LEN_OFF; 418 } 419 420 // Ensure descriptor effective before start dma 421 MemoryFence(); 422 423 // Start dma 424 WRITE_REG32(base, DLVRY_Q_0_WR_PTR + queue * 0x14, ++w % QUEUE_SLOTS); 425 426 // Wait for dma complete 427 while (slot->used) { 428 if (READ_REG32(base, OQ_INT_SRC) & BIT(queue)) { 429 struct hisi_sas_complete_hdr *complete_hdr; 430 UINT32 data, rd; 431 rd = READ_REG32(base, COMPL_Q_0_RD_PTR + (0x14 * queue)); 432 433 complete_hdr = &hba->complete_hdr[queue][rd]; 434 data = complete_hdr->data; 435 436 // Check whether dma transfer error 437 if ((data & CMPLT_HDR_ERR_RCRD_XFRD_MSK) && 438 !(data & CMPLT_HDR_RSPNS_XFRD_MSK)) { 439 DEBUG ((EFI_D_VERBOSE, "sas retry data=0x%x\n", data)); 440 DEBUG ((EFI_D_VERBOSE, "sts[0]=0x%x\n", sts->status[0])); 441 DEBUG ((EFI_D_VERBOSE, "sts[1]=0x%x\n", sts->status[1])); 442 DEBUG ((EFI_D_VERBOSE, "sts[2]=0x%x\n", sts->status[2])); 443 Status = EFI_NOT_READY; 444 // wait 1 second and retry, some disk need long time to be ready 445 // and ScsiDisk treat retry over 3 times as error 446 MicroSecondDelay(1000000); 447 } 448 // Update read point 449 WRITE_REG32(base, COMPL_Q_0_RD_PTR + (0x14 * queue), w); 450 // Clear int 451 WRITE_REG32(base, OQ_INT_SRC, BIT(queue)); 452 slot->used = FALSE; 453 break; 454 } 455 // Wait for status change in polling 456 NanoSecondDelay (100); 457 } 458 459 if (BufferMap) 460 DmaUnmap (BufferMap); 461 462 p = (UINT8 *)&sts->status[0]; 463 if (p[SENSE_DATA_PRES]) { 464 // Disk not ready normal return for ScsiDiskTestUnitReady do next try 465 SensePtr->Sense_Key = EFI_SCSI_SK_NOT_READY; 466 SensePtr->Addnl_Sense_Code = EFI_SCSI_ASC_NOT_READY; 467 SensePtr->Addnl_Sense_Code_Qualifier = EFI_SCSI_ASCQ_IN_PROGRESS; 468 // wait 1 second for disk spin up, refer drivers/scsi/sd.c 469 MicroSecondDelay(1000000); 470 } 471 return Status; 472 } 473 474 STATIC VOID hisi_sas_v1_init(struct hisi_hba *hba, PLATFORM_SAS_PROTOCOL *plat) 475 { 476 int i, j; 477 UINT32 val, base = hba->base; 478 479 // Reset 480 for (i = 0; i < PHY_CNT; i++) { 481 UINT32 phy_ctrl = PHY_READ_REG32(base, PHY_CTRL, i); 482 483 phy_ctrl |= PHY_CTRL_RESET; 484 PHY_WRITE_REG32(base, PHY_CTRL, i, phy_ctrl); 485 } 486 // spec says safe to wait 50us after reset 487 MicroSecondDelay(50); 488 489 // Ensure DMA tx & rx idle 490 for (i = 0; i < PHY_CNT; i++) { 491 UINT32 dma_tx_status, dma_rx_status; 492 493 for (j = 0; j < 100; j++) { 494 dma_tx_status = PHY_READ_REG32(base, DMA_TX_STATUS, i); 495 dma_rx_status = PHY_READ_REG32(base, DMA_RX_STATUS, i); 496 497 if (!(dma_tx_status & DMA_TX_STATUS_BUSY) && 498 !(dma_rx_status & DMA_RX_STATUS_BUSY)) 499 break; 500 501 // Wait for status change in polling 502 NanoSecondDelay (100); 503 } 504 } 505 506 // Ensure axi bus idle 507 for (j = 0; j < 100; j++) { 508 UINT32 axi_status = READ_REG32(base, AXI_CFG); 509 if (axi_status == 0) 510 break; 511 512 // Wait for status change in polling 513 NanoSecondDelay (100); 514 } 515 516 plat->Init(plat); 517 518 WRITE_REG32(base, DLVRY_QUEUE_ENABLE, 0xffffffff); 519 WRITE_REG32(base, HGC_TRANS_TASK_CNT_LIMIT, 0x11); 520 WRITE_REG32(base, DEVICE_MSG_WORK_MODE, 0x1); 521 WRITE_REG32(base, HGC_SAS_TXFAIL_RETRY_CTRL, 0x1ff); 522 WRITE_REG32(base, HGC_ERR_STAT_EN, 0x401); 523 WRITE_REG32(base, CFG_1US_TIMER_TRSH, 0x64); 524 WRITE_REG32(base, HGC_GET_ITV_TIME, 0x1); 525 WRITE_REG32(base, I_T_NEXUS_LOSS_TIME, 0x64); 526 WRITE_REG32(base, BUS_INACTIVE_LIMIT_TIME, 0x2710); 527 WRITE_REG32(base, REJECT_TO_OPEN_LIMIT_TIME, 0x1); 528 WRITE_REG32(base, CFG_AGING_TIME, 0x7a12); 529 WRITE_REG32(base, HGC_DFX_CFG2, 0x9c40); 530 WRITE_REG32(base, FIS_LIST_BADDR_L, 0x2); 531 WRITE_REG32(base, INT_COAL_EN, 0xc); 532 WRITE_REG32(base, OQ_INT_COAL_TIME, 0x186a0); 533 WRITE_REG32(base, OQ_INT_COAL_CNT, 1); 534 WRITE_REG32(base, ENT_INT_COAL_TIME, 0x1); 535 WRITE_REG32(base, ENT_INT_COAL_CNT, 0x1); 536 WRITE_REG32(base, OQ_INT_SRC, 0xffffffff); 537 WRITE_REG32(base, ENT_INT_SRC1, 0xffffffff); 538 WRITE_REG32(base, ENT_INT_SRC_MSK1, 0); 539 WRITE_REG32(base, ENT_INT_SRC2, 0xffffffff); 540 WRITE_REG32(base, ENT_INT_SRC_MSK2, 0); 541 WRITE_REG32(base, SAS_ECC_INTR_MSK, 0); 542 WRITE_REG32(base, AXI_AHB_CLK_CFG, 0x2); 543 WRITE_REG32(base, CFG_SAS_CONFIG, 0x22000000); 544 545 for (i = 0; i < PHY_CNT; i++) { 546 PHY_WRITE_REG32(base, PROG_PHY_LINK_RATE, i, 0x88a); 547 PHY_WRITE_REG32(base, PHY_CONFIG2, i, 0x7c080); 548 PHY_WRITE_REG32(base, PHY_RATE_NEGO, i, 0x415ee00); 549 PHY_WRITE_REG32(base, PHY_PCN, i, 0x80a80000); 550 PHY_WRITE_REG32(base, SL_TOUT_CFG, i, 0x7d7d7d7d); 551 PHY_WRITE_REG32(base, DONE_RECEIVED_TIME, i, 0x0); 552 PHY_WRITE_REG32(base, RXOP_CHECK_CFG_H, i, 0x1000); 553 PHY_WRITE_REG32(base, DONE_RECEIVED_TIME, i, 0); 554 PHY_WRITE_REG32(base, CON_CFG_DRIVER, i, 0x13f0a); 555 PHY_WRITE_REG32(base, CHL_INT_COAL_EN, i, 3); 556 PHY_WRITE_REG32(base, DONE_RECEIVED_TIME, i, 8); 557 } 558 559 for (i = 0; i < QUEUE_CNT; i++) { 560 WRITE_REG32(base, DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14), upper_32_bits((UINT64)(hba->cmd_hdr[i]))); 561 WRITE_REG32(base, DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14), lower_32_bits((UINT64)(hba->cmd_hdr[i]))); 562 WRITE_REG32(base, DLVRY_Q_0_DEPTH + (i * 0x14), QUEUE_SLOTS); 563 564 WRITE_REG32(base, COMPL_Q_0_BASE_ADDR_HI + (i * 0x14), upper_32_bits((UINT64)(hba->complete_hdr[i]))); 565 WRITE_REG32(base, COMPL_Q_0_BASE_ADDR_LO + (i * 0x14), lower_32_bits((UINT64)(hba->complete_hdr[i]))); 566 WRITE_REG32(base, COMPL_Q_0_DEPTH + (i * 0x14), QUEUE_SLOTS); 567 } 568 569 WRITE_REG32(base, ITCT_BASE_ADDR_LO, lower_32_bits((UINT64)(hba->itct))); 570 WRITE_REG32(base, ITCT_BASE_ADDR_HI, upper_32_bits((UINT64)(hba->itct))); 571 572 WRITE_REG32(base, IOST_BASE_ADDR_LO, lower_32_bits((UINT64)(hba->iost))); 573 WRITE_REG32(base, IOST_BASE_ADDR_HI, upper_32_bits((UINT64)(hba->iost))); 574 575 WRITE_REG32(base, BROKEN_MSG_ADDR_LO, lower_32_bits((UINT64)(hba->breakpoint))); 576 WRITE_REG32(base, BROKEN_MSG_ADDR_HI, upper_32_bits((UINT64)(hba->breakpoint))); 577 578 for (i = 0; i < PHY_CNT; i++) { 579 // Clear interrupt status 580 val = PHY_READ_REG32(base, CHL_INT0, i); 581 PHY_WRITE_REG32(base, CHL_INT0, i, val); 582 val = PHY_READ_REG32(base, CHL_INT1, i); 583 PHY_WRITE_REG32(base, CHL_INT1, i, val); 584 val = PHY_READ_REG32(base, CHL_INT2, i); 585 PHY_WRITE_REG32(base, CHL_INT2, i, val); 586 587 // Bypass chip bug mask abnormal intr 588 PHY_WRITE_REG32(base, CHL_INT0_MSK, i, 0x3fffff & ~CHL_INT0_MSK_PHYCTRL_NOTRDY); 589 } 590 591 // Init phy 592 for (i = 0; i < PHY_CNT; i++) { 593 PHY_WRITE_REG32(base, TX_ID_DWORD0, i, 0x10010e00); 594 PHY_WRITE_REG32(base, TX_ID_DWORD1, i, 0x16); 595 PHY_WRITE_REG32(base, TX_ID_DWORD2, i, 0x20880150); 596 PHY_WRITE_REG32(base, TX_ID_DWORD3, i, 0x16); 597 PHY_WRITE_REG32(base, TX_ID_DWORD4, i, 0x20880150); 598 PHY_WRITE_REG32(base, TX_ID_DWORD5, i, 0x0); 599 600 val = PHY_READ_REG32(base, PHY_CFG, i); 601 val &= ~PHY_CFG_DC_OPT_MSK; 602 val |= 1 << PHY_CFG_DC_OPT_OFF; 603 PHY_WRITE_REG32(base, PHY_CFG, i, val); 604 605 val = PHY_READ_REG32(base, PHY_CONFIG2, i); 606 val &= ~PHY_CONFIG2_FORCE_TXDEEMPH_MSK; 607 PHY_WRITE_REG32(base, PHY_CONFIG2, i, val); 608 609 val = PHY_READ_REG32(base, PHY_CFG, i); 610 val |= PHY_CFG_ENA_MSK; 611 PHY_WRITE_REG32(base, PHY_CFG, i, val); 612 } 613 } 614 615 STATIC VOID sas_init(SAS_V1_INFO *SasV1Info, PLATFORM_SAS_PROTOCOL *plat) 616 { 617 struct hisi_hba *hba = SasV1Info->hba; 618 int i, s; 619 620 for (i = 0; i < QUEUE_CNT; i++) { 621 s = sizeof(struct hisi_sas_cmd_hdr) * QUEUE_SLOTS; 622 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->cmd_hdr[i]); 623 ASSERT (hba->cmd_hdr[i] != NULL); 624 ZeroMem (hba->cmd_hdr[i], s); 625 626 s = sizeof(struct hisi_sas_complete_hdr) * QUEUE_SLOTS; 627 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->complete_hdr[i]); 628 ASSERT (hba->complete_hdr[i] != NULL); 629 ZeroMem (hba->complete_hdr[i], s); 630 631 s = sizeof(struct hisi_sas_sts) * QUEUE_SLOTS; 632 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->status_buf[i]); 633 ASSERT (hba->status_buf[i] != NULL); 634 ZeroMem (hba->status_buf[i], s); 635 636 s = sizeof(struct hisi_sas_cmd) * QUEUE_SLOTS; 637 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->command_table[i]); 638 ASSERT (hba->command_table[i] != NULL); 639 ZeroMem (hba->command_table[i], s); 640 641 s = sizeof(struct hisi_sas_sge_page) * QUEUE_SLOTS; 642 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->sge[i]); 643 ASSERT (hba->sge[i] != NULL); 644 ZeroMem (hba->sge[i], s); 645 } 646 647 s = SLOT_ENTRIES * sizeof(struct hisi_sas_iost); 648 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->iost); 649 ASSERT (hba->iost != NULL); 650 ZeroMem (hba->iost, s); 651 652 s = SLOT_ENTRIES * sizeof(struct hisi_sas_breakpoint); 653 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->breakpoint); 654 ASSERT (hba->breakpoint != NULL); 655 ZeroMem (hba->breakpoint, s); 656 657 s = MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); 658 DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->itct); 659 ASSERT (hba->itct != NULL); 660 ZeroMem (hba->itct, s); 661 662 hba->slots = AllocateZeroPool (SLOT_ENTRIES * sizeof(struct hisi_sas_slot)); 663 ASSERT (hba->slots != NULL); 664 665 hisi_sas_v1_init(hba, plat); 666 } 667 668 STATIC 669 EFI_STATUS 670 EFIAPI 671 SasV1ExtScsiPassThruFunction ( 672 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, 673 IN UINT8 *Target, 674 IN UINT64 Lun, 675 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, 676 IN EFI_EVENT Event OPTIONAL 677 ) 678 { 679 SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This); 680 struct hisi_hba *hba = SasV1Info->hba; 681 682 return prepare_cmd(hba, Packet); 683 } 684 685 STATIC 686 EFI_STATUS 687 EFIAPI 688 SasV1ExtScsiPassThruGetNextTargetLun ( 689 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, 690 IN OUT UINT8 **Target, 691 IN OUT UINT64 *Lun 692 ) 693 { 694 SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This); 695 struct hisi_hba *hba = SasV1Info->hba; 696 UINT8 ScsiId[TARGET_MAX_BYTES]; 697 UINT8 TargetId; 698 699 if (*Target == NULL || Lun == NULL) { 700 return EFI_INVALID_PARAMETER; 701 } 702 703 SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF); 704 705 TargetId = (*Target)[0]; 706 707 if (TargetId == MAX_TARGET_ID) { 708 return EFI_NOT_FOUND; 709 } 710 711 if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0) { 712 SetMem (*Target, TARGET_MAX_BYTES,0); 713 } else { 714 (*Target)[0] = (UINT8) (hba->LatestTargetId + 1); 715 } 716 717 *Lun = 0; 718 719 // 720 // Update the LatestTargetId. 721 // 722 hba->LatestTargetId = (*Target)[0]; 723 hba->LatestLun = *Lun; 724 725 return EFI_SUCCESS; 726 } 727 728 STATIC 729 EFI_STATUS 730 EFIAPI 731 SasV1ExtScsiPassThruBuildDevicePath ( 732 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, 733 IN UINT8 *Target, 734 IN UINT64 Lun, 735 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath 736 ) 737 { 738 SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This); 739 740 *DevicePath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)(SasV1Info->DevicePath)); 741 return EFI_SUCCESS; 742 } 743 744 STATIC 745 EFI_STATUS 746 EFIAPI 747 SasV1ExtScsiPassThruGetTargetLun ( 748 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, 749 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 750 OUT UINT8 **Target, 751 OUT UINT64 *Lun 752 ) 753 { 754 return EFI_UNSUPPORTED; 755 } 756 757 STATIC 758 EFI_STATUS 759 EFIAPI 760 SasV1ExtScsiPassThruResetChannel ( 761 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This 762 ) 763 { 764 765 return EFI_UNSUPPORTED; 766 } 767 768 STATIC 769 EFI_STATUS 770 EFIAPI 771 SasV1ExtScsiPassThruResetTarget ( 772 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, 773 IN UINT8 *Target, 774 IN UINT64 Lun 775 ) 776 { 777 778 return EFI_UNSUPPORTED; 779 } 780 781 STATIC 782 EFI_STATUS 783 EFIAPI 784 SasV1ExtScsiPassThruGetNextTarget ( 785 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, 786 IN OUT UINT8 **Target 787 ) 788 { 789 790 return EFI_UNSUPPORTED; 791 } 792 793 STATIC EFI_EXT_SCSI_PASS_THRU_PROTOCOL SasV1ExtScsiPassThruProtocolTemplate = { 794 NULL, 795 SasV1ExtScsiPassThruFunction, 796 SasV1ExtScsiPassThruGetNextTargetLun, 797 SasV1ExtScsiPassThruBuildDevicePath, 798 SasV1ExtScsiPassThruGetTargetLun, 799 SasV1ExtScsiPassThruResetChannel, 800 SasV1ExtScsiPassThruResetTarget, 801 SasV1ExtScsiPassThruGetNextTarget 802 }; 803 804 EFI_STATUS 805 EFIAPI 806 SasDriverBindingSupported ( 807 IN EFI_DRIVER_BINDING_PROTOCOL *This, 808 IN EFI_HANDLE Controller, 809 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 810 ) 811 { 812 PLATFORM_SAS_PROTOCOL *plat; 813 EFI_STATUS Status; 814 815 Status = gBS->OpenProtocol ( 816 Controller, 817 &gPlatformSasProtocolGuid, 818 (VOID **) &plat, 819 This->DriverBindingHandle, 820 Controller, 821 EFI_OPEN_PROTOCOL_BY_DRIVER 822 ); 823 if (Status == EFI_ALREADY_STARTED) { 824 return EFI_SUCCESS; 825 } 826 if (EFI_ERROR (Status)) { 827 return Status; 828 } 829 830 // 831 // Close the Sas Host used to perform the supported test 832 // 833 gBS->CloseProtocol ( 834 Controller, 835 &gPlatformSasProtocolGuid, 836 This->DriverBindingHandle, 837 Controller 838 ); 839 840 return EFI_SUCCESS; 841 } 842 843 EFI_STATUS 844 EFIAPI 845 SasDriverBindingStart ( 846 IN EFI_DRIVER_BINDING_PROTOCOL *This, 847 IN EFI_HANDLE Controller, 848 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 849 ) 850 { 851 EFI_STATUS Status; 852 PLATFORM_SAS_PROTOCOL *plat; 853 SAS_V1_INFO *SasV1Info = NULL; 854 SAS_V1_TRANSPORT_DEVICE_PATH *DevicePath; 855 UINT32 val, base; 856 int i, phy_id = 0; 857 struct hisi_sas_itct *itct; 858 struct hisi_hba *hba; 859 860 Status = gBS->OpenProtocol ( 861 Controller, 862 &gPlatformSasProtocolGuid, 863 (VOID **) &plat, 864 This->DriverBindingHandle, 865 Controller, 866 EFI_OPEN_PROTOCOL_BY_DRIVER 867 ); 868 869 if (EFI_ERROR (Status)) { 870 if (Status == EFI_ALREADY_STARTED) { 871 return EFI_SUCCESS; 872 } 873 return Status; 874 } 875 876 SasV1Info = AllocateZeroPool (sizeof (SAS_V1_INFO)); 877 ASSERT (SasV1Info); 878 SasV1Info->Signature = SAS_DEVICE_SIGNATURE; 879 880 SasV1Info->hba = AllocateZeroPool (sizeof(struct hisi_hba)); 881 ASSERT (SasV1Info->hba); 882 hba = SasV1Info->hba; 883 base = hba->base = plat->BaseAddr; 884 885 sas_init(SasV1Info, plat); 886 887 // Wait for sas controller phyup happen 888 MicroSecondDelay(100000); 889 890 for (i = 0; i < PHY_CNT; i++) { 891 val = PHY_READ_REG32(base, CHL_INT2, i); 892 893 if (val & CHL_INT2_SL_PHY_ENA) { 894 phy_id = i; 895 } 896 } 897 898 itct = &hba->itct[0]; //device_id = 0 899 900 hba->port_id = (READ_REG32(base, PHY_PORT_NUM_MA) >> (4 * phy_id)) & 0xf; 901 // Setup itct 902 itct->qw0 = 0x355; 903 itct->sas_addr = PHY_READ_REG32(base, RX_IDAF_DWORD3, phy_id); 904 itct->sas_addr = itct->sas_addr << 32 | PHY_READ_REG32(base, RX_IDAF_DWORD4, phy_id); 905 itct->qw2 = 0; 906 907 // Clear phyup 908 PHY_WRITE_REG32(base, CHL_INT2, phy_id, CHL_INT2_SL_PHY_ENA); 909 val = PHY_READ_REG32(base, CHL_INT0, phy_id); 910 val &= ~CHL_INT0_PHYCTRL_NOTRDY; 911 PHY_WRITE_REG32(base, CHL_INT0, phy_id, val); 912 PHY_WRITE_REG32(base, CHL_INT0_MSK, phy_id, 0x3ce3ee); 913 914 // Need notify 915 val = PHY_READ_REG32(base, SL_CONTROL, phy_id); 916 val |= SL_CONTROL_NOTIFY_EN; 917 PHY_WRITE_REG32(base, SL_CONTROL, phy_id, val); 918 // wait 100ms required for notify takes effect, refer drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 919 MicroSecondDelay(100000); 920 val = PHY_READ_REG32(base, SL_CONTROL, phy_id); 921 val &= ~SL_CONTROL_NOTIFY_EN; 922 PHY_WRITE_REG32(base, SL_CONTROL, phy_id, val); 923 924 CopyMem (&SasV1Info->ExtScsiPassThru, &SasV1ExtScsiPassThruProtocolTemplate, sizeof (EFI_EXT_SCSI_PASS_THRU_PROTOCOL)); 925 SasV1Info->ExtScsiPassThruMode.AdapterId = 2; 926 SasV1Info->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL; 927 SasV1Info->ExtScsiPassThruMode.IoAlign = 64; //cache line align 928 SasV1Info->ExtScsiPassThru.Mode = &SasV1Info->ExtScsiPassThruMode; 929 930 DevicePath = (SAS_V1_TRANSPORT_DEVICE_PATH *)CreateDeviceNode ( 931 HARDWARE_DEVICE_PATH, 932 HW_VENDOR_DP, 933 sizeof (SAS_V1_TRANSPORT_DEVICE_PATH)); 934 ASSERT (DevicePath != NULL); 935 SasV1Info->DevicePath = DevicePath; 936 937 CopyMem (&DevicePath->Vendor.Guid, &gPlatformSasProtocolGuid, sizeof (EFI_GUID)); 938 DevicePath->PhysBase = base; 939 SetDevicePathNodeLength (&DevicePath->Vendor, 940 sizeof (*DevicePath) - sizeof (DevicePath->End)); 941 SetDevicePathEndNode (&DevicePath->End); 942 943 Status = gBS->InstallMultipleProtocolInterfaces ( 944 &Controller, 945 &gEfiDevicePathProtocolGuid, DevicePath, 946 &gEfiExtScsiPassThruProtocolGuid, &SasV1Info->ExtScsiPassThru, 947 NULL); 948 ASSERT_EFI_ERROR (Status); 949 950 return EFI_SUCCESS; 951 } 952 953 EFI_STATUS 954 EFIAPI 955 SasDriverBindingStop ( 956 IN EFI_DRIVER_BINDING_PROTOCOL *This, 957 IN EFI_HANDLE Controller, 958 IN UINTN NumberOfChildren, 959 IN EFI_HANDLE *ChildHandleBuffer 960 ) 961 { 962 SAS_V1_INFO *SasV1Info; 963 EFI_STATUS Status; 964 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsi; 965 int i, s; 966 967 Status = gBS->OpenProtocol ( 968 Controller, 969 &gEfiExtScsiPassThruProtocolGuid, 970 (VOID **) &ExtScsi, 971 This->DriverBindingHandle, 972 Controller, 973 EFI_OPEN_PROTOCOL_GET_PROTOCOL 974 ); 975 if (EFI_ERROR (Status)) { 976 return Status; 977 } 978 979 SasV1Info = SAS_FROM_PASS_THRU(ExtScsi); 980 981 Status = gBS->UninstallMultipleProtocolInterfaces ( 982 Controller, 983 &gEfiDevicePathProtocolGuid, 984 SasV1Info->DevicePath, 985 &gEfiExtScsiPassThruProtocolGuid, 986 &SasV1Info->ExtScsiPassThru, 987 NULL); 988 if (!EFI_ERROR (Status)) { 989 gBS->CloseProtocol ( 990 Controller, 991 &gPlatformSasProtocolGuid, 992 This->DriverBindingHandle, 993 Controller 994 ); 995 996 gBS->CloseEvent (SasV1Info->TimerEvent); 997 998 for (i = 0; i < QUEUE_CNT; i++) { 999 s = sizeof(struct hisi_sas_cmd_hdr) * QUEUE_SLOTS; 1000 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->cmd_hdr[i]); 1001 s = sizeof(struct hisi_sas_complete_hdr) * QUEUE_SLOTS; 1002 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->complete_hdr[i]); 1003 s = sizeof(struct hisi_sas_sts) * QUEUE_SLOTS; 1004 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->status_buf[i]); 1005 s = sizeof(struct hisi_sas_cmd) * QUEUE_SLOTS; 1006 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->command_table[i]); 1007 s = sizeof(struct hisi_sas_sge_page) * QUEUE_SLOTS; 1008 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->sge[i]); 1009 } 1010 1011 s = SLOT_ENTRIES * sizeof(struct hisi_sas_iost); 1012 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->iost); 1013 s = SLOT_ENTRIES * sizeof(struct hisi_sas_breakpoint); 1014 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->breakpoint); 1015 s = MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); 1016 DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->itct); 1017 1018 FreePool (SasV1Info->hba->slots); 1019 FreePool (SasV1Info->hba); 1020 FreePool (SasV1Info); 1021 return EFI_SUCCESS; 1022 } 1023 return Status; 1024 } 1025 1026 EFI_DRIVER_BINDING_PROTOCOL gSasDriverBinding = { 1027 SasDriverBindingSupported, 1028 SasDriverBindingStart, 1029 SasDriverBindingStop, 1030 0xa, 1031 NULL, 1032 NULL 1033 }; 1034 1035 EFI_STATUS 1036 SasV1Initialize ( 1037 IN EFI_HANDLE ImageHandle, 1038 IN EFI_SYSTEM_TABLE *SystemTable 1039 ) 1040 { 1041 return EfiLibInstallDriverBindingComponentName2 ( 1042 ImageHandle, 1043 SystemTable, 1044 &gSasDriverBinding, 1045 ImageHandle, 1046 NULL, 1047 NULL 1048 ); 1049 } 1050