| 
				
			 | 
			
			
				
				@@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); 
			 | 
		
		
	
		
			
			| 
				31
			 | 
			
				31
			 | 
			
			
				
				 #include <byteswap.h> 
			 | 
		
		
	
		
			
			| 
				32
			 | 
			
				32
			 | 
			
			
				
				 #include <ipxe/io.h> 
			 | 
		
		
	
		
			
			| 
				33
			 | 
			
				33
			 | 
			
			
				
				 #include <ipxe/pci.h> 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				
				+#include <ipxe/pcibackup.h> 
			 | 
		
		
	
		
			
			| 
				34
			 | 
			
				35
			 | 
			
			
				
				 #include <ipxe/malloc.h> 
			 | 
		
		
	
		
			
			| 
				35
			 | 
			
				36
			 | 
			
			
				
				 #include <ipxe/umalloc.h> 
			 | 
		
		
	
		
			
			| 
				36
			 | 
			
				37
			 | 
			
			
				
				 #include <ipxe/iobuf.h> 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -1991,7 +1992,7 @@ static int arbel_start_firmware ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				1991
			 | 
			
				1992
			 | 
			
			
				
				 	struct arbelprm_query_fw fw; 
			 | 
		
		
	
		
			
			| 
				1992
			 | 
			
				1993
			 | 
			
			
				
				 	struct arbelprm_access_lam lam; 
			 | 
		
		
	
		
			
			| 
				1993
			 | 
			
				1994
			 | 
			
			
				
				 	unsigned int fw_pages; 
			 | 
		
		
	
		
			
			| 
				1994
			 | 
			
				
			 | 
			
			
				
				-	size_t fw_size; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				1995
			 | 
			
			
				
				+	size_t fw_len; 
			 | 
		
		
	
		
			
			| 
				1995
			 | 
			
				1996
			 | 
			
			
				
				 	physaddr_t fw_base; 
			 | 
		
		
	
		
			
			| 
				1996
			 | 
			
				1997
			 | 
			
			
				
				 	uint64_t eq_set_ci_base_addr; 
			 | 
		
		
	
		
			
			| 
				1997
			 | 
			
				1998
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2019,17 +2020,22 @@ static int arbel_start_firmware ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				2019
			 | 
			
				2020
			 | 
			
			
				
				 	arbel_cmd_enable_lam ( arbel, &lam ); 
			 | 
		
		
	
		
			
			| 
				2020
			 | 
			
				2021
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2021
			 | 
			
				2022
			 | 
			
			
				
				 	/* Allocate firmware pages and map firmware area */ 
			 | 
		
		
	
		
			
			| 
				2022
			 | 
			
				
			 | 
			
			
				
				-	fw_size = ( fw_pages * ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2023
			 | 
			
				
			 | 
			
			
				
				-	arbel->firmware_area = umalloc ( fw_size ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2023
			 | 
			
			
				
				+	fw_len = ( fw_pages * ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2024
			 | 
			
				2024
			 | 
			
			
				
				 	if ( ! arbel->firmware_area ) { 
			 | 
		
		
	
		
			
			| 
				2025
			 | 
			
				
			 | 
			
			
				
				-		rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				2026
			 | 
			
				
			 | 
			
			
				
				-		goto err_alloc_fa; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2025
			 | 
			
			
				
				+		arbel->firmware_len = fw_len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2026
			 | 
			
			
				
				+		arbel->firmware_area = umalloc ( arbel->firmware_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2027
			 | 
			
			
				
				+		if ( ! arbel->firmware_area ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2028
			 | 
			
			
				
				+			rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2029
			 | 
			
			
				
				+			goto err_alloc_fa; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2030
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2031
			 | 
			
			
				
				+	} else { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2032
			 | 
			
			
				
				+		assert ( arbel->firmware_len == fw_len ); 
			 | 
		
		
	
		
			
			| 
				2027
			 | 
			
				2033
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2028
			 | 
			
				2034
			 | 
			
			
				
				 	fw_base = user_to_phys ( arbel->firmware_area, 0 ); 
			 | 
		
		
	
		
			
			| 
				2029
			 | 
			
				2035
			 | 
			
			
				
				 	DBGC ( arbel, "Arbel %p firmware area at [%08lx,%08lx)\n", 
			 | 
		
		
	
		
			
			| 
				2030
			 | 
			
				
			 | 
			
			
				
				-	       arbel, fw_base, ( fw_base + fw_size ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2036
			 | 
			
			
				
				+	       arbel, fw_base, ( fw_base + fw_len ) ); 
			 | 
		
		
	
		
			
			| 
				2031
			 | 
			
				2037
			 | 
			
			
				
				 	if ( ( rc = arbel_map_vpm ( arbel, arbel_cmd_map_fa, 
			 | 
		
		
	
		
			
			| 
				2032
			 | 
			
				
			 | 
			
			
				
				-				    0, fw_base, fw_size ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2038
			 | 
			
			
				
				+				    0, fw_base, fw_len ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				2033
			 | 
			
				2039
			 | 
			
			
				
				 		DBGC ( arbel, "Arbel %p could not map firmware: %s\n", 
			 | 
		
		
	
		
			
			| 
				2034
			 | 
			
				2040
			 | 
			
			
				
				 		       arbel, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				2035
			 | 
			
				2041
			 | 
			
			
				
				 		goto err_map_fa; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2048,8 +2054,6 @@ static int arbel_start_firmware ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				2048
			 | 
			
				2054
			 | 
			
			
				
				  err_run_fw: 
			 | 
		
		
	
		
			
			| 
				2049
			 | 
			
				2055
			 | 
			
			
				
				 	arbel_cmd_unmap_fa ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2050
			 | 
			
				2056
			 | 
			
			
				
				  err_map_fa: 
			 | 
		
		
	
		
			
			| 
				2051
			 | 
			
				
			 | 
			
			
				
				-	ufree ( arbel->firmware_area ); 
			 | 
		
		
	
		
			
			| 
				2052
			 | 
			
				
			 | 
			
			
				
				-	arbel->firmware_area = UNULL; 
			 | 
		
		
	
		
			
			| 
				2053
			 | 
			
				2057
			 | 
			
			
				
				  err_alloc_fa: 
			 | 
		
		
	
		
			
			| 
				2054
			 | 
			
				2058
			 | 
			
			
				
				  err_query_fw: 
			 | 
		
		
	
		
			
			| 
				2055
			 | 
			
				2059
			 | 
			
			
				
				 	return rc; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2067,10 +2071,9 @@ static void arbel_stop_firmware ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				2067
			 | 
			
				2071
			 | 
			
			
				
				 		DBGC ( arbel, "Arbel %p FATAL could not stop firmware: %s\n", 
			 | 
		
		
	
		
			
			| 
				2068
			 | 
			
				2072
			 | 
			
			
				
				 		       arbel, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				2069
			 | 
			
				2073
			 | 
			
			
				
				 		/* Leak memory and return; at least we avoid corruption */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2074
			 | 
			
			
				
				+		arbel->firmware_area = UNULL; 
			 | 
		
		
	
		
			
			| 
				2070
			 | 
			
				2075
			 | 
			
			
				
				 		return; 
			 | 
		
		
	
		
			
			| 
				2071
			 | 
			
				2076
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2072
			 | 
			
				
			 | 
			
			
				
				-	ufree ( arbel->firmware_area ); 
			 | 
		
		
	
		
			
			| 
				2073
			 | 
			
				
			 | 
			
			
				
				-	arbel->firmware_area = UNULL; 
			 | 
		
		
	
		
			
			| 
				2074
			 | 
			
				2077
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2075
			 | 
			
				2078
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2076
			 | 
			
				2079
			 | 
			
			
				
				 /*************************************************************************** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2180,6 +2183,7 @@ static int arbel_alloc_icm ( struct arbel *arbel, 
			 | 
		
		
	
		
			
			| 
				2180
			 | 
			
				2183
			 | 
			
			
				
				 	unsigned int log_num_uars, log_num_qps, log_num_srqs, log_num_ees; 
			 | 
		
		
	
		
			
			| 
				2181
			 | 
			
				2184
			 | 
			
			
				
				 	unsigned int log_num_cqs, log_num_mtts, log_num_mpts, log_num_rdbs; 
			 | 
		
		
	
		
			
			| 
				2182
			 | 
			
				2185
			 | 
			
			
				
				 	unsigned int log_num_eqs, log_num_mcs; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2186
			 | 
			
			
				
				+	size_t icm_len, icm_aux_len; 
			 | 
		
		
	
		
			
			| 
				2183
			 | 
			
				2187
			 | 
			
			
				
				 	size_t len; 
			 | 
		
		
	
		
			
			| 
				2184
			 | 
			
				2188
			 | 
			
			
				
				 	physaddr_t icm_phys; 
			 | 
		
		
	
		
			
			| 
				2185
			 | 
			
				2189
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2351,7 +2355,7 @@ static int arbel_alloc_icm ( struct arbel *arbel, 
			 | 
		
		
	
		
			
			| 
				2351
			 | 
			
				2355
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2352
			 | 
			
				2356
			 | 
			
			
				
				 	/* Record amount of ICM to be allocated */ 
			 | 
		
		
	
		
			
			| 
				2353
			 | 
			
				2357
			 | 
			
			
				
				 	icm_offset = icm_align ( icm_offset, ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2354
			 | 
			
				
			 | 
			
			
				
				-	arbel->icm_len = icm_offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2358
			 | 
			
			
				
				+	icm_len = icm_offset; 
			 | 
		
		
	
		
			
			| 
				2355
			 | 
			
				2359
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2356
			 | 
			
				2360
			 | 
			
			
				
				 	/* User access region contexts 
			 | 
		
		
	
		
			
			| 
				2357
			 | 
			
				2361
			 | 
			
			
				
				 	 * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2376,24 +2380,29 @@ static int arbel_alloc_icm ( struct arbel *arbel, 
			 | 
		
		
	
		
			
			| 
				2376
			 | 
			
				2380
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2377
			 | 
			
				2381
			 | 
			
			
				
				 	/* Get ICM auxiliary area size */ 
			 | 
		
		
	
		
			
			| 
				2378
			 | 
			
				2382
			 | 
			
			
				
				 	memset ( &icm_size, 0, sizeof ( icm_size ) ); 
			 | 
		
		
	
		
			
			| 
				2379
			 | 
			
				
			 | 
			
			
				
				-	MLX_FILL_1 ( &icm_size, 1, value, arbel->icm_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2383
			 | 
			
			
				
				+	MLX_FILL_1 ( &icm_size, 1, value, icm_len ); 
			 | 
		
		
	
		
			
			| 
				2380
			 | 
			
				2384
			 | 
			
			
				
				 	if ( ( rc = arbel_cmd_set_icm_size ( arbel, &icm_size, 
			 | 
		
		
	
		
			
			| 
				2381
			 | 
			
				2385
			 | 
			
			
				
				 					     &icm_aux_size ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				2382
			 | 
			
				2386
			 | 
			
			
				
				 		DBGC ( arbel, "Arbel %p could not set ICM size: %s\n", 
			 | 
		
		
	
		
			
			| 
				2383
			 | 
			
				2387
			 | 
			
			
				
				 		       arbel, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				2384
			 | 
			
				2388
			 | 
			
			
				
				 		goto err_set_icm_size; 
			 | 
		
		
	
		
			
			| 
				2385
			 | 
			
				2389
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2386
			 | 
			
				
			 | 
			
			
				
				-	arbel->icm_aux_len = 
			 | 
		
		
	
		
			
			| 
				2387
			 | 
			
				
			 | 
			
			
				
				-		( MLX_GET ( &icm_aux_size, value ) * ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2390
			 | 
			
			
				
				+	icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2388
			 | 
			
				2391
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2389
			 | 
			
				2392
			 | 
			
			
				
				 	/* Allocate ICM data and auxiliary area */ 
			 | 
		
		
	
		
			
			| 
				2390
			 | 
			
				2393
			 | 
			
			
				
				 	DBGC ( arbel, "Arbel %p requires %zd kB ICM and %zd kB AUX ICM\n", 
			 | 
		
		
	
		
			
			| 
				2391
			 | 
			
				
			 | 
			
			
				
				-	       arbel, ( arbel->icm_len / 1024 ), 
			 | 
		
		
	
		
			
			| 
				2392
			 | 
			
				
			 | 
			
			
				
				-	       ( arbel->icm_aux_len / 1024 ) ); 
			 | 
		
		
	
		
			
			| 
				2393
			 | 
			
				
			 | 
			
			
				
				-	arbel->icm = umalloc ( arbel->icm_len + arbel->icm_aux_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2394
			 | 
			
			
				
				+	       arbel, ( icm_len / 1024 ), ( icm_aux_len / 1024 ) ); 
			 | 
		
		
	
		
			
			| 
				2394
			 | 
			
				2395
			 | 
			
			
				
				 	if ( ! arbel->icm ) { 
			 | 
		
		
	
		
			
			| 
				2395
			 | 
			
				
			 | 
			
			
				
				-		rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				2396
			 | 
			
				
			 | 
			
			
				
				-		goto err_alloc_icm; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2396
			 | 
			
			
				
				+		arbel->icm_len = icm_len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2397
			 | 
			
			
				
				+		arbel->icm_aux_len = icm_aux_len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2398
			 | 
			
			
				
				+		arbel->icm = umalloc ( arbel->icm_len + arbel->icm_aux_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2399
			 | 
			
			
				
				+		if ( ! arbel->icm ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2400
			 | 
			
			
				
				+			rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2401
			 | 
			
			
				
				+			goto err_alloc_icm; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2402
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2403
			 | 
			
			
				
				+	} else { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2404
			 | 
			
			
				
				+		assert ( arbel->icm_len == icm_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2405
			 | 
			
			
				
				+		assert ( arbel->icm_aux_len == icm_aux_len ); 
			 | 
		
		
	
		
			
			| 
				2397
			 | 
			
				2406
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2398
			 | 
			
				2407
			 | 
			
			
				
				 	icm_phys = user_to_phys ( arbel->icm, 0 ); 
			 | 
		
		
	
		
			
			| 
				2399
			 | 
			
				2408
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2459,8 +2468,6 @@ static int arbel_alloc_icm ( struct arbel *arbel, 
			 | 
		
		
	
		
			
			| 
				2459
			 | 
			
				2468
			 | 
			
			
				
				 	free_dma ( arbel->db_rec, ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2460
			 | 
			
				2469
			 | 
			
			
				
				 	arbel->db_rec= NULL; 
			 | 
		
		
	
		
			
			| 
				2461
			 | 
			
				2470
			 | 
			
			
				
				  err_alloc_doorbell: 
			 | 
		
		
	
		
			
			| 
				2462
			 | 
			
				
			 | 
			
			
				
				-	ufree ( arbel->icm ); 
			 | 
		
		
	
		
			
			| 
				2463
			 | 
			
				
			 | 
			
			
				
				-	arbel->icm = UNULL; 
			 | 
		
		
	
		
			
			| 
				2464
			 | 
			
				2471
			 | 
			
			
				
				  err_alloc_icm: 
			 | 
		
		
	
		
			
			| 
				2465
			 | 
			
				2472
			 | 
			
			
				
				  err_set_icm_size: 
			 | 
		
		
	
		
			
			| 
				2466
			 | 
			
				2473
			 | 
			
			
				
				 	return rc; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2483,17 +2490,41 @@ static void arbel_free_icm ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				2483
			 | 
			
				2490
			 | 
			
			
				
				 	arbel_cmd_unmap_icm_aux ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2484
			 | 
			
				2491
			 | 
			
			
				
				 	free_dma ( arbel->db_rec, ARBEL_PAGE_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2485
			 | 
			
				2492
			 | 
			
			
				
				 	arbel->db_rec = NULL; 
			 | 
		
		
	
		
			
			| 
				2486
			 | 
			
				
			 | 
			
			
				
				-	ufree ( arbel->icm ); 
			 | 
		
		
	
		
			
			| 
				2487
			 | 
			
				
			 | 
			
			
				
				-	arbel->icm = UNULL; 
			 | 
		
		
	
		
			
			| 
				2488
			 | 
			
				2493
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2489
			 | 
			
				2494
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2490
			 | 
			
				2495
			 | 
			
			
				
				 /*************************************************************************** 
			 | 
		
		
	
		
			
			| 
				2491
			 | 
			
				2496
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				2492
			 | 
			
				
			 | 
			
			
				
				- * Initialisation 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2497
			 | 
			
			
				
				+ * Initialisation and teardown 
			 | 
		
		
	
		
			
			| 
				2493
			 | 
			
				2498
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				2494
			 | 
			
				2499
			 | 
			
			
				
				  *************************************************************************** 
			 | 
		
		
	
		
			
			| 
				2495
			 | 
			
				2500
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				2496
			 | 
			
				2501
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2502
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2503
			 | 
			
			
				
				+ * Reset device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2504
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2505
			 | 
			
			
				
				+ * @v arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2506
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2507
			 | 
			
			
				
				+static void arbel_reset ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2508
			 | 
			
			
				
				+	struct pci_device *pci = arbel->pci; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2509
			 | 
			
			
				
				+	struct pci_config_backup backup; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2510
			 | 
			
			
				
				+	static const uint8_t backup_exclude[] = 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2511
			 | 
			
			
				
				+		PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2512
			 | 
			
			
				
				+	uint16_t vendor; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2513
			 | 
			
			
				
				+	unsigned int i; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2514
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2515
			 | 
			
			
				
				+	/* Perform device reset and preserve PCI configuration */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2516
			 | 
			
			
				
				+	pci_backup ( pci, &backup, backup_exclude ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2517
			 | 
			
			
				
				+	writel ( ARBEL_RESET_MAGIC, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2518
			 | 
			
			
				
				+		 ( arbel->config + ARBEL_RESET_OFFSET ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2519
			 | 
			
			
				
				+	for ( i = 0 ; i < ARBEL_RESET_WAIT_TIME_MS ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2520
			 | 
			
			
				
				+		mdelay ( 1 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2521
			 | 
			
			
				
				+		pci_read_config_word ( pci, PCI_VENDOR_ID, &vendor ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2522
			 | 
			
			
				
				+		if ( vendor != 0xffff ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2523
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2524
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2525
			 | 
			
			
				
				+	pci_restore ( pci, &backup, backup_exclude ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2526
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2527
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				2497
			 | 
			
				2528
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				2498
			 | 
			
				2529
			 | 
			
			
				
				  * Set up memory protection table 
			 | 
		
		
	
		
			
			| 
				2499
			 | 
			
				2530
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2572,6 +2603,115 @@ static int arbel_configure_special_qps ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				2572
			 | 
			
				2603
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				2573
			 | 
			
				2604
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2574
			 | 
			
				2605
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2606
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2607
			 | 
			
			
				
				+ * Start Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2608
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2609
			 | 
			
			
				
				+ * @v arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2610
			 | 
			
			
				
				+ * @v running		Firmware is already running 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2611
			 | 
			
			
				
				+ * @ret rc		Return status code 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2612
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2613
			 | 
			
			
				
				+static int arbel_start ( struct arbel *arbel, int running ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2614
			 | 
			
			
				
				+	struct arbelprm_init_hca init_hca; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2615
			 | 
			
			
				
				+	unsigned int i; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2616
			 | 
			
			
				
				+	int rc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2617
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2618
			 | 
			
			
				
				+	/* Start firmware if not already running */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2619
			 | 
			
			
				
				+	if ( ! running ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2620
			 | 
			
			
				
				+		if ( ( rc = arbel_start_firmware ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2621
			 | 
			
			
				
				+			goto err_start_firmware; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2622
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2623
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2624
			 | 
			
			
				
				+	/* Allocate ICM */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2625
			 | 
			
			
				
				+	memset ( &init_hca, 0, sizeof ( init_hca ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2626
			 | 
			
			
				
				+	if ( ( rc = arbel_alloc_icm ( arbel, &init_hca ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2627
			 | 
			
			
				
				+		goto err_alloc_icm; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2628
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2629
			 | 
			
			
				
				+	/* Initialise HCA */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2630
			 | 
			
			
				
				+	if ( ( rc = arbel_cmd_init_hca ( arbel, &init_hca ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2631
			 | 
			
			
				
				+		DBGC ( arbel, "Arbel %p could not initialise HCA: %s\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2632
			 | 
			
			
				
				+		       arbel, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2633
			 | 
			
			
				
				+		goto err_init_hca; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2634
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2635
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2636
			 | 
			
			
				
				+	/* Set up memory protection */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2637
			 | 
			
			
				
				+	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2638
			 | 
			
			
				
				+		goto err_setup_mpt; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2639
			 | 
			
			
				
				+	for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2640
			 | 
			
			
				
				+		arbel->ibdev[i]->rdma_key = arbel->lkey; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2641
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2642
			 | 
			
			
				
				+	/* Set up event queue */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2643
			 | 
			
			
				
				+	if ( ( rc = arbel_create_eq ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2644
			 | 
			
			
				
				+		goto err_create_eq; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2645
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2646
			 | 
			
			
				
				+	/* Configure special QPs */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2647
			 | 
			
			
				
				+	if ( ( rc = arbel_configure_special_qps ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2648
			 | 
			
			
				
				+		goto err_conf_special_qps; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2649
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2650
			 | 
			
			
				
				+	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2651
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2652
			 | 
			
			
				
				+ err_conf_special_qps: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2653
			 | 
			
			
				
				+	arbel_destroy_eq ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2654
			 | 
			
			
				
				+ err_create_eq: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2655
			 | 
			
			
				
				+ err_setup_mpt: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2656
			 | 
			
			
				
				+	arbel_cmd_close_hca ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2657
			 | 
			
			
				
				+ err_init_hca: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2658
			 | 
			
			
				
				+	arbel_free_icm ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2659
			 | 
			
			
				
				+ err_alloc_icm: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2660
			 | 
			
			
				
				+	arbel_stop_firmware ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2661
			 | 
			
			
				
				+ err_start_firmware: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2662
			 | 
			
			
				
				+	return rc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2663
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2664
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2665
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2666
			 | 
			
			
				
				+ * Stop Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2667
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2668
			 | 
			
			
				
				+ * @v arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2669
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2670
			 | 
			
			
				
				+static void arbel_stop ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2671
			 | 
			
			
				
				+	arbel_destroy_eq ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2672
			 | 
			
			
				
				+	arbel_cmd_close_hca ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2673
			 | 
			
			
				
				+	arbel_free_icm ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2674
			 | 
			
			
				
				+	arbel_stop_firmware ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2675
			 | 
			
			
				
				+	arbel_reset ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2676
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2677
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2678
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2679
			 | 
			
			
				
				+ * Open Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2680
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2681
			 | 
			
			
				
				+ * @v arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2682
			 | 
			
			
				
				+ * @ret rc		Return status code 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2683
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2684
			 | 
			
			
				
				+static int arbel_open ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2685
			 | 
			
			
				
				+	int rc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2686
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2687
			 | 
			
			
				
				+	/* Start device if applicable */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2688
			 | 
			
			
				
				+	if ( arbel->open_count == 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2689
			 | 
			
			
				
				+		if ( ( rc = arbel_start ( arbel, 0 ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2690
			 | 
			
			
				
				+			return rc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2691
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2692
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2693
			 | 
			
			
				
				+	/* Increment open counter */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2694
			 | 
			
			
				
				+	arbel->open_count++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2695
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2696
			 | 
			
			
				
				+	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2697
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2698
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2699
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2700
			 | 
			
			
				
				+ * Close Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2701
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2702
			 | 
			
			
				
				+ * @v arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2703
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2704
			 | 
			
			
				
				+static void arbel_close ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2705
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2706
			 | 
			
			
				
				+	/* Decrement open counter */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2707
			 | 
			
			
				
				+	assert ( arbel->open_count != 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2708
			 | 
			
			
				
				+	arbel->open_count--; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2709
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2710
			 | 
			
			
				
				+	/* Stop device if applicable */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2711
			 | 
			
			
				
				+	if ( arbel->open_count == 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2712
			 | 
			
			
				
				+		arbel_stop ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2713
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2714
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				2575
			 | 
			
				2715
			 | 
			
			
				
				 /*************************************************************************** 
			 | 
		
		
	
		
			
			| 
				2576
			 | 
			
				2716
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				2577
			 | 
			
				2717
			 | 
			
			
				
				  * Infiniband link-layer operations 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2585,11 +2725,16 @@ static int arbel_configure_special_qps ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				2585
			 | 
			
				2725
			 | 
			
			
				
				  * @v ibdev		Infiniband device 
			 | 
		
		
	
		
			
			| 
				2586
			 | 
			
				2726
			 | 
			
			
				
				  * @ret rc		Return status code 
			 | 
		
		
	
		
			
			| 
				2587
			 | 
			
				2727
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				2588
			 | 
			
				
			 | 
			
			
				
				-static int arbel_open ( struct ib_device *ibdev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2728
			 | 
			
			
				
				+static int arbel_ib_open ( struct ib_device *ibdev ) { 
			 | 
		
		
	
		
			
			| 
				2589
			 | 
			
				2729
			 | 
			
			
				
				 	struct arbel *arbel = ib_get_drvdata ( ibdev ); 
			 | 
		
		
	
		
			
			| 
				2590
			 | 
			
				2730
			 | 
			
			
				
				 	struct arbelprm_init_ib init_ib; 
			 | 
		
		
	
		
			
			| 
				2591
			 | 
			
				2731
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				2592
			 | 
			
				2732
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2733
			 | 
			
			
				
				+	/* Open hardware */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2734
			 | 
			
			
				
				+	if ( ( rc = arbel_open ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2735
			 | 
			
			
				
				+		goto err_open; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2736
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2737
			 | 
			
			
				
				+	/* Initialise IB */ 
			 | 
		
		
	
		
			
			| 
				2593
			 | 
			
				2738
			 | 
			
			
				
				 	memset ( &init_ib, 0, sizeof ( init_ib ) ); 
			 | 
		
		
	
		
			
			| 
				2594
			 | 
			
				2739
			 | 
			
			
				
				 	MLX_FILL_3 ( &init_ib, 0, 
			 | 
		
		
	
		
			
			| 
				2595
			 | 
			
				2740
			 | 
			
			
				
				 		     mtu_cap, ARBEL_MTU_2048, 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2601,13 +2746,18 @@ static int arbel_open ( struct ib_device *ibdev ) { 
			 | 
		
		
	
		
			
			| 
				2601
			 | 
			
				2746
			 | 
			
			
				
				 					&init_ib ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				2602
			 | 
			
				2747
			 | 
			
			
				
				 		DBGC ( arbel, "Arbel %p port %d could not intialise IB: %s\n", 
			 | 
		
		
	
		
			
			| 
				2603
			 | 
			
				2748
			 | 
			
			
				
				 		       arbel, ibdev->port, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				2604
			 | 
			
				
			 | 
			
			
				
				-		return rc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2749
			 | 
			
			
				
				+		goto err_init_ib; 
			 | 
		
		
	
		
			
			| 
				2605
			 | 
			
				2750
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2606
			 | 
			
				2751
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2607
			 | 
			
				2752
			 | 
			
			
				
				 	/* Update MAD parameters */ 
			 | 
		
		
	
		
			
			| 
				2608
			 | 
			
				2753
			 | 
			
			
				
				 	ib_smc_update ( ibdev, arbel_mad ); 
			 | 
		
		
	
		
			
			| 
				2609
			 | 
			
				2754
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2610
			 | 
			
				2755
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2756
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2757
			 | 
			
			
				
				+ err_init_ib: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2758
			 | 
			
			
				
				+	arbel_close ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2759
			 | 
			
			
				
				+ err_open: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2760
			 | 
			
			
				
				+	return rc; 
			 | 
		
		
	
		
			
			| 
				2611
			 | 
			
				2761
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2612
			 | 
			
				2762
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2613
			 | 
			
				2763
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2615,15 +2765,19 @@ static int arbel_open ( struct ib_device *ibdev ) { 
			 | 
		
		
	
		
			
			| 
				2615
			 | 
			
				2765
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				2616
			 | 
			
				2766
			 | 
			
			
				
				  * @v ibdev		Infiniband device 
			 | 
		
		
	
		
			
			| 
				2617
			 | 
			
				2767
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				2618
			 | 
			
				
			 | 
			
			
				
				-static void arbel_close ( struct ib_device *ibdev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2768
			 | 
			
			
				
				+static void arbel_ib_close ( struct ib_device *ibdev ) { 
			 | 
		
		
	
		
			
			| 
				2619
			 | 
			
				2769
			 | 
			
			
				
				 	struct arbel *arbel = ib_get_drvdata ( ibdev ); 
			 | 
		
		
	
		
			
			| 
				2620
			 | 
			
				2770
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				2621
			 | 
			
				2771
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2772
			 | 
			
			
				
				+	/* Close IB */ 
			 | 
		
		
	
		
			
			| 
				2622
			 | 
			
				2773
			 | 
			
			
				
				 	if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				2623
			 | 
			
				2774
			 | 
			
			
				
				 		DBGC ( arbel, "Arbel %p port %d could not close IB: %s\n", 
			 | 
		
		
	
		
			
			| 
				2624
			 | 
			
				2775
			 | 
			
			
				
				 		       arbel, ibdev->port, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				2625
			 | 
			
				2776
			 | 
			
			
				
				 		/* Nothing we can do about this */ 
			 | 
		
		
	
		
			
			| 
				2626
			 | 
			
				2777
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2778
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2779
			 | 
			
			
				
				+	/* Close hardware */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2780
			 | 
			
			
				
				+	arbel_close ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2627
			 | 
			
				2781
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2628
			 | 
			
				2782
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2629
			 | 
			
				2783
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2753,8 +2907,8 @@ static struct ib_device_operations arbel_ib_operations = { 
			 | 
		
		
	
		
			
			| 
				2753
			 | 
			
				2907
			 | 
			
			
				
				 	.post_recv	= arbel_post_recv, 
			 | 
		
		
	
		
			
			| 
				2754
			 | 
			
				2908
			 | 
			
			
				
				 	.poll_cq	= arbel_poll_cq, 
			 | 
		
		
	
		
			
			| 
				2755
			 | 
			
				2909
			 | 
			
			
				
				 	.poll_eq	= arbel_poll_eq, 
			 | 
		
		
	
		
			
			| 
				2756
			 | 
			
				
			 | 
			
			
				
				-	.open		= arbel_open, 
			 | 
		
		
	
		
			
			| 
				2757
			 | 
			
				
			 | 
			
			
				
				-	.close		= arbel_close, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2910
			 | 
			
			
				
				+	.open		= arbel_ib_open, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2911
			 | 
			
			
				
				+	.close		= arbel_ib_close, 
			 | 
		
		
	
		
			
			| 
				2758
			 | 
			
				2912
			 | 
			
			
				
				 	.mcast_attach	= arbel_mcast_attach, 
			 | 
		
		
	
		
			
			| 
				2759
			 | 
			
				2913
			 | 
			
			
				
				 	.mcast_detach	= arbel_mcast_detach, 
			 | 
		
		
	
		
			
			| 
				2760
			 | 
			
				2914
			 | 
			
			
				
				 	.set_port_info	= arbel_inform_sma, 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2768,6 +2922,52 @@ static struct ib_device_operations arbel_ib_operations = { 
			 | 
		
		
	
		
			
			| 
				2768
			 | 
			
				2922
			 | 
			
			
				
				  *************************************************************************** 
			 | 
		
		
	
		
			
			| 
				2769
			 | 
			
				2923
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				2770
			 | 
			
				2924
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2925
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2926
			 | 
			
			
				
				+ * Allocate Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2927
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2928
			 | 
			
			
				
				+ * @ret arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2929
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2930
			 | 
			
			
				
				+static struct arbel * arbel_alloc ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2931
			 | 
			
			
				
				+	struct arbel *arbel; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2932
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2933
			 | 
			
			
				
				+	/* Allocate Arbel device */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2934
			 | 
			
			
				
				+	arbel = zalloc ( sizeof ( *arbel ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2935
			 | 
			
			
				
				+	if ( ! arbel ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2936
			 | 
			
			
				
				+		goto err_arbel; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2937
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2938
			 | 
			
			
				
				+	/* Allocate space for mailboxes */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2939
			 | 
			
			
				
				+	arbel->mailbox_in = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2940
			 | 
			
			
				
				+	if ( ! arbel->mailbox_in ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2941
			 | 
			
			
				
				+		goto err_mailbox_in; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2942
			 | 
			
			
				
				+	arbel->mailbox_out = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2943
			 | 
			
			
				
				+	if ( ! arbel->mailbox_out ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2944
			 | 
			
			
				
				+		goto err_mailbox_out; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2945
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2946
			 | 
			
			
				
				+	return arbel; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2947
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2948
			 | 
			
			
				
				+	free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2949
			 | 
			
			
				
				+ err_mailbox_out: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2950
			 | 
			
			
				
				+	free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2951
			 | 
			
			
				
				+ err_mailbox_in: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2952
			 | 
			
			
				
				+	free ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2953
			 | 
			
			
				
				+ err_arbel: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2954
			 | 
			
			
				
				+	return NULL; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2955
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2956
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2957
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2958
			 | 
			
			
				
				+ * Free Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2959
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2960
			 | 
			
			
				
				+ * @v arbel		Arbel device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2961
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2962
			 | 
			
			
				
				+static void arbel_free ( struct arbel *arbel ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2963
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2964
			 | 
			
			
				
				+	ufree ( arbel->icm ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2965
			 | 
			
			
				
				+	ufree ( arbel->firmware_area ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2966
			 | 
			
			
				
				+	free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2967
			 | 
			
			
				
				+	free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2968
			 | 
			
			
				
				+	free ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2969
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2970
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				2771
			 | 
			
				2971
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				2772
			 | 
			
				2972
			 | 
			
			
				
				  * Probe PCI device 
			 | 
		
		
	
		
			
			| 
				2773
			 | 
			
				2973
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2778,17 +2978,17 @@ static struct ib_device_operations arbel_ib_operations = { 
			 | 
		
		
	
		
			
			| 
				2778
			 | 
			
				2978
			 | 
			
			
				
				 static int arbel_probe ( struct pci_device *pci ) { 
			 | 
		
		
	
		
			
			| 
				2779
			 | 
			
				2979
			 | 
			
			
				
				 	struct arbel *arbel; 
			 | 
		
		
	
		
			
			| 
				2780
			 | 
			
				2980
			 | 
			
			
				
				 	struct ib_device *ibdev; 
			 | 
		
		
	
		
			
			| 
				2781
			 | 
			
				
			 | 
			
			
				
				-	struct arbelprm_init_hca init_hca; 
			 | 
		
		
	
		
			
			| 
				2782
			 | 
			
				2981
			 | 
			
			
				
				 	int i; 
			 | 
		
		
	
		
			
			| 
				2783
			 | 
			
				2982
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				2784
			 | 
			
				2983
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2785
			 | 
			
				2984
			 | 
			
			
				
				 	/* Allocate Arbel device */ 
			 | 
		
		
	
		
			
			| 
				2786
			 | 
			
				
			 | 
			
			
				
				-	arbel = zalloc ( sizeof ( *arbel ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2985
			 | 
			
			
				
				+	arbel = arbel_alloc(); 
			 | 
		
		
	
		
			
			| 
				2787
			 | 
			
				2986
			 | 
			
			
				
				 	if ( ! arbel ) { 
			 | 
		
		
	
		
			
			| 
				2788
			 | 
			
				2987
			 | 
			
			
				
				 		rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				2789
			 | 
			
				
			 | 
			
			
				
				-		goto err_alloc_arbel; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2988
			 | 
			
			
				
				+		goto err_alloc; 
			 | 
		
		
	
		
			
			| 
				2790
			 | 
			
				2989
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2791
			 | 
			
				2990
			 | 
			
			
				
				 	pci_set_drvdata ( pci, arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2991
			 | 
			
			
				
				+	arbel->pci = pci; 
			 | 
		
		
	
		
			
			| 
				2792
			 | 
			
				2992
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2793
			 | 
			
				2993
			 | 
			
			
				
				 	/* Allocate Infiniband devices */ 
			 | 
		
		
	
		
			
			| 
				2794
			 | 
			
				2994
			 | 
			
			
				
				 	for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) { 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2814,17 +3014,8 @@ static int arbel_probe ( struct pci_device *pci ) { 
			 | 
		
		
	
		
			
			| 
				2814
			 | 
			
				3014
			 | 
			
			
				
				 				 ARBEL_PCI_UAR_IDX * ARBEL_PCI_UAR_SIZE ), 
			 | 
		
		
	
		
			
			| 
				2815
			 | 
			
				3015
			 | 
			
			
				
				 			       ARBEL_PCI_UAR_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2816
			 | 
			
				3016
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2817
			 | 
			
				
			 | 
			
			
				
				-	/* Allocate space for mailboxes */ 
			 | 
		
		
	
		
			
			| 
				2818
			 | 
			
				
			 | 
			
			
				
				-	arbel->mailbox_in = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN ); 
			 | 
		
		
	
		
			
			| 
				2819
			 | 
			
				
			 | 
			
			
				
				-	if ( ! arbel->mailbox_in ) { 
			 | 
		
		
	
		
			
			| 
				2820
			 | 
			
				
			 | 
			
			
				
				-		rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				2821
			 | 
			
				
			 | 
			
			
				
				-		goto err_mailbox_in; 
			 | 
		
		
	
		
			
			| 
				2822
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				2823
			 | 
			
				
			 | 
			
			
				
				-	arbel->mailbox_out = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN ); 
			 | 
		
		
	
		
			
			| 
				2824
			 | 
			
				
			 | 
			
			
				
				-	if ( ! arbel->mailbox_out ) { 
			 | 
		
		
	
		
			
			| 
				2825
			 | 
			
				
			 | 
			
			
				
				-		rc = -ENOMEM; 
			 | 
		
		
	
		
			
			| 
				2826
			 | 
			
				
			 | 
			
			
				
				-		goto err_mailbox_out; 
			 | 
		
		
	
		
			
			| 
				2827
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3017
			 | 
			
			
				
				+	/* Reset device */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3018
			 | 
			
			
				
				+	arbel_reset ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2828
			 | 
			
				3019
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2829
			 | 
			
				3020
			 | 
			
			
				
				 	/* Start firmware */ 
			 | 
		
		
	
		
			
			| 
				2830
			 | 
			
				3021
			 | 
			
			
				
				 	if ( ( rc = arbel_start_firmware ( arbel ) ) != 0 ) 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2834,31 +3025,9 @@ static int arbel_probe ( struct pci_device *pci ) { 
			 | 
		
		
	
		
			
			| 
				2834
			 | 
			
				3025
			 | 
			
			
				
				 	if ( ( rc = arbel_get_limits ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				2835
			 | 
			
				3026
			 | 
			
			
				
				 		goto err_get_limits; 
			 | 
		
		
	
		
			
			| 
				2836
			 | 
			
				3027
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2837
			 | 
			
				
			 | 
			
			
				
				-	/* Allocate ICM */ 
			 | 
		
		
	
		
			
			| 
				2838
			 | 
			
				
			 | 
			
			
				
				-	memset ( &init_hca, 0, sizeof ( init_hca ) ); 
			 | 
		
		
	
		
			
			| 
				2839
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = arbel_alloc_icm ( arbel, &init_hca ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				2840
			 | 
			
				
			 | 
			
			
				
				-		goto err_alloc_icm; 
			 | 
		
		
	
		
			
			| 
				2841
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				2842
			 | 
			
				
			 | 
			
			
				
				-	/* Initialise HCA */ 
			 | 
		
		
	
		
			
			| 
				2843
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = arbel_cmd_init_hca ( arbel, &init_hca ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				2844
			 | 
			
				
			 | 
			
			
				
				-		DBGC ( arbel, "Arbel %p could not initialise HCA: %s\n", 
			 | 
		
		
	
		
			
			| 
				2845
			 | 
			
				
			 | 
			
			
				
				-		       arbel, strerror ( rc ) ); 
			 | 
		
		
	
		
			
			| 
				2846
			 | 
			
				
			 | 
			
			
				
				-		goto err_init_hca; 
			 | 
		
		
	
		
			
			| 
				2847
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				2848
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				2849
			 | 
			
				
			 | 
			
			
				
				-	/* Set up memory protection */ 
			 | 
		
		
	
		
			
			| 
				2850
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				2851
			 | 
			
				
			 | 
			
			
				
				-		goto err_setup_mpt; 
			 | 
		
		
	
		
			
			| 
				2852
			 | 
			
				
			 | 
			
			
				
				-	for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) 
			 | 
		
		
	
		
			
			| 
				2853
			 | 
			
				
			 | 
			
			
				
				-		arbel->ibdev[i]->rdma_key = arbel->lkey; 
			 | 
		
		
	
		
			
			| 
				2854
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				2855
			 | 
			
				
			 | 
			
			
				
				-	/* Set up event queue */ 
			 | 
		
		
	
		
			
			| 
				2856
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = arbel_create_eq ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				2857
			 | 
			
				
			 | 
			
			
				
				-		goto err_create_eq; 
			 | 
		
		
	
		
			
			| 
				2858
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				2859
			 | 
			
				
			 | 
			
			
				
				-	/* Configure special QPs */ 
			 | 
		
		
	
		
			
			| 
				2860
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = arbel_configure_special_qps ( arbel ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				2861
			 | 
			
				
			 | 
			
			
				
				-		goto err_conf_special_qps; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3028
			 | 
			
			
				
				+	/* Start device */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3029
			 | 
			
			
				
				+	if ( ( rc = arbel_start ( arbel, 1 ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3030
			 | 
			
			
				
				+		goto err_start; 
			 | 
		
		
	
		
			
			| 
				2862
			 | 
			
				3031
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2863
			 | 
			
				3032
			 | 
			
			
				
				 	/* Initialise parameters using SMC */ 
			 | 
		
		
	
		
			
			| 
				2864
			 | 
			
				3033
			 | 
			
			
				
				 	for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2874,33 +3043,27 @@ static int arbel_probe ( struct pci_device *pci ) { 
			 | 
		
		
	
		
			
			| 
				2874
			 | 
			
				3043
			 | 
			
			
				
				 		} 
			 | 
		
		
	
		
			
			| 
				2875
			 | 
			
				3044
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				2876
			 | 
			
				3045
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3046
			 | 
			
			
				
				+	/* Leave device quiescent until opened */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3047
			 | 
			
			
				
				+	if ( arbel->open_count == 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3048
			 | 
			
			
				
				+		arbel_stop ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3049
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				2877
			 | 
			
				3050
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				2878
			 | 
			
				3051
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2879
			 | 
			
				3052
			 | 
			
			
				
				 	i = ARBEL_NUM_PORTS; 
			 | 
		
		
	
		
			
			| 
				2880
			 | 
			
				3053
			 | 
			
			
				
				  err_register_ibdev: 
			 | 
		
		
	
		
			
			| 
				2881
			 | 
			
				3054
			 | 
			
			
				
				 	for ( i-- ; i >= 0 ; i-- ) 
			 | 
		
		
	
		
			
			| 
				2882
			 | 
			
				3055
			 | 
			
			
				
				 		unregister_ibdev ( arbel->ibdev[i] ); 
			 | 
		
		
	
		
			
			| 
				2883
			 | 
			
				
			 | 
			
			
				
				- err_conf_special_qps: 
			 | 
		
		
	
		
			
			| 
				2884
			 | 
			
				
			 | 
			
			
				
				-	arbel_destroy_eq ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2885
			 | 
			
				
			 | 
			
			
				
				- err_create_eq: 
			 | 
		
		
	
		
			
			| 
				2886
			 | 
			
				
			 | 
			
			
				
				- err_setup_mpt: 
			 | 
		
		
	
		
			
			| 
				2887
			 | 
			
				
			 | 
			
			
				
				-	arbel_cmd_close_hca ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2888
			 | 
			
				
			 | 
			
			
				
				- err_init_hca: 
			 | 
		
		
	
		
			
			| 
				2889
			 | 
			
				
			 | 
			
			
				
				-	arbel_free_icm ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2890
			 | 
			
				
			 | 
			
			
				
				- err_alloc_icm: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3056
			 | 
			
			
				
				+	arbel_stop ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3057
			 | 
			
			
				
				+ err_start: 
			 | 
		
		
	
		
			
			| 
				2891
			 | 
			
				3058
			 | 
			
			
				
				  err_get_limits: 
			 | 
		
		
	
		
			
			| 
				2892
			 | 
			
				3059
			 | 
			
			
				
				 	arbel_stop_firmware ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2893
			 | 
			
				3060
			 | 
			
			
				
				  err_start_firmware: 
			 | 
		
		
	
		
			
			| 
				2894
			 | 
			
				
			 | 
			
			
				
				-	free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2895
			 | 
			
				
			 | 
			
			
				
				- err_mailbox_out: 
			 | 
		
		
	
		
			
			| 
				2896
			 | 
			
				
			 | 
			
			
				
				-	free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2897
			 | 
			
				
			 | 
			
			
				
				- err_mailbox_in: 
			 | 
		
		
	
		
			
			| 
				2898
			 | 
			
				3061
			 | 
			
			
				
				 	i = ARBEL_NUM_PORTS; 
			 | 
		
		
	
		
			
			| 
				2899
			 | 
			
				3062
			 | 
			
			
				
				  err_alloc_ibdev: 
			 | 
		
		
	
		
			
			| 
				2900
			 | 
			
				3063
			 | 
			
			
				
				 	for ( i-- ; i >= 0 ; i-- ) 
			 | 
		
		
	
		
			
			| 
				2901
			 | 
			
				3064
			 | 
			
			
				
				 		ibdev_put ( arbel->ibdev[i] ); 
			 | 
		
		
	
		
			
			| 
				2902
			 | 
			
				
			 | 
			
			
				
				-	free ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2903
			 | 
			
				
			 | 
			
			
				
				- err_alloc_arbel: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3065
			 | 
			
			
				
				+	arbel_free ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3066
			 | 
			
			
				
				+ err_alloc: 
			 | 
		
		
	
		
			
			| 
				2904
			 | 
			
				3067
			 | 
			
			
				
				 	return rc; 
			 | 
		
		
	
		
			
			| 
				2905
			 | 
			
				3068
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2906
			 | 
			
				3069
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -2915,15 +3078,9 @@ static void arbel_remove ( struct pci_device *pci ) { 
			 | 
		
		
	
		
			
			| 
				2915
			 | 
			
				3078
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2916
			 | 
			
				3079
			 | 
			
			
				
				 	for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- ) 
			 | 
		
		
	
		
			
			| 
				2917
			 | 
			
				3080
			 | 
			
			
				
				 		unregister_ibdev ( arbel->ibdev[i] ); 
			 | 
		
		
	
		
			
			| 
				2918
			 | 
			
				
			 | 
			
			
				
				-	arbel_destroy_eq ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2919
			 | 
			
				
			 | 
			
			
				
				-	arbel_cmd_close_hca ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2920
			 | 
			
				
			 | 
			
			
				
				-	arbel_free_icm ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2921
			 | 
			
				
			 | 
			
			
				
				-	arbel_stop_firmware ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2922
			 | 
			
				
			 | 
			
			
				
				-	free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2923
			 | 
			
				
			 | 
			
			
				
				-	free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE ); 
			 | 
		
		
	
		
			
			| 
				2924
			 | 
			
				3081
			 | 
			
			
				
				 	for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- ) 
			 | 
		
		
	
		
			
			| 
				2925
			 | 
			
				3082
			 | 
			
			
				
				 		ibdev_put ( arbel->ibdev[i] ); 
			 | 
		
		
	
		
			
			| 
				2926
			 | 
			
				
			 | 
			
			
				
				-	free ( arbel ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3083
			 | 
			
			
				
				+	arbel_free ( arbel ); 
			 | 
		
		
	
		
			
			| 
				2927
			 | 
			
				3084
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				2928
			 | 
			
				3085
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				2929
			 | 
			
				3086
			 | 
			
			
				
				 static struct pci_device_id arbel_nics[] = { 
			 |