From nobody Sat Sep 9 07:31:02 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RjPm64dJjz4t4Cj; Sat, 9 Sep 2023 07:31:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RjPm6424Dz3YBH; Sat, 9 Sep 2023 07:31:02 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1694244662; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=nLxrRcT6+wpFkqZ53BUBIz11V7oB4k0MKHX/u6ZHD4o=; b=TKMYISSItq6h7MVKr1az5vcSs6ZE/mZtg9gEgkjubM3RBOqDaWn04b2+uGCurfBXGr3nrY rsaFnn7rv5dndrBEOoKzrh3ponxnHDBIH1Ix84ML//k064AfXQRaG1alHZkZAmF0Jrzmxr 9S6nF3CMbbrn8hBY0Ktk4k0H4TZdZExGRms8Lv2TdIIr75/Faz11rIcu6FNxKbh+a2Phdv hJ2wubtyzZ1smsFLK3JTCeQW4bDFy/oFzyIkpdkFaTFLIbr0w/NyPBbTVgU6v7wcYsICFB 65Qo1wplBhezfRSX7hjC/E8rytqXMd3nB4TnL5mN710jz76knPFmsd0qd4SkcQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1694244662; a=rsa-sha256; cv=none; b=lA/dFSWfmuCmRaa75Em4S34eHOQyVDO0QqOC43sgzCYaixtQSwaPYt3Q+ErQVEGFJ/r77I JhiZPAdOnDrfE146FSp8GEbUl4FeBG8BCM0wWVufmLDvywkrey4YSUOrfgfQKz/VUB0TD8 P4XnJB5MLNPYTbHOh1wDUoSzBXgMLDOCAW2Go/bz2dOyrrPjTb8nBHdxYqXyCy5FSQg33X ACjUcKB5fAj71c5y5y3vMkUTY3YytXnYrjRFRvfsUct7v8frf2BRKjtRqENtX9ps6DqCDx CVjr1Ewbwc8xFKHTzJySTmVPHfCriL3O/pPR/358nUrgAQpdCzQYZz72wxwBew== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1694244662; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=nLxrRcT6+wpFkqZ53BUBIz11V7oB4k0MKHX/u6ZHD4o=; b=LziYEzRYxJl0+WmfPGuH8XHk/ucNyawYXQ8FZWDErTCETHrUv8uXi50DxsAYxXp+Z5WjFL S6g86rJqxUpHxJdPha0W3uEqNuH2fWGoGdZo04bvMDMgbN+qOMD/Vi/OC6x9/quqneTXfm 3ibkzJHqSKYk6/x7rDDIpyPpfH3l0ahra/WGfLD4s8wIkp5tpvMkheVjuU9l90tBAy1XVt qOJjiEj7UZ4zyYxX8cvL6Fmf5zSe7QZFNRkyB/VfxMBqX3zA8T1WyELUjospvPU0Z9E7o8 g5iQ8j0LJvYdLiV0U27o/CQhD/YvR9r9FsJob4wfo10BTirEpIhsVrzGrifscg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RjPm61GFCz1C4; Sat, 9 Sep 2023 07:31:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3897V2dk061860; Sat, 9 Sep 2023 07:31:02 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3897V2B2061857; Sat, 9 Sep 2023 07:31:02 GMT (envelope-from git) Date: Sat, 9 Sep 2023 07:31:02 GMT Message-Id: <202309090731.3897V2B2061857@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Xin LI Subject: git: c92758cfd8ce - releng/14.0 - sys/dev/arcmsr: Update Areca RAID driver to version 1.50.00.06. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: delphij X-Git-Repository: src X-Git-Refname: refs/heads/releng/14.0 X-Git-Reftype: branch X-Git-Commit: c92758cfd8cecd542269b6ae6622b3efad8f66a7 Auto-Submitted: auto-generated The branch releng/14.0 has been updated by delphij: URL: https://cgit.FreeBSD.org/src/commit/?id=c92758cfd8cecd542269b6ae6622b3efad8f66a7 commit c92758cfd8cecd542269b6ae6622b3efad8f66a7 Author: 黃清隆 AuthorDate: 2023-09-06 07:59:22 +0000 Commit: Xin LI CommitDate: 2023-09-09 07:30:39 +0000 sys/dev/arcmsr: Update Areca RAID driver to version 1.50.00.06. - Suppressed a harmless warning message, "arcmsr_dr_handle: target=f, lun=0, GONE!!!," which could appear a few seconds after UEFI system boot due to the boot volume UEFI initialization. - Corrected various typing errors. - Refactored arcmsr_initialize() to improve code readability. - Added support for device IDs 1883 and 1886 controllers. - Introduced support for controllers requiring host memory for the RAID 5 and 6 XOR engines. Many thanks to Areca for continuing to support FreeBSD. Approved by: re (gjb) (cherry picked from commit cb1a0aab4f3ca169509ab86a67a4630e72790869) (cherry picked from commit 72a9f518d5973bb1cd371cff8ee4e3f24c410e42) --- sys/dev/arcmsr/arcmsr.c | 693 ++++++++++++++++++++++++++++++++---------------- sys/dev/arcmsr/arcmsr.h | 51 +++- 2 files changed, 507 insertions(+), 237 deletions(-) diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index b43e9b8b3813..bbb1b6a9b53f 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -88,6 +88,8 @@ ** 1.50.00.03 05/04/2021 Ching Huang Fixed doorbell status arrived late on ARC-1886 ** 1.50.00.04 12/08/2021 Ching Huang Fixed boot up hung under ARC-1886 with no volume created ** 1.50.00.05 03/23/2023 Ching Huang Fixed reading buffer empty length error +** 1.50.00.06 08/07/2023 Ching Huang Add support adapter using system memory as XOR buffer, +** Add support device ID 1883,1886 ****************************************************************************************** */ @@ -143,7 +145,7 @@ #define arcmsr_callout_init(a) callout_init(a, /*mpsafe*/1); -#define ARCMSR_DRIVER_VERSION "arcmsr version 1.50.00.05 2023-03-23" +#define ARCMSR_DRIVER_VERSION "arcmsr version 1.50.00.06 2023-08-07" #include /* ************************************************************************** @@ -1071,7 +1073,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb, */ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb) { - u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr_low; + u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr; struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb; bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD); @@ -1131,10 +1133,10 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr ARCMSR_LOCK_ACQUIRE(&acb->postDone_lock); postq_index = phbdmu->postq_index; pinbound_srb = (struct InBound_SRB *)&phbdmu->post_qbuffer[postq_index & 0xFF]; - pinbound_srb->addressHigh = srb->cdb_phyaddr_high; - pinbound_srb->addressLow = srb->cdb_phyaddr_low; + pinbound_srb->addressHigh = (u_int32_t)((srb->cdb_phyaddr >> 16) >> 16); + pinbound_srb->addressLow = (u_int32_t)srb->cdb_phyaddr; pinbound_srb->length = srb->arc_cdb_size >> 2; - arcmsr_cdb->Context = srb->cdb_phyaddr_low; + arcmsr_cdb->Context = (u_int32_t)srb->cdb_phyaddr; if (postq_index & 0x4000) { index_stripped = postq_index & 0xFF; index_stripped += 1; @@ -1742,7 +1744,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); for (target = 0; target < 4; target++) { - deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); + deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); devicemap += 4; } break; @@ -1751,7 +1753,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); for (target = 0; target < 4; target++) { - deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap); + deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap); devicemap += 4; } break; @@ -1760,7 +1762,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); for (target = 0; target < 4; target++) { - deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); + deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); devicemap += 4; } break; @@ -1768,7 +1770,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); for (target = 0; target < 4; target++) { - deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); + deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); devicemap += 4; } break; @@ -1776,7 +1778,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { devicemap = offsetof(struct HBE_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); for (target = 0; target < 4; target++) { - deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); + deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); devicemap += 4; } break; @@ -1813,14 +1815,15 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { { if(acb->device_map[target] & bit_check) {/* unit departed */ - printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun); + if (target != 0x0f) + printf("arcmsr_dr_handle: Target=0x%x, lun=%x, GONE!!!\n",target,lun); arcmsr_abort_dr_ccbs(acb, target, lun); arcmsr_rescan_lun(acb, target, lun); acb->devstate[target][lun] = ARECA_RAID_GONE; } else {/* unit arrived */ - printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun); + printf("arcmsr_dr_handle: Target=0x%x, lun=%x, Plug-IN!!!\n",target,lun); arcmsr_rescan_lun(acb, target, lun); acb->devstate[target][lun] = ARECA_RAID_GOOD; } @@ -3170,7 +3173,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) return; } - if(target == 16) { + if(target == ARCMSR_VIRTUAL_DEVICE_ID) { /* virtual device for iop message transfer */ arcmsr_handle_virtual_command(acb, pccb); return; @@ -3216,7 +3219,9 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) else cpi->base_transfer_speed = 300000; if((acb->vendor_device_id == PCIDevVenIDARC1880) || + (acb->vendor_device_id == PCIDevVenIDARC1883) || (acb->vendor_device_id == PCIDevVenIDARC1884) || + (acb->vendor_device_id == PCIDevVenIDARC1886) || (acb->vendor_device_id == PCIDevVenIDARC1680) || (acb->vendor_device_id == PCIDevVenIDARC1214)) { @@ -3282,7 +3287,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) case XPT_GET_TRAN_SETTINGS: { struct ccb_trans_settings *cts; - if(pccb->ccb_h.target_id == 16) { + if(pccb->ccb_h.target_id == ARCMSR_VIRTUAL_DEVICE_ID) { pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL; xpt_done(pccb); break; @@ -3299,7 +3304,9 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) cts->protocol = PROTO_SCSI; if((acb->vendor_device_id == PCIDevVenIDARC1880) || + (acb->vendor_device_id == PCIDevVenIDARC1883) || (acb->vendor_device_id == PCIDevVenIDARC1884) || + (acb->vendor_device_id == PCIDevVenIDARC1886) || (acb->vendor_device_id == PCIDevVenIDARC1680) || (acb->vendor_device_id == PCIDevVenIDARC1214)) { @@ -3344,7 +3351,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) break; } case XPT_CALC_GEOMETRY: - if(pccb->ccb_h.target_id == 16) { + if(pccb->ccb_h.target_id == ARCMSR_VIRTUAL_DEVICE_ID) { pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL; xpt_done(pccb); break; @@ -4047,6 +4054,7 @@ static void arcmsr_get_hbf_config(struct AdapterControlBlock *acb) acb->firm_sdram_size = acb->msgcode_rwbuffer[3]; /*firm_sdram_size, 3, 12-15*/ acb->firm_ide_channels = acb->msgcode_rwbuffer[4]; /*firm_ide_channels, 4, 16-19*/ acb->firm_cfg_version = acb->msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]; /*firm_cfg_version, 25*/ + acb->firm_PicStatus = acb->msgcode_rwbuffer[ARCMSR_FW_PICSTATUS]; /* firm_PicStatus, 30 */ if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD) acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1; else @@ -4340,6 +4348,12 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) acb->msgcode_rwbuffer[5] = cdb_phyaddr_lo32; acb->msgcode_rwbuffer[6] = srb_phyaddr_hi32; acb->msgcode_rwbuffer[7] = COMPLETION_Q_POOL_SIZE; + if (acb->xor_mega) { + acb->msgcode_rwbuffer[8] = 0x555AA; //FreeBSD init 2 + acb->msgcode_rwbuffer[9] = 0; + acb->msgcode_rwbuffer[10] = (uint32_t)acb->xor_sgtable_phy; + acb->msgcode_rwbuffer[11] = (uint32_t)((acb->xor_sgtable_phy >> 16) >> 16); + } CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); @@ -4414,20 +4428,48 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) || (acb->adapter_type == ACB_ADAPTER_TYPE_E) || (acb->adapter_type == ACB_ADAPTER_TYPE_F)) { - srb_tmp->cdb_phyaddr_low = srb_phyaddr; - srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16); + srb_tmp->cdb_phyaddr = srb_phyaddr; } else - srb_tmp->cdb_phyaddr_low = srb_phyaddr >> 5; + srb_tmp->cdb_phyaddr = srb_phyaddr >> 5; srb_tmp->acb = acb; srb_tmp->smid = i << 16; acb->srbworkingQ[i] = acb->psrb_pool[i] = srb_tmp; srb_phyaddr = srb_phyaddr + SRB_SIZE; srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp + SRB_SIZE); } - if (acb->adapter_type == ACB_ADAPTER_TYPE_E) + srb_tmp = (struct CommandControlBlock *)(acb->uncacheptr + ARCMSR_SRBS_POOL_SIZE); + srb_phyaddr = (unsigned long)segs->ds_addr + ARCMSR_SRBS_POOL_SIZE; + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_B: { + struct HBB_MessageUnit *phbbmu; + + acb->pmu = (struct MessageUnit_UNION *)srb_tmp; + phbbmu = (struct HBB_MessageUnit *)acb->pmu; + phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)acb->mem_base0; + phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)acb->mem_base1; + if (acb->vendor_device_id == PCIDevVenIDARC1203) { + phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell); + phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask); + phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell); + phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask); + } else { + phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell); + phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask); + phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell); + phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask); + } + } + break; + case ACB_ADAPTER_TYPE_D: + acb->pmu = (struct MessageUnit_UNION *)srb_tmp; + acb->pmu->muu.hbdmu.phbdmu = (struct HBD_MessageUnit *)acb->mem_base0; + break; + case ACB_ADAPTER_TYPE_E: acb->pCompletionQ = (pCompletion_Q)srb_tmp; - else if (acb->adapter_type == ACB_ADAPTER_TYPE_F) { + break; + case ACB_ADAPTER_TYPE_F: { + unsigned long host_buffer_dma; acb->pCompletionQ = (pCompletion_Q)srb_tmp; acb->completeQ_phys = srb_phyaddr; memset(acb->pCompletionQ, 0xff, COMPLETION_Q_POOL_SIZE); @@ -4435,9 +4477,62 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in acb->message_rbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x100); acb->msgcode_rwbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x200); memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE); + arcmsr_wait_firmware_ready(acb); + host_buffer_dma = acb->completeQ_phys + COMPLETION_Q_POOL_SIZE; + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, (u_int32_t)(host_buffer_dma | 1)); /* host buffer low addr, bit0:1 all buffer active */ + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr1, (u_int32_t)((host_buffer_dma >> 16) >> 16));/* host buffer high addr */ + CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBFMU_DOORBELL_SYNC1); /* set host buffer physical address */ + acb->firm_PicStatus = CHIP_REG_READ32(HBF_MessageUnit, 0, outbound_msgaddr1); /* get firmware spec info */ + break; + } } acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr; } + +static void arcmsr_map_xor_sgtable(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct AdapterControlBlock *acb = arg; + + acb->xor_sgtable_phy = (unsigned long)segs->ds_addr; + if ((nseg != 1) || ((u_int32_t)segs->ds_len != acb->init2cfg_size)) { + acb->acb_flags |= ACB_F_MAPXOR_FAILD; + printf("arcmsr%d: alloc xor table seg num or size not as i wish!\n", acb->pci_unit); + return; + } +} + +static void arcmsr_map_xor_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct AdapterControlBlock *acb = arg; + int i; + struct HostRamBuf *pRamBuf; + struct XorSg *pxortable = (struct XorSg *)(acb->xortable + sizeof(struct HostRamBuf)); + + if (nseg != acb->xor_mega) { + acb->acb_flags |= ACB_F_MAPXOR_FAILD; + printf("arcmsr%d: alloc xor seg NUM not as i wish!\n", acb->pci_unit); + return; + } + for (i = 0; i < nseg; i++) { + if ((u_int32_t)segs->ds_len != ARCMSR_XOR_SEG_SIZE) { + acb->acb_flags |= ACB_F_MAPXOR_FAILD; + printf("arcmsr%d: alloc xor seg SIZE not as i wish!\n", acb->pci_unit); + return; + } + pxortable->xorPhys = (u_int64_t)segs->ds_addr; + pxortable->xorBufLen = (u_int64_t)segs->ds_len; + pxortable++; + segs++; + } + pRamBuf = (struct HostRamBuf *)acb->xortable; + pRamBuf->hrbSignature = 0x53425248; //HRBS + pRamBuf->hrbSize = ARCMSR_XOR_SEG_SIZE * nseg; + pRamBuf->hrbRes[0] = 0; + pRamBuf->hrbRes[1] = 0; + bus_dmamap_sync(acb->xortable_dmat, acb->xortable_dmamap, BUS_DMASYNC_PREREAD); + bus_dmamap_sync(acb->xor_dmat, acb->xor_dmamap, BUS_DMASYNC_PREWRITE); +} + /* ************************************************************************ ************************************************************************ @@ -4448,11 +4543,55 @@ static void arcmsr_free_resource(struct AdapterControlBlock *acb) if(acb->ioctl_dev != NULL) { destroy_dev(acb->ioctl_dev); } - bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap); - bus_dmamap_destroy(acb->srb_dmat, acb->srb_dmamap); - bus_dma_tag_destroy(acb->srb_dmat); - bus_dma_tag_destroy(acb->dm_segs_dmat); - bus_dma_tag_destroy(acb->parent_dmat); + if (acb->acb_flags & ACB_F_DMAMAP_SG) + bus_dmamap_unload(acb->xor_dmat, acb->xor_dmamap); + if (acb->xor_dmamap) { + bus_dmamem_free(acb->xor_dmat, acb->xorptr, acb->xor_dmamap); + } + if (acb->acb_flags & ACB_F_DMAMAP_SGTABLE) + bus_dmamap_unload(acb->xortable_dmat, acb->xortable_dmamap); + if (acb->xortable_dmamap) { + bus_dmamem_free(acb->xortable_dmat, acb->xortable, acb->xortable_dmamap); + } + if (acb->acb_flags & ACB_F_DMAMAP_SRB) + bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap); + if (acb->srb_dmamap) { + bus_dmamem_free(acb->srb_dmat, acb->uncacheptr, acb->srb_dmamap); + } + if (acb->srb_dmat) + bus_dma_tag_destroy(acb->srb_dmat); + if (acb->dm_segs_dmat) + bus_dma_tag_destroy(acb->dm_segs_dmat); + if (acb->parent_dmat) + bus_dma_tag_destroy(acb->parent_dmat); + switch(acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: + if (acb->sys_res_arcmsr[0]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]); + break; + case ACB_ADAPTER_TYPE_B: + if (acb->sys_res_arcmsr[0]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]); + if (acb->sys_res_arcmsr[1]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(2), acb->sys_res_arcmsr[1]); + break; + case ACB_ADAPTER_TYPE_C: + if (acb->sys_res_arcmsr[0]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(1), acb->sys_res_arcmsr[0]); + break; + case ACB_ADAPTER_TYPE_D: + if (acb->sys_res_arcmsr[0]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]); + break; + case ACB_ADAPTER_TYPE_E: + if (acb->sys_res_arcmsr[0]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(1), acb->sys_res_arcmsr[0]); + break; + case ACB_ADAPTER_TYPE_F: + if (acb->sys_res_arcmsr[0]) + bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]); + break; + } } /* ************************************************************************ @@ -4480,21 +4619,16 @@ static void arcmsr_mutex_destroy(struct AdapterControlBlock *acb) ************************************************************************ ************************************************************************ */ -static u_int32_t arcmsr_initialize(device_t dev) +static int arcmsr_define_adapter_type(struct AdapterControlBlock *acb) { - struct AdapterControlBlock *acb = device_get_softc(dev); - u_int16_t pci_command; - int i, j,max_coherent_size; - u_int32_t vendor_dev_id; - - vendor_dev_id = pci_get_devid(dev); - acb->vendor_device_id = vendor_dev_id; - acb->sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2); - switch (vendor_dev_id) { - case PCIDevVenIDARC1880: - case PCIDevVenIDARC1882: - case PCIDevVenIDARC1213: - case PCIDevVenIDARC1223: { + int rc = 0; + + switch (acb->vendor_device_id) { + case PCIDevVenIDARC1880: + case PCIDevVenIDARC1882: + case PCIDevVenIDARC1883: + case PCIDevVenIDARC1213: + case PCIDevVenIDARC1223: { acb->adapter_type = ACB_ADAPTER_TYPE_C; if ((acb->sub_device_id == ARECA_SUB_DEV_ID_1883) || (acb->sub_device_id == ARECA_SUB_DEV_ID_1216) || @@ -4502,158 +4636,78 @@ static u_int32_t arcmsr_initialize(device_t dev) acb->adapter_bus_speed = ACB_BUS_SPEED_12G; else acb->adapter_bus_speed = ACB_BUS_SPEED_6G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE; - } - break; - case PCIDevVenIDARC1884: - acb->adapter_type = ACB_ADAPTER_TYPE_E; - acb->adapter_bus_speed = ACB_BUS_SPEED_12G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE; - acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ); - break; - case PCIDevVenIDARC1886_: - case PCIDevVenIDARC1886: - acb->adapter_type = ACB_ADAPTER_TYPE_F; - acb->adapter_bus_speed = ACB_BUS_SPEED_12G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE + MESG_RW_BUFFER_SIZE; - acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ); - break; - case PCIDevVenIDARC1214: { + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE; + } + break; + case PCIDevVenIDARC1884: + acb->adapter_type = ACB_ADAPTER_TYPE_E; + acb->adapter_bus_speed = ACB_BUS_SPEED_12G; + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE; + acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ); + break; + case PCIDevVenIDARC1886_0: + case PCIDevVenIDARC1886_: + case PCIDevVenIDARC1886: + acb->adapter_type = ACB_ADAPTER_TYPE_F; + acb->adapter_bus_speed = ACB_BUS_SPEED_12G; + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE + MESG_RW_BUFFER_SIZE; + acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ); + break; + case PCIDevVenIDARC1214: + case PCIDevVenIDARC1224: { acb->adapter_type = ACB_ADAPTER_TYPE_D; acb->adapter_bus_speed = ACB_BUS_SPEED_6G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0)); - } - break; - case PCIDevVenIDARC1200: - case PCIDevVenIDARC1201: { + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0)); + } + break; + case PCIDevVenIDARC1200: + case PCIDevVenIDARC1201: { acb->adapter_type = ACB_ADAPTER_TYPE_B; acb->adapter_bus_speed = ACB_BUS_SPEED_3G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit)); - } - break; - case PCIDevVenIDARC1203: { + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit)); + } + break; + case PCIDevVenIDARC1203: { acb->adapter_type = ACB_ADAPTER_TYPE_B; acb->adapter_bus_speed = ACB_BUS_SPEED_6G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit)); - } - break; - case PCIDevVenIDARC1110: - case PCIDevVenIDARC1120: - case PCIDevVenIDARC1130: - case PCIDevVenIDARC1160: - case PCIDevVenIDARC1170: - case PCIDevVenIDARC1210: - case PCIDevVenIDARC1220: - case PCIDevVenIDARC1230: - case PCIDevVenIDARC1231: - case PCIDevVenIDARC1260: - case PCIDevVenIDARC1261: - case PCIDevVenIDARC1270: - case PCIDevVenIDARC1280: - case PCIDevVenIDARC1212: - case PCIDevVenIDARC1222: - case PCIDevVenIDARC1380: - case PCIDevVenIDARC1381: - case PCIDevVenIDARC1680: - case PCIDevVenIDARC1681: { + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit)); + } + break; + case PCIDevVenIDARC1110: + case PCIDevVenIDARC1120: + case PCIDevVenIDARC1130: + case PCIDevVenIDARC1160: + case PCIDevVenIDARC1170: + case PCIDevVenIDARC1210: + case PCIDevVenIDARC1220: + case PCIDevVenIDARC1230: + case PCIDevVenIDARC1231: + case PCIDevVenIDARC1260: + case PCIDevVenIDARC1261: + case PCIDevVenIDARC1270: + case PCIDevVenIDARC1280: + case PCIDevVenIDARC1212: + case PCIDevVenIDARC1222: + case PCIDevVenIDARC1380: + case PCIDevVenIDARC1381: + case PCIDevVenIDARC1680: + case PCIDevVenIDARC1681: { acb->adapter_type = ACB_ADAPTER_TYPE_A; acb->adapter_bus_speed = ACB_BUS_SPEED_3G; - max_coherent_size = ARCMSR_SRBS_POOL_SIZE; - } - break; - default: { + acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE; + } + break; + default: { printf("arcmsr%d:" - " unknown RAID adapter type \n", device_get_unit(dev)); - return ENOMEM; + " unknown RAID adapter type \n", acb->pci_unit); + rc = ENOMEM; } } - if(bus_dma_tag_create( /*PCI parent*/ bus_get_dma_tag(dev), - /*alignemnt*/ 1, - /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR, - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/ BUS_SPACE_UNRESTRICTED, - /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, - /*flags*/ 0, - /*lockfunc*/ NULL, - /*lockarg*/ NULL, - &acb->parent_dmat) != 0) - { - printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", device_get_unit(dev)); - return ENOMEM; - } - - /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */ - if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat, - /*alignment*/ 1, - /*boundary*/ 0, -#ifdef PAE - /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, -#else - /*lowaddr*/ BUS_SPACE_MAXADDR, -#endif - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM, - /*nsegments*/ ARCMSR_MAX_SG_ENTRIES, - /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, - /*flags*/ 0, - /*lockfunc*/ busdma_lock_mutex, - /*lockarg*/ &acb->isr_lock, - &acb->dm_segs_dmat) != 0) - { - bus_dma_tag_destroy(acb->parent_dmat); - printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", device_get_unit(dev)); - return ENOMEM; - } + return rc; +} - /* DMA tag for our srb structures.... Allocate the freesrb memory */ - if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat, - /*alignment*/ 0x20, - /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ max_coherent_size, - /*nsegments*/ 1, - /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, - /*flags*/ 0, - /*lockfunc*/ NULL, - /*lockarg*/ NULL, - &acb->srb_dmat) != 0) - { - bus_dma_tag_destroy(acb->dm_segs_dmat); - bus_dma_tag_destroy(acb->parent_dmat); - printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", device_get_unit(dev)); - return ENXIO; - } - /* Allocation for our srbs */ - if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr, BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &acb->srb_dmamap) != 0) { - bus_dma_tag_destroy(acb->srb_dmat); - bus_dma_tag_destroy(acb->dm_segs_dmat); - bus_dma_tag_destroy(acb->parent_dmat); - printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", device_get_unit(dev)); - return ENXIO; - } - /* And permanently map them */ - if(bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr, max_coherent_size, arcmsr_map_free_srb, acb, /*flags*/0)) { - bus_dma_tag_destroy(acb->srb_dmat); - bus_dma_tag_destroy(acb->dm_segs_dmat); - bus_dma_tag_destroy(acb->parent_dmat); - printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", device_get_unit(dev)); - return ENXIO; - } - pci_command = pci_read_config(dev, PCIR_COMMAND, 2); - pci_command |= PCIM_CMD_BUSMASTEREN; - pci_command |= PCIM_CMD_PERRESPEN; - pci_command |= PCIM_CMD_MWRICEN; - /* Enable Busmaster */ - pci_write_config(dev, PCIR_COMMAND, pci_command, 2); +static int arcmsr_map_pcireg(device_t dev, struct AdapterControlBlock *acb) +{ switch(acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { u_int32_t rid0 = PCIR_BAR(0); @@ -4662,18 +4716,18 @@ static u_int32_t arcmsr_initialize(device_t dev) acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit); return ENOMEM; } if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit); return ENXIO; } mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); if(mem_base0 == 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit); return ENXIO; } acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); @@ -4683,47 +4737,33 @@ static u_int32_t arcmsr_initialize(device_t dev) } break; case ACB_ADAPTER_TYPE_B: { - struct HBB_MessageUnit *phbbmu; - struct CommandControlBlock *freesrb; u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) }; vm_offset_t mem_base[]={0,0}; + u_int16_t i; + for(i=0; i < 2; i++) { acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i], RF_ACTIVE); if(acb->sys_res_arcmsr[i] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource %d failure!\n", device_get_unit(dev), i); + printf("arcmsr%d: bus_alloc_resource %d failure!\n", acb->pci_unit, i); return ENOMEM; } if(rman_get_start(acb->sys_res_arcmsr[i]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i); + printf("arcmsr%d: rman_get_start %d failure!\n", acb->pci_unit, i); return ENXIO; } mem_base[i] = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]); if(mem_base[i] == 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i); + printf("arcmsr%d: rman_get_virtual %d failure!\n", acb->pci_unit, i); return ENXIO; } acb->btag[i] = rman_get_bustag(acb->sys_res_arcmsr[i]); acb->bhandle[i] = rman_get_bushandle(acb->sys_res_arcmsr[i]); } - freesrb = (struct CommandControlBlock *)acb->uncacheptr; - acb->pmu = (struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE); - phbbmu = (struct HBB_MessageUnit *)acb->pmu; - phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0]; - phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1]; - if (vendor_dev_id == PCIDevVenIDARC1203) { - phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell); - phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask); - phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell); - phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask); - } else { - phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell); - phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask); - phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell); - phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask); - } + acb->mem_base0 = mem_base[0]; + acb->mem_base1 = mem_base[1]; acb->rid[0] = rid[0]; acb->rid[1] = rid[1]; } @@ -4735,18 +4775,18 @@ static u_int32_t arcmsr_initialize(device_t dev) acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit); return ENOMEM; } if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit); return ENXIO; } mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); if(mem_base0 == 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit); return ENXIO; } acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); @@ -4756,32 +4796,29 @@ static u_int32_t arcmsr_initialize(device_t dev) } break; case ACB_ADAPTER_TYPE_D: { - struct HBD_MessageUnit0 *phbdmu; u_int32_t rid0 = PCIR_BAR(0); vm_offset_t mem_base0; acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit); return ENOMEM; } if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit); return ENXIO; } mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); if(mem_base0 == 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit); return ENXIO; } acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]); - acb->pmu = (struct MessageUnit_UNION *)((unsigned long)acb->uncacheptr+ARCMSR_SRBS_POOL_SIZE); - phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; - phbdmu->phbdmu = (struct HBD_MessageUnit *)mem_base0; + acb->mem_base0 = mem_base0; acb->rid[0] = rid0; } break; @@ -4792,18 +4829,18 @@ static u_int32_t arcmsr_initialize(device_t dev) acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit); return ENOMEM; } if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit); return ENXIO; } mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); if(mem_base0 == 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit); return ENXIO; } acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); @@ -4820,23 +4857,22 @@ static u_int32_t arcmsr_initialize(device_t dev) case ACB_ADAPTER_TYPE_F: { u_int32_t rid0 = PCIR_BAR(0); vm_offset_t mem_base0; - unsigned long host_buffer_dma; acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit); return ENOMEM; } if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit); return ENXIO; } mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); if(mem_base0 == 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit); return ENXIO; } acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); @@ -4848,17 +4884,203 @@ static u_int32_t arcmsr_initialize(device_t dev) acb->rid[0] = rid0; CHIP_REG_WRITE32(HBF_MessageUnit, 0, host_int_status, 0); /*clear interrupt*/ CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBEMU_DOORBELL_SYNC); /* synchronize doorbell to 0 */ - arcmsr_wait_firmware_ready(acb); - host_buffer_dma = acb->completeQ_phys + COMPLETION_Q_POOL_SIZE; - CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, (u_int32_t)(host_buffer_dma | 1)); /* host buffer low addr, bit0:1 all buffer active */ - CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr1, (u_int32_t)((host_buffer_dma >> 16) >> 16));/* host buffer high addr */ - CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBFMU_DOORBELL_SYNC1); /* set host buffer physical address */ } break; } - if(acb->acb_flags & ACB_F_MAPFREESRB_FAILD) { + return (0); +} + +static int arcmsr_alloc_srb(device_t dev, struct AdapterControlBlock *acb) +{ + int rc; + + if(bus_dma_tag_create( /*PCI parent*/ bus_get_dma_tag(dev), + /*alignemnt*/ 1, + /*boundary*/ 0, + /*lowaddr*/ BUS_SPACE_MAXADDR, + /*highaddr*/ BUS_SPACE_MAXADDR, + /*filter*/ NULL, + /*filterarg*/ NULL, + /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT, + /*nsegments*/ BUS_SPACE_UNRESTRICTED, + /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, + /*flags*/ 0, + /*lockfunc*/ NULL, + /*lockarg*/ NULL, + &acb->parent_dmat) != 0) + { + printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", acb->pci_unit); + return ENOMEM; + } + + /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */ + if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat, + /*alignment*/ 1, + /*boundary*/ 0, +#ifdef PAE + /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, +#else + /*lowaddr*/ BUS_SPACE_MAXADDR, +#endif + /*highaddr*/ BUS_SPACE_MAXADDR, + /*filter*/ NULL, + /*filterarg*/ NULL, + /*maxsize*/ ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM, + /*nsegments*/ ARCMSR_MAX_SG_ENTRIES, + /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, + /*flags*/ 0, + /*lockfunc*/ busdma_lock_mutex, + /*lockarg*/ &acb->isr_lock, + &acb->dm_segs_dmat) != 0) + { + arcmsr_free_resource(acb); + printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", acb->pci_unit); + return ENOMEM; + } + + /* DMA tag for our srb structures.... Allocate the freesrb memory */ + if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat, + /*alignment*/ 0x20, + /*boundary*/ 0, + /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/ BUS_SPACE_MAXADDR, + /*filter*/ NULL, + /*filterarg*/ NULL, + /*maxsize*/ acb->max_coherent_size, + /*nsegments*/ 1, + /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, + /*flags*/ 0, + /*lockfunc*/ NULL, + /*lockarg*/ NULL, + &acb->srb_dmat) != 0) + { + arcmsr_free_resource(acb); + printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", acb->pci_unit); + return ENXIO; + } + /* Allocation for our srbs */ + if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr, ARCMSR_DMA_ALLOC_FLAG, &acb->srb_dmamap) != 0) { + arcmsr_free_resource(acb); + printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", acb->pci_unit); + return ENXIO; + } + /* And permanently map them */ + rc = bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr, acb->max_coherent_size, arcmsr_map_free_srb, acb, /*flags*/0); + if((rc != 0) && (rc != EINPROGRESS)) { + arcmsr_free_resource(acb); + printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", acb->pci_unit); + return ENXIO; + } + acb->acb_flags |= ACB_F_DMAMAP_SRB; + return (0); +} + +static int arcmsr_alloc_xor_mem(device_t dev, struct AdapterControlBlock *acb) +{ + int rc, xor_ram; + + xor_ram = (acb->firm_PicStatus >> 24) & 0x0f; + acb->xor_mega = (xor_ram - 1) * 32 + 128 + 3; + acb->init2cfg_size = sizeof(struct HostRamBuf) + (sizeof(struct XorSg) * acb->xor_mega); + /* DMA tag for XOR engine of Raid 5,6 */ + if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat, + /*alignment*/ 0x40, + /*boundary*/ 0, + /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/ BUS_SPACE_MAXADDR, + /*filter*/ NULL, + /*filterarg*/ NULL, + /*maxsize*/ acb->init2cfg_size, + /*nsegments*/ 1, + /*maxsegsz*/ acb->init2cfg_size, + /*flags*/ 0, + /*lockfunc*/ NULL, + /*lockarg*/ NULL, + &acb->xortable_dmat) != 0) + { + arcmsr_free_resource(acb); + printf("arcmsr%d: xor table bus_dma_tag_create failure!\n", acb->pci_unit); + return ENXIO; + } + /* Allocation for xors */ + if(bus_dmamem_alloc(acb->xortable_dmat, (void **)&acb->xortable, ARCMSR_DMA_ALLOC_FLAG, &acb->xortable_dmamap) != 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: map free srb failure!\n", device_get_unit(dev)); + printf("arcmsr%d: xor table bus_dmamem_alloc failure!\n", acb->pci_unit); + return ENXIO; + } + /* And permanently map xor segs */ + rc = bus_dmamap_load(acb->xortable_dmat, acb->xortable_dmamap, acb->xortable, acb->init2cfg_size, arcmsr_map_xor_sgtable, acb, /*flags*/0); + if((rc != 0) && (rc != EINPROGRESS)) { + arcmsr_free_resource(acb); + printf("arcmsr%d: xor table bus_dmamap_load failure!\n", acb->pci_unit); + return ENXIO; + } + acb->acb_flags |= ACB_F_DMAMAP_SGTABLE; + + /* DMA tag for XOR engine of Raid 5,6 */ + if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat, + /*alignment*/ 0x1000, + /*boundary*/ 0, + /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/ BUS_SPACE_MAXADDR, + /*filter*/ NULL, + /*filterarg*/ NULL, + /*maxsize*/ (ARCMSR_XOR_SEG_SIZE * acb->xor_mega), + /*nsegments*/ acb->xor_mega, + /*maxsegsz*/ ARCMSR_XOR_SEG_SIZE, + /*flags*/ 0, + /*lockfunc*/ NULL, + /*lockarg*/ NULL, + &acb->xor_dmat) != 0) + { + arcmsr_free_resource(acb); + printf("arcmsr%d: xor bus_dma_tag_create failure!\n", acb->pci_unit); + return ENXIO; + } + /* Allocation for xors */ *** 250 LINES SKIPPED ***