Date: Fri, 14 Jul 2017 14:53:14 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320986 - in head: share/man/man4 sys/dev/arcmsr Message-ID: <201707141453.v6EErEpf020364@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Fri Jul 14 14:53:13 2017 New Revision: 320986 URL: https://svnweb.freebsd.org/changeset/base/320986 Log: Update arcmsr(4) to 1.40.00.00 in order to add support of ARC-1884 SATA RAID controllers. Many thanks to Areca for continuing to support FreeBSD. Submitted by: 黃清隆 <ching2048 areca com tw> MFC after: 3 days Modified: head/share/man/man4/arcmsr.4 head/sys/dev/arcmsr/arcmsr.c head/sys/dev/arcmsr/arcmsr.h Modified: head/share/man/man4/arcmsr.4 ============================================================================== --- head/share/man/man4/arcmsr.4 Fri Jul 14 14:52:44 2017 (r320985) +++ head/share/man/man4/arcmsr.4 Fri Jul 14 14:53:13 2017 (r320986) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 4, 2015 +.Dd July 14, 2017 .Dt ARCMSR 4 .Os .Sh NAME @@ -147,6 +147,8 @@ ARC-1880 ARC-1882 .It ARC-1883 +.It +ARC-1884 .El .Sh FILES .Bl -tag -width ".Pa /dev/arcmsr?" -compact Modified: head/sys/dev/arcmsr/arcmsr.c ============================================================================== --- head/sys/dev/arcmsr/arcmsr.c Fri Jul 14 14:52:44 2017 (r320985) +++ head/sys/dev/arcmsr/arcmsr.c Fri Jul 14 14:53:13 2017 (r320986) @@ -77,6 +77,7 @@ ** 1.20.00.28 09/13/2013 Ching Huang Removed recursive mutex in arcmsr_abort_dr_ccbs ** 1.20.00.29 12/18/2013 Ching Huang Change simq allocation number, support ARC1883 ** 1.30.00.00 11/30/2015 Ching Huang Added support ARC1203 +** 1.40.00.00 07/11/2017 Ching Huang Added support ARC1884 ****************************************************************************************** */ @@ -148,7 +149,7 @@ __FBSDID("$FreeBSD$"); #define arcmsr_callout_init(a) callout_init(a); #endif -#define ARCMSR_DRIVER_VERSION "arcmsr version 1.30.00.00 2015-11-30" +#define ARCMSR_DRIVER_VERSION "arcmsr version 1.40.00.00 2017-07-11" #include <dev/arcmsr/arcmsr.h> /* ************************************************************************** @@ -185,6 +186,8 @@ static void arcmsr_rescanLun_cb(struct cam_periph *per static void arcmsr_polling_devmap(void *arg); static void arcmsr_srb_timeout(void *arg); static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb); +static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb); +void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb); #ifdef ARCMSR_DEBUG1 static void arcmsr_dump_data(struct AdapterControlBlock *acb); #endif @@ -376,6 +379,12 @@ static u_int32_t arcmsr_disable_allintr( struct Adapte CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE); } break; + case ACB_ADAPTER_TYPE_E: { + /* disable all outbound interrupt */ + intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask) ; /* disable outbound message0 int */ + CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE); + } + break; } return (intmask_org); } @@ -418,6 +427,13 @@ static void arcmsr_enable_allintr( struct AdapterContr acb->outbound_int_enable = mask; } break; + case ACB_ADAPTER_TYPE_E: { + /* enable outbound Post Queue, outbound doorbell Interrupt */ + mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org & mask); + acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f; + } + break; } } /* @@ -503,6 +519,28 @@ static u_int8_t arcmsr_hbd_wait_msgint_ready(struct Ad return (FALSE); } /* +********************************************************************** +********************************************************************** +*/ +static u_int8_t arcmsr_hbe_wait_msgint_ready(struct AdapterControlBlock *acb) +{ + u_int32_t Index, read_doorbell; + u_int8_t Retries = 0x00; + + do { + for(Index=0; Index < 100; Index++) { + read_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell); + if((read_doorbell ^ acb->in_doorbell) & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) { + CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);/*clear interrupt*/ + acb->in_doorbell = read_doorbell; + return TRUE; + } + UDELAY(10000); + }/*max 1 seconds*/ + }while(Retries++ < 20);/*max 20 sec*/ + return (FALSE); +} +/* ************************************************************************ ************************************************************************ */ @@ -576,6 +614,25 @@ static void arcmsr_flush_hbd_cache(struct AdapterContr ************************************************************************ ************************************************************************ */ +static void arcmsr_flush_hbe_cache(struct AdapterControlBlock *acb) +{ + int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ + + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + do { + if(arcmsr_hbe_wait_msgint_ready(acb)) { + break; + } else { + retry_count--; + } + }while(retry_count != 0); +} +/* +************************************************************************ +************************************************************************ +*/ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -595,6 +652,10 @@ static void arcmsr_flush_adapter_cache(struct AdapterC arcmsr_flush_hbd_cache(acb); } break; + case ACB_ADAPTER_TYPE_E: { + arcmsr_flush_hbe_cache(acb); + } + break; } } /* @@ -715,6 +776,19 @@ static void arcmsr_abort_hbd_allcmd(struct AdapterCont ********************************************************************* ********************************************************************* */ +static void arcmsr_abort_hbe_allcmd(struct AdapterControlBlock *acb) +{ + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit); + } +} +/* +********************************************************************* +********************************************************************* +*/ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -734,6 +808,10 @@ static void arcmsr_abort_allcmd(struct AdapterControlB arcmsr_abort_hbd_allcmd(acb); } break; + case ACB_ADAPTER_TYPE_E: { + arcmsr_abort_hbe_allcmd(acb); + } + break; } } /* @@ -836,6 +914,9 @@ static void arcmsr_drain_donequeue(struct AdapterContr case ACB_ADAPTER_TYPE_D: srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/ break; + case ACB_ADAPTER_TYPE_E: + srb = acb->psrb_pool[flag_srb]; + break; case ACB_ADAPTER_TYPE_A: case ACB_ADAPTER_TYPE_B: default: @@ -938,6 +1019,10 @@ static void arcmsr_done4abort_postqueue(struct Adapter arcmsr_hbd_postqueue_isr(acb); } break; + case ACB_ADAPTER_TYPE_E: { + arcmsr_hbe_postqueue_isr(acb); + } + break; } } /* @@ -1149,6 +1234,15 @@ static void arcmsr_post_srb(struct AdapterControlBlock ARCMSR_LOCK_RELEASE(&acb->postDone_lock); } break; + case ACB_ADAPTER_TYPE_E: { + u_int32_t ccb_post_stamp, arc_cdb_size; + + arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size; + ccb_post_stamp = (srb->smid | ((arc_cdb_size-1) >> 6)); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_high, 0); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp); + } + break; } } /* @@ -1184,6 +1278,12 @@ static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer; } break; + case ACB_ADAPTER_TYPE_E: { + struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu; + + qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer; + } + break; } return(qbuffer); } @@ -1220,6 +1320,12 @@ static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer; } break; + case ACB_ADAPTER_TYPE_E: { + struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu; + + qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer; + } + break; } return(qbuffer); } @@ -1251,6 +1357,12 @@ static void arcmsr_iop_message_read(struct AdapterCont CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ); } break; + case ACB_ADAPTER_TYPE_E: { + /* let IOP know data has been read */ + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + } + break; } } /* @@ -1293,6 +1405,15 @@ static void arcmsr_iop_message_wrote(struct AdapterCon CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY); } break; + case ACB_ADAPTER_TYPE_E: { + /* + ** push inbound doorbell tell iop, driver data write ok + ** and wait reply on next hwinterrupt for next Qbuffer post + */ + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + } + break; } } /* @@ -1352,6 +1473,20 @@ static void arcmsr_stop_hbd_bgrb(struct AdapterControl ************************************************************************ ************************************************************************ */ +static void arcmsr_stop_hbe_bgrb(struct AdapterControlBlock *acb) +{ + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit); + } +} +/* +************************************************************************ +************************************************************************ +*/ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -1371,6 +1506,10 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterCon arcmsr_stop_hbd_bgrb(acb); } break; + case ACB_ADAPTER_TYPE_E: { + arcmsr_stop_hbe_bgrb(acb); + } + break; } } /* @@ -1446,7 +1585,8 @@ static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct u_int8_t *iop_data; u_int32_t iop_len; - if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) { + if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) || + (acb->adapter_type == ACB_ADAPTER_TYPE_E)) { return(arcmsr_Read_iop_rqbuffer_data_D(acb, prbuffer)); } iop_data = (u_int8_t *)prbuffer->data; @@ -1541,7 +1681,8 @@ static void arcmsr_Write_data_2iop_wqbuffer(struct Ada u_int8_t *iop_data; int32_t allxfer_len=0; - if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) { + if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) || + (acb->adapter_type == ACB_ADAPTER_TYPE_E)) { arcmsr_Write_data_2iop_wqbuffer_D(acb); return; } @@ -1694,6 +1835,14 @@ static void arcmsr_dr_handle(struct AdapterControlBloc devicemap += 4; } break; + case ACB_ADAPTER_TYPE_E: + 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); + devicemap += 4; + } + break; } if(acb->acb_flags & ACB_F_BUS_HANG_ON) @@ -1792,6 +1941,18 @@ static void arcmsr_hbd_message_isr(struct AdapterContr ************************************************************************** ************************************************************************** */ +static void arcmsr_hbe_message_isr(struct AdapterControlBlock *acb) { + u_int32_t outbound_message; + + CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); + outbound_message = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[0]); + if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG) + arcmsr_dr_handle( acb ); +} +/* +************************************************************************** +************************************************************************** +*/ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb) { u_int32_t doorbell_status; @@ -1876,6 +2037,35 @@ static void arcmsr_hbd_doorbell_isr(struct AdapterCont ************************************************************************** ************************************************************************** */ +static void arcmsr_hbe_doorbell_isr(struct AdapterControlBlock *acb) +{ + u_int32_t doorbell_status, in_doorbell; + + /* + ******************************************************************* + ** Maybe here we need to check wrqbuffer_lock is lock or not + ** DOORBELL: din! don! + ** check if there are any mail need to pack from firmware + ******************************************************************* + */ + in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /* clear doorbell interrupt */ + doorbell_status = in_doorbell ^ acb->in_doorbell; + if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK) { + arcmsr_iop2drv_data_wrote_handle(acb); + } + if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK) { + arcmsr_iop2drv_data_read_handle(acb); + } + if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) { + arcmsr_hbe_message_isr(acb); /* messenger of "driver to iop commands" */ + } + acb->in_doorbell = in_doorbell; +} +/* +************************************************************************** +************************************************************************** +*/ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) { u_int32_t flag_srb; @@ -2013,6 +2203,34 @@ static void arcmsr_hbd_postqueue_isr(struct AdapterCon CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause); /*Dummy ioread32 to force pci flush */ } /* +************************************************************************** +************************************************************************** +*/ +static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb) +{ + u_int16_t error; + uint32_t doneq_index; + uint16_t cmdSMID; + + /* + ***************************************************************************** + ** areca cdb command done + ***************************************************************************** + */ + bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + doneq_index = acb->doneq_index; + while ((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) != doneq_index) { + cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID; + error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; + arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error); + doneq_index++; + if (doneq_index >= acb->completionQ_entry) + doneq_index = 0; + } + acb->doneq_index = doneq_index; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_consumer_index, doneq_index); +} +/* ********************************************************************** ********************************************************************** */ @@ -2143,6 +2361,37 @@ static void arcmsr_handle_hbd_isr( struct AdapterContr // CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable); } /* +********************************************************************** +********************************************************************** +*/ +static void arcmsr_handle_hbe_isr( struct AdapterControlBlock *acb) +{ + u_int32_t host_interrupt_status; + /* + ********************************************* + ** check outbound intstatus + ********************************************* + */ + host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status) & + (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | + ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR); + if(!host_interrupt_status) { + /*it must be share irq*/ + return; + } + do { + /* MU doorbell interrupts*/ + if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) { + arcmsr_hbe_doorbell_isr(acb); + } + /* MU post queue interrupts*/ + if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) { + arcmsr_hbe_postqueue_isr(acb); + } + host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status); + } while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR)); +} +/* ****************************************************************************** ****************************************************************************** */ @@ -2161,6 +2410,9 @@ static void arcmsr_interrupt(struct AdapterControlBloc case ACB_ADAPTER_TYPE_D: arcmsr_handle_hbd_isr(acb); break; + case ACB_ADAPTER_TYPE_E: + arcmsr_handle_hbe_isr(acb); + break; default: printf("arcmsr%d: interrupt service," " unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type); @@ -2205,6 +2457,12 @@ static void arcmsr_polling_devmap(void *arg) case ACB_ADAPTER_TYPE_D: CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); break; + + case ACB_ADAPTER_TYPE_E: + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + break; } if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0) @@ -2907,6 +3165,7 @@ static void arcmsr_action(struct cam_sim *psim, union else cpi->base_transfer_speed = 300000; if((acb->vendor_device_id == PCIDevVenIDARC1880) || + (acb->vendor_device_id == PCIDevVenIDARC1884) || (acb->vendor_device_id == PCIDevVenIDARC1680) || (acb->vendor_device_id == PCIDevVenIDARC1214)) { @@ -2991,6 +3250,7 @@ static void arcmsr_action(struct cam_sim *psim, union cts->protocol = PROTO_SCSI; if((acb->vendor_device_id == PCIDevVenIDARC1880) || + (acb->vendor_device_id == PCIDevVenIDARC1884) || (acb->vendor_device_id == PCIDevVenIDARC1680) || (acb->vendor_device_id == PCIDevVenIDARC1214)) { @@ -3150,6 +3410,20 @@ static void arcmsr_start_hbd_bgrb(struct AdapterContro ********************************************************************** ********************************************************************** */ +static void arcmsr_start_hbe_bgrb(struct AdapterControlBlock *acb) +{ + acb->acb_flags |= ACB_F_MSG_START_BGRB; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit); + } +} +/* +********************************************************************** +********************************************************************** +*/ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -3165,6 +3439,9 @@ static void arcmsr_start_adapter_bgrb(struct AdapterCo case ACB_ADAPTER_TYPE_D: arcmsr_start_hbd_bgrb(acb); break; + case ACB_ADAPTER_TYPE_E: + arcmsr_start_hbe_bgrb(acb); + break; } } /* @@ -3388,8 +3665,63 @@ polling_ccb_retry: } /* ********************************************************************** +** ********************************************************************** */ +static void arcmsr_polling_hbe_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb) +{ + struct CommandControlBlock *srb; + u_int32_t poll_srb_done=0, poll_count=0, doneq_index; + u_int16_t error, cmdSMID; + +polling_ccb_retry: + poll_count++; + bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); + while(1) { + doneq_index = acb->doneq_index; + if((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) == doneq_index) { + if(poll_srb_done) { + break;/*chip FIFO no ccb for completion already*/ + } else { + UDELAY(25000); + if ((poll_count > 100) && (poll_srb != NULL)) { + break; + } + if (acb->srboutstandingcount == 0) { + break; + } + goto polling_ccb_retry; + } + } + cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID; + doneq_index++; + if (doneq_index >= acb->completionQ_entry) + doneq_index = 0; + acb->doneq_index = doneq_index; + srb = acb->psrb_pool[cmdSMID]; + error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; + if (poll_srb != NULL) + poll_srb_done = (srb == poll_srb) ? 1:0; + if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) { + if(srb->srb_state == ARCMSR_SRB_ABORTED) { + printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n" + , acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb); + srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; + arcmsr_srb_complete(srb, 1); + continue; + } + printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n" + , acb->pci_unit, srb, acb->srboutstandingcount); + continue; + } + arcmsr_report_srb_state(acb, srb, error); + } /*drain reply FIFO*/ + CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_producer_index, doneq_index); +} +/* +********************************************************************** +********************************************************************** +*/ static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb) { switch (acb->adapter_type) { @@ -3409,6 +3741,10 @@ static void arcmsr_polling_srbdone(struct AdapterContr arcmsr_polling_hbd_srbdone(acb, poll_srb); } break; + case ACB_ADAPTER_TYPE_E: { + arcmsr_polling_hbe_srbdone(acb, poll_srb); + } + break; } } /* @@ -3615,6 +3951,58 @@ static void arcmsr_get_hbd_config(struct AdapterContro ********************************************************************** ********************************************************************** */ +static void arcmsr_get_hbe_config(struct AdapterControlBlock *acb) +{ + char *acb_firm_model = acb->firm_model; + char *acb_firm_version = acb->firm_version; + char *acb_device_map = acb->device_map; + size_t iop_firm_model = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ + size_t iop_firm_version = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ + size_t iop_device_map = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); + int i; + + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); + } + + i = 0; + while(i < 8) { + *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); + /* 8 bytes firm_model, 15, 60-67*/ + acb_firm_model++; + i++; + } + i = 0; + while(i < 16) { + *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i); + /* 16 bytes firm_version, 17, 68-83*/ + acb_firm_version++; + i++; + } + i = 0; + while(i < 16) { + *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i); + acb_device_map++; + i++; + } + printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version); + acb->firm_request_len = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ + acb->firm_numbers_queue = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ + acb->firm_sdram_size = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ + acb->firm_ide_channels = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ + acb->firm_cfg_version = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ + if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD) + acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1; + else + acb->maxOutstanding = acb->firm_numbers_queue - 1; +} +/* +********************************************************************** +********************************************************************** +*/ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -3634,6 +4022,10 @@ static void arcmsr_get_firmware_spec(struct AdapterCon arcmsr_get_hbd_config(acb); } break; + case ACB_ADAPTER_TYPE_E: { + arcmsr_get_hbe_config(acb); + } + break; } } /* @@ -3695,6 +4087,18 @@ static void arcmsr_wait_firmware_ready( struct Adapter } } break; + case ACB_ADAPTER_TYPE_E: { + while ((CHIP_REG_READ32(HBE_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0) + { + if (timeout++ > 4000) /* (4000*15)/1000 = 60 sec */ + { + printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit); + return; + } + UDELAY(15000); /* wait 15 milli-seconds */ + } + } + break; } } /* @@ -3738,6 +4142,14 @@ static void arcmsr_clear_doorbell_queue_buffer( struct } break; + case ACB_ADAPTER_TYPE_E: { + /* empty doorbell Qbuffer if door bell ringed */ + acb->in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /*clear doorbell interrupt */ + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + } + break; } } /* @@ -3844,6 +4256,27 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterCont } } break; + case ACB_ADAPTER_TYPE_E: { + u_int32_t cdb_phyaddr_lo32; + cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[1], ARCMSR_SIGNATURE_1884); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[2], cdb_phyaddr_lo32); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[3], srb_phyaddr_hi32); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[4], SRB_SIZE); + cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[5], cdb_phyaddr_lo32); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[6], srb_phyaddr_hi32); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[7], COMPLETION_Q_POOL_SIZE); + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) { + printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit); + return FALSE; + } + } + break; } return (TRUE); } @@ -3853,21 +4286,14 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterCont */ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb) { - switch (acb->adapter_type) + if (acb->adapter_type == ACB_ADAPTER_TYPE_B) { - case ACB_ADAPTER_TYPE_A: - case ACB_ADAPTER_TYPE_C: - case ACB_ADAPTER_TYPE_D: - break; - case ACB_ADAPTER_TYPE_B: { - struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; - WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE); - if(!arcmsr_hbb_wait_msgint_ready(acb)) { - printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit); - return; - } + struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; + WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE); + if(!arcmsr_hbb_wait_msgint_ready(acb)) { + printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit); + return; } - break; } } /* @@ -3913,7 +4339,8 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_seg " srb dmamap bus_dmamap_create error\n", acb->pci_unit); return; } - if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D)) + if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) + || (acb->adapter_type == ACB_ADAPTER_TYPE_E)) { srb_tmp->cdb_phyaddr_low = srb_phyaddr; srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16); @@ -3921,10 +4348,12 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_seg else srb_tmp->cdb_phyaddr_low = 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); } + acb->pCompletionQ = (pCompletion_Q)srb_tmp; acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr; } /* @@ -3992,6 +4421,12 @@ static u_int32_t arcmsr_initialize(device_t dev) 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 PCIDevVenIDARC1214: { acb->adapter_type = ACB_ADAPTER_TYPE_D; acb->adapter_bus_speed = ACB_BUS_SPEED_6G; @@ -4140,141 +4575,177 @@ static u_int32_t arcmsr_initialize(device_t dev) pci_write_config(dev, PCIR_COMMAND, pci_command, 2); switch(acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - u_int32_t rid0 = PCIR_BAR(0); - vm_offset_t mem_base0; + 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)); - 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)); - 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)); - 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 *)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)); + 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)); + 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)); + 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 *)mem_base0; + acb->rid = 0; + } 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_long size; - if (vendor_dev_id == PCIDevVenIDARC1203) - size = sizeof(struct HBB_DOORBELL_1203); - else - size = sizeof(struct HBB_DOORBELL); - for(i=0; i < 2; i++) { - if(i == 0) { - acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid[i], - RF_ACTIVE); - } else { - 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); - 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); - 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); - 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); + 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_long size; + if (vendor_dev_id == PCIDevVenIDARC1203) + size = sizeof(struct HBB_DOORBELL_1203); + else + size = sizeof(struct HBB_DOORBELL); + for(i=0; i < 2; i++) { + if(i == 0) { + acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid[i], + RF_ACTIVE); } 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->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i], + RF_ACTIVE); } - } - break; - case ACB_ADAPTER_TYPE_C: { - u_int32_t rid0 = PCIR_BAR(1); - 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) { + if(acb->sys_res_arcmsr[i] == NULL) { arcmsr_free_resource(acb); - printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + printf("arcmsr%d: bus_alloc_resource %d failure!\n", device_get_unit(dev), i); return ENOMEM; } - if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { + if(rman_get_start(acb->sys_res_arcmsr[i]) <= 0) { arcmsr_free_resource(acb); - printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i); return ENXIO; } - mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); - if(mem_base0 == 0) { + 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 failure!\n", device_get_unit(dev)); + printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i); 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 *)mem_base0; + 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->rid = 0; + } break; + case ACB_ADAPTER_TYPE_C: { + u_int32_t rid0 = PCIR_BAR(1); + 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)); + 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)); + 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)); + 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 *)mem_base0; + acb->rid = 1; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707141453.v6EErEpf020364>