[Openib-windows] RE: Handling LionCub Rev. C HCAs
Leonid Keller
leonid at mellanox.co.il
Sun Mar 26 10:42:38 PST 2006
Looks fine, but I did't test it.
If you saw it working on both types of flashes you may commit it.
> -----Original Message-----
> From: Fab Tillier [mailto:ftillier at silverstorm.com]
> Sent: Thursday, March 23, 2006 3:31 AM
> To: Leonid Keller
> Cc: openib-windows at openib.org
> Subject: Handling LionCub Rev. C HCAs
>
> Hi Leonid,
>
> The following patch enables LionCub Rev C HCAs to be used
> with the mt23108 driver. The Flash sector size is 128K on
> these, rather than the "standard" 64K.
> The patch updates the driver to determine the Flash sector
> size dynamically, rather than using a hard coded value.
>
> The driver tries to read the GUIDs from the Flash, and would
> fail loading if it couldn't find it.
>
> Let me know if I can commit this.
>
> Thanks,
>
> - Fab
>
> Index: hw/mt23108/kernel/hca_driver.c
> ===================================================================
> --- hw/mt23108/kernel/hca_driver.c (revision 249)
> +++ hw/mt23108/kernel/hca_driver.c (working copy)
> @@ -914,6 +914,7 @@
> NTSTATUS status;
> hca_dev_ext_t *p_ext;
> net64_t ca_guid = 0;
> +
> HCA_ENTER( HCA_DBG_PNP );
>
> /* Handled on the way up. */
> @@ -1260,7 +1261,10 @@
>
> NULL,
>
> &event,
>
> &ioStatus );
> - if (p_irp == NULL) {
> + if (p_irp == NULL)
> + {
> + HCA_TRACE( HCA_DBG_ERROR,
> + ("IoBuildSynchronousFsdRequest failed.\n") );
> status = STATUS_INSUFFICIENT_RESOURCES;
> goto End;
> }
> @@ -1473,9 +1477,9 @@
> NTSTATUS status = STATUS_SUCCESS;
> BUS_INTERFACE_STANDARD BusInterface;
>
> - uint32_t NODE_GUIDH, NODE_GUIDL;
> + uint32_t NODE_GUIDH, NODE_GUIDL;
> uint32_t prim_ptr = 0;
> - uint32_t signature;
> + uint32_t signature, offset, sect_size;
>
> primary_sector_t ps;
> cl_memset( &ps, 0, sizeof(primary_sector_t)); @@
> -1487,39 +1491,67 @@
>
> status = fw_flash_init (&BusInterface);
> if (status != STATUS_SUCCESS )
> - return status;
> - status = fw_flash_read_data(&BusInterface, &signature, 0x24, 4);
> + goto err1;
> +
> + status = fw_flash_read_data(&BusInterface, &signature,
> FW_SIG_OFFSET,
> 4);
> if (status != STATUS_SUCCESS )
> - return status;
> - //signature = cl_ntoh32(signature);
> + goto err2;
>
> - if (signature == FW_SIGNATURE)
> - {
> - //Fail Safe image
> -
> - // Assume flash has been verified, and both images
> have the same guids,
> therefore,
> - // we only need to read the primary image's guids
> - status = fw_flash_readbuf(&BusInterface, FW_SECT_SIZE, &ps,
> sizeof(ps));
> - if ( status == STATUS_SUCCESS )
> + if (signature == FW_SIGNATURE)
> + {
> + //Fail Safe image
> +
> + /* Find the sector size offset. */
> + status = fw_flash_read_data(
> + &BusInterface, &offset, FW_SECT_PTR_OFFSET, 4 );
> + if( status != STATUS_SUCCESS )
> + goto err2;
> +
> + offset &= 0x0000FFFF;
> +
> + status = fw_flash_read_data(
> + &BusInterface, §_size,
> FW_SECT_OFFSET + offset, 4 );
> + if( status != STATUS_SUCCESS )
> + goto err2;
> +
> + sect_size = 1 << (sect_size & 0x0000FFFF);
> +
> + /* Try to read the GUIDs from the primary image. */
> + status = fw_flash_readbuf(&BusInterface, sect_size, &ps,
> sizeof(ps));
> + if ( status == STATUS_SUCCESS && ps.signature
> != FW_SIGNATURE )
> {
> + /* Hmm, that didn't work. Try the
> secondary image. */
> + status = fw_flash_readbuf(
> + &BusInterface, sect_size * 2,
> &ps, sizeof(ps) );
> + }
> + if( status == STATUS_SUCCESS )
> + {
> + signature = ps.signature;
> status =
> fw_flash_read_data(&BusInterface, &prim_ptr, ps.fi_addr+0x24, 4);
> if (status == STATUS_SUCCESS )
> prim_ptr = prim_ptr + ps.fi_addr;
> }
> - }
> - else
> - {
> - // Short image
> - prim_ptr = signature;
> - }
> + else
> + {
> + signature = 0;
> + }
> + }
> + else
> + {
> + // Short image
> + HCA_TRACE( HCA_DBG_ERROR,
> + ("Invalid signature %08x, assuming
> short image.\n",
> signature) );
> + prim_ptr = signature;
> + signature = FW_SIGNATURE;
> + }
>
> - if ( signature == FW_SIGNATURE || prim_ptr < MAX_FLASH_SIZE )
> - {
> + if ( signature == FW_SIGNATURE && prim_ptr < MAX_FLASH_SIZE )
> + {
> /* now we can read ca guid
> * since we read it in host mode fw_flash_read4()
> * swaps it back in BE - how it was stored in FW
> */
> - if (( status = fw_flash_read4(&BusInterface,
> prim_ptr, &NODE_GUIDL)) ==
> STATUS_SUCCESS )
> + if (( status = fw_flash_read4(&BusInterface, prim_ptr,
> &NODE_GUIDL)) == STATUS_SUCCESS )
> if (( status =
> fw_flash_read4(&BusInterface, prim_ptr+4,
> &NODE_GUIDH)) == STATUS_SUCCESS )
> {
> *ca_guid = NODE_GUIDH;
> @@ -1527,13 +1559,15 @@
> }
> }
> else
> - {
> - //invalid GUID pointer
> - return STATUS_NO_SUCH_DEVICE;
> - }
> + {
> + //invalid GUID pointer
> + status = STATUS_NO_SUCH_DEVICE;
> + }
> +err2:
> fw_flash_deinit(&BusInterface);
> +err1:
> BusInterface.InterfaceDereference((PVOID)BusInterface.Context);
> - return status;
> + return status;
> }
>
> static NTSTATUS
> @@ -1548,14 +1582,20 @@
> static uint32_t curr_bank = 0xffffffff;
>
> if (addr & 0x3)
> + {
> + HCA_TRACE( HCA_DBG_ERROR, ("Invalid address
> %08x\n", addr) );
> return STATUS_INVALID_PARAMETER;
> + }
>
> bank = addr & BANK_MASK;
> if (bank != curr_bank)
> {
> curr_bank = bank;
> if ((status = fw_set_bank(p_BusInterface,
> bank)) != STATUS_SUCCESS )
> + {
> + HCA_TRACE( HCA_DBG_ERROR, ("fw_set_bank returned
> %08x\n", status) );
> return STATUS_INVALID_PARAMETER;
> + }
> }
> status = fw_flash_read_data(p_BusInterface, &lcl_data, addr, 4);
> *p_data = cl_ntoh32(lcl_data);
> @@ -1576,11 +1616,13 @@
> if (offset & 0x3)
> {
> //Address should be 4-bytes aligned
> + HCA_TRACE( HCA_DBG_ERROR, ("Invalid address
> %08x\n", offset) );
> return STATUS_INVALID_PARAMETER;
> }
> if (len & 0x3)
> {
> //Length should be 4-bytes aligned
> + HCA_TRACE( HCA_DBG_ERROR, ("Invalid length
> %d\n", len) );
> return STATUS_INVALID_PARAMETER;
> }
> p_lcl_data = (uint32_t *)p_data;
> Index: hw/mt23108/kernel/hca_driver.h
> ===================================================================
> --- hw/mt23108/kernel/hca_driver.h (revision 249)
> +++ hw/mt23108/kernel/hca_driver.h (working copy)
> @@ -138,6 +138,11 @@
> #define FW_CLOSE_IF 0x7e
>
> #define FW_SIGNATURE (0x5a445a44)
> -#define FW_SECT_SIZE (0x10000)
> +#define FW_SIG_OFFSET (0x24)
>
> +#define FW_SECT_PTR_OFFSET (0x14)
> +/* The real offset is 0x32, but we're reading DWORDS at a
> time, so we align */
> +#define FW_SECT_OFFSET (0x30)
> +
> +
> #endif /* !defined( _HCA_DRIVER_H_ ) */
>
More information about the ofw
mailing list