kernels/linux-2.4.0/drivers/scsi/cpqfcTSinit.c
// we need about 8 allocations per HBA.  Figuring at most 10 HBAs per server
// size the dynamic_mem array at 80.
we need about 8 allocations per HBA.  Figuring at most 10 HBAs per server
size the dynamic_mem array at 80.
we need about 8 allocations per HBA . Figuring at most 10 HBAs per server size the dynamic_mem array at 80 .
void* fcMemManager( ALIGNED_MEM *dynamic_mem, ULONG n_alloc, ULONG ab,
                   ULONG u32_AlignedAddress)
{
  USHORT allocBoundary=1;   
  unsigned long ulAddress;
  ULONG t_alloc, i;
  void *alloc_address = 0;  
  LONG mask;                
  ENTER("fcMemManager");
  if( u32_AlignedAddress )          
  {
    for( i=0; i<DYNAMIC_ALLOCATIONS; i++) 
    {
      if( dynamic_mem[i].AlignedAddress == u32_AlignedAddress )
      {
        alloc_address = dynamic_mem[i].BaseAllocated; 
        kfree( dynamic_mem[i].BaseAllocated);  
        dynamic_mem[i].BaseAllocated = 0;   
        dynamic_mem[i].AlignedAddress = 0;
        break;                        
      }
    }
  }
  else if( n_alloc )                   
  {
    t_alloc = n_alloc + (ab - allocBoundary); 
    alloc_address =                  
      kmalloc( t_alloc, GFP_KERNEL); 
    if( alloc_address )           
    {
      for( i=0; i<DYNAMIC_ALLOCATIONS; i++) 
      {
        if( dynamic_mem[i].BaseAllocated == 0) 
        {
          dynamic_mem[i].BaseAllocated = alloc_address;
          break;
        }
      }
      mask = (LONG)(ab - 1);            
      mask = ~mask;                            
      ulAddress = (unsigned long)alloc_address;
      ulAddress += (ab - allocBoundary);    
      alloc_address = (void*)(ulAddress & mask);
      dynamic_mem[i].AlignedAddress = 
	(ULONG)(ulAddress & mask); 
      memset( alloc_address, 0, n_alloc );  
    }
    else  
      alloc_address = 0;  
  }
  LEAVE("fcMemManager");
  return alloc_address;  
}
void * fcMemManager ( ALIGNED_MEM * dynamic_mem , ULONG n_alloc , ULONG ab , ULONG u32_AlignedAddress ) { USHORT allocBoundary = 1 ; unsigned long ulAddress ; ULONG t_alloc , i ; void * alloc_address = 0 ; LONG mask ; ENTER ( " " ) ; if ( u32_AlignedAddress ) { for ( i = 0 ; i < DYNAMIC_ALLOCATIONS ; i ++ ) { if ( dynamic_mem [ i ] . AlignedAddress == u32_AlignedAddress ) { alloc_address = dynamic_mem [ i ] . BaseAllocated ; kfree ( dynamic_mem [ i ] . BaseAllocated ) ; dynamic_mem [ i ] . BaseAllocated = 0 ; dynamic_mem [ i ] . AlignedAddress = 0 ; break ; } } } else if ( n_alloc ) { t_alloc = n_alloc + ( ab - allocBoundary ) ; alloc_address = kmalloc ( t_alloc , GFP_KERNEL ) ; if ( alloc_address ) { for ( i = 0 ; i < DYNAMIC_ALLOCATIONS ; i ++ ) { if ( dynamic_mem [ i ] . BaseAllocated == 0 ) { dynamic_mem [ i ] . BaseAllocated = alloc_address ; break ; } } mask = ( LONG ) ( ab - 1 ) ; mask = ~ mask ; ulAddress = ( unsigned long ) alloc_address ; ulAddress += ( ab - allocBoundary ) ; alloc_address = ( void * ) ( ulAddress & mask ) ; dynamic_mem [ i ] . AlignedAddress = ( ULONG ) ( ulAddress & mask ) ; memset ( alloc_address , 0 , n_alloc ) ; } else alloc_address = 0 ; } LEAVE ( " " ) ; return alloc_address ; }
we need about 8 allocations per HBA.
we need about 8 allocations per HBA .
// compiler specific - worst case 1 // best case - replace malloc() call // with function that allocates exactly // at desired boundary // def. error code / address not found // must be 32-bits wide! // are we freeing existing memory? //    printk(" freeing AlignedAddress %Xh\n", u32_AlignedAddress); // look for the base address //    printk("dynamic_mem[%u].AlignedAddress %lX\n", i, dynamic_mem[i].AlignedAddress); // 'success' status // return pages to kernel // clear for next use // quit for loop; done // want new memory? // pad bytes for alignment //    printk("kmalloc() for Tach alignment: %ld bytes\n", t_alloc); // total bytes (NumberOfBytes) // allow thread block to free pages  // now mask off least sig. bits of address // (only if non-NULL) // find place to store ptr, so we // can free it later... // look for free slot // take 1st available // address from O/S // mask all low-order bits // invert bits // add the alignment bytes- // then truncate address... // 32bit Tach address // clear new memory // O/S dynamic mem alloc failed! // (for debugging breakpt) // good (or NULL) address