[TOOLS] changes, caused by previous patch
[mirror/winof/.git] / tools / mtcr / user / mtcr.c
1 // mtcr.c : Defines the entry point for the DLL application.\r
2 //\r
3 #include <stdlib.h>\r
4 #include <errno.h>\r
5 #include <ib_types.h>\r
6 #include <ib_al.h>\r
7 \r
8 \r
9 #include "com_def.h"\r
10 #include "usb.h"\r
11 #include "mtcr.h"\r
12 #include "mtcr_i2c.h"\r
13 #include "mthca_vc.h"\r
14 \r
15 //-----------------------------------------------------\r
16 // NEW FEATURES\r
17 //-----------------------------------------------------\r
18 #define FIX_NAME                        1\r
19 #define SUPPORT_I2CM            1\r
20 \r
21 #define USB_DEV_NAME    "mtusb-1"\r
22 #define CLEAR(st)               memset(&(st), 0, sizeof(st))\r
23 \r
24 \r
25 \r
26 #define MTCR_DEBUG_ENV "MTCR_DEBUG_LEVEL"\r
27 #ifdef DBG\r
28 ULONG g_DebugLevel = DEBUG_LEVEL_MID;\r
29 #else\r
30 ULONG g_DebugLevel = DEBUG_LEVEL_LOW;\r
31 #endif\r
32 \r
33 //-----------------------------------------------------\r
34 \r
35 #define MAX_HCA_NUM 16\r
36 \r
37 \r
38 typedef struct mfile_ibal_t {\r
39     mfile            s;\r
40     ib_al_handle_t   h_al;      \r
41     ib_ca_handle_t   h_ca;\r
42     map_crspace      cr_map;\r
43 } mfile_ibal;\r
44 \r
45 \r
46 BOOL APIENTRY DllMain( HANDLE hModule,\r
47                        DWORD  ul_reason_for_call,\r
48                        LPVOID lpReserved\r
49                                          )\r
50 {\r
51     char* pszDbgLevel;\r
52     switch (ul_reason_for_call)\r
53     {\r
54     case DLL_PROCESS_ATTACH:\r
55         // s_hCtl = (HANDLE)-1;\r
56         // ConnectToDriver();\r
57         g_DebugLevel = 0;\r
58         pszDbgLevel = getenv(MTCR_DEBUG_ENV);\r
59         if (pszDbgLevel) {\r
60             g_DebugLevel = atol(pszDbgLevel);\r
61         }\r
62 \r
63         break;\r
64         \r
65     case DLL_PROCESS_DETACH:\r
66         // DisconnectFromDriver();\r
67         break;\r
68         \r
69     case DLL_THREAD_ATTACH:\r
70     case DLL_THREAD_DETACH:\r
71         break;\r
72     }\r
73     return TRUE;\r
74 }\r
75 \r
76 // device ids\r
77 #define DEVASYS_DEV_ID                                  12345   /* dummy */\r
78 #define TAVOR_DEV_ID                                    23108\r
79 #define TAVOR_CONF_DEV_ID                               23109\r
80 #define ARBEL_TM_DEV_ID                                 25208\r
81 #define ARBEL_TM_CONF_DEV_ID                            25209\r
82 #define ARBEL_DEV_ID                                    25218\r
83 #define ARBEL_CONF_DEV_ID                               25219\r
84 #define SINAI_4X_DEV_ID                                 24204\r
85 #define SINAI_4X_CONF_DEV_ID                            24205\r
86 #define SINAI_8X_DEV_ID                                 25204\r
87 #define SINAI_8X_CONF_DEV_ID                            25205\r
88 \r
89 #define IS_CONF_DEV(dev_id)     \\r
90         ((dev_id == TAVOR_CONF_DEV_ID)    || \\r
91          (dev_id == ARBEL_TM_CONF_DEV_ID) || \\r
92          (dev_id == ARBEL_CONF_DEV_ID)    || \\r
93          (dev_id == SINAI_4X_CONF_DEV_ID) || \\r
94          (dev_id == SINAI_8X_CONF_DEV_ID))\r
95         \r
96 #define MAX_DEV_NAME            32\r
97 typedef struct {\r
98     USHORT  DevId;                             // Device Id, e.g.      23108                   \r
99     UCHAR   DevName[MAX_DEV_NAME];     // exported name, e.g.  "InfiniHost"\r
100     Mdevs   mask;\r
101 } DEVICE_DB_T, *PDEVICE_DB_T;\r
102 \r
103 \r
104 #define TAVOR_TYPE_DEVICE_NAME_FMT      "mt%hu_pci%s%hu"\r
105 #define MDT_DEVICE_NAME_FMT             "%s%hu"\r
106 \r
107 static DEVICE_DB_T db[] = {\r
108         {       DEVASYS_DEV_ID,         "devasys_usb",          MDEVS_TAVOR     },\r
109         {       TAVOR_DEV_ID,           "InfiniHost",           MDEVS_TAVOR     },\r
110         {       TAVOR_CONF_DEV_ID,      "InfiniHostBd",         MDEVS_TAVOR_CR  },\r
111         {       ARBEL_TM_DEV_ID,        "InfiniHost",           MDEVS_TAVOR     },\r
112         {       ARBEL_TM_CONF_DEV_ID,   "InfiniHostBd",         MDEVS_TAVOR_CR  },\r
113         {       ARBEL_DEV_ID,           "InfiniHost_III_Ex",    MDEVS_TAVOR     },\r
114         {       ARBEL_CONF_DEV_ID,      "InfiniHostBd",         MDEVS_TAVOR_CR  },\r
115         {       SINAI_4X_DEV_ID,        "InfiniHost_III_Lx",    MDEVS_TAVOR     },\r
116         {       SINAI_4X_CONF_DEV_ID,   "InfiniHostBd",         MDEVS_TAVOR_CR  },\r
117         {       SINAI_8X_DEV_ID,        "InfiniHost_III_Lx",    MDEVS_TAVOR     },\r
118         {       SINAI_8X_CONF_DEV_ID,   "InfiniHostBd",         MDEVS_TAVOR_CR  },\r
119 };\r
120 #define DEVICE_DB_SIZE  (sizeof(db) / sizeof(DEVICE_DB_T))\r
121 \r
122 Mdevs dmasks[] = { MDEVS_TAVOR_CR, MDEVS_TAVOR_CR, MDEVS_TAVOR_UAR, MDEVS_TAVOR_DDR };\r
123 char *dsuffix[] = { "conf", "_cr", "_uar", "_ddr"};\r
124 #define MASKS_SIZE      (sizeof(dmasks) / sizeof(Mdevs))\r
125 \r
126 \r
127 // Return: < 0 - Error.   > 0 - Numbern of characters written (including last '\0')\r
128 int create_mst_names_by_dev_id(USHORT dev_id, int dev_ix, int mask, char *name, int name_len, int *cnt)\r
129 {\r
130     int i,j; char *suffix; BOOL found = FALSE; char *nm_ptr = name;\r
131     int tot_len = 0;\r
132 \r
133     DPRINT3(( "create_mst_names_by_dev_id: dev_id %d, dev_ix %d, mask %#x, name_len %d\n", \r
134               dev_id, dev_ix, mask, name_len ));\r
135     \r
136     // specific stuff: for CONF devices create only "_cr" device\r
137     *name = 0;\r
138     *cnt = 0;\r
139     if (IS_CONF_DEV(dev_id)) {\r
140         int len;\r
141         tot_len += _snprintf(name, name_len, TAVOR_TYPE_DEVICE_NAME_FMT, dev_id, "conf", dev_ix );\r
142         tot_len++; // trailing null\r
143         *cnt = 1;\r
144         return tot_len;\r
145     }\r
146     DPRINT3(( "create_mst_names_by_dev_id: not conf device %hu, is_conf_dev %d \n", \r
147               dev_id, IS_CONF_DEV(dev_id) ));\r
148     \r
149     // find device\r
150     for (i=0; i<DEVICE_DB_SIZE; i++) {\r
151         if ((db[i].DevId == dev_id) && (db[i].mask & mask)) {\r
152             found = TRUE;\r
153             break;\r
154         }\r
155     }\r
156     if (!found) {\r
157         DPRINT1(( "create_mst_names_by_dev_id: device %hu, mask %#x not found \n", \r
158                   dev_id, mask ));\r
159         return -1;\r
160     }\r
161     \r
162     // names generation\r
163     for (j=0; j<MASKS_SIZE; j++) {\r\r
164         if ((db[i].mask & mask) & dmasks[j]) {\r
165             char l_name[MAX_DEV_NAME]; int len; \r
166             // create one name\r
167             len = _snprintf(l_name, sizeof(l_name), TAVOR_TYPE_DEVICE_NAME_FMT, dev_id, dsuffix[j], dev_ix );\r
168             len++;\r
169             // check whether we have enough place\r
170             if (len > name_len) {\r
171                 DPRINT1(( "create_mst_names_by_dev_id: not enough length (%d > %d)\n", \r
172                           len, name_len ));\r
173                 return -1;       \r
174             }\r
175             // copy the results\r
176             DPRINT5(( "create_mst_names_by_dev_id: name %s\n", \r
177                       l_name ));\r
178             memcpy( nm_ptr, l_name, len );\r
179             nm_ptr += len;\r
180             tot_len += len;\r
181             name_len -= len;\r
182             (*cnt)++;\r
183         }\r
184     }\r
185         \r
186     return tot_len;\r
187 }\r
188 \r
189 \r
190 // Return: 0 - error, 1 - OK\r
191 int parse_mst_name(const char *mst_name, \r
192                    PUSHORT     dev_id,\r
193                    PUSHORT     dev_ix,\r
194                    MType*      mst_dev_type,\r
195                    Mdevs*      access_type)\r
196 {\r
197     char *ptr;\r
198     char suffix[MAX_DEV_NAME];\r
199     const char* fname;\r
200 \r
201     // Unix device name compatibility: Remove path (if exists) from device name:\r
202 \r
203     if ((fname = strrchr(mst_name, '/')) || (fname = strrchr(mst_name, '\\'))) {\r
204         DPRINT3(("Removing path from file: %s --> %s\n", mst_name, fname + 1));\r
205         mst_name = fname + 1;\r
206     }\r
207 \r
208     suffix[0] = '\0';\r
209 \r
210     if (strstr(mst_name, USB_DEV_NAME)) {\r
211         *dev_id = DEVASYS_DEV_ID;\r
212         *dev_ix =0;\r
213         *mst_dev_type = MST_USB;\r
214 \r
215     } else {\r
216         // get dev_id and suffix. dev_ix gets a dummy value.\r
217         sscanf( mst_name, TAVOR_TYPE_DEVICE_NAME_FMT, dev_id, suffix, dev_ix );\r
218         // step over the suffix. ptr will be at the card's number\r
219         if ((ptr=strstr( suffix, "conf"))) {   /* CONF device */\r
220             ptr += 7;\r
221             *mst_dev_type = MST_PCICONF;\r
222         } else if ((ptr=strstr( suffix, "_cr")))  {\r
223             ptr += 3;\r
224             *mst_dev_type = MST_PCI;\r
225             *access_type  = MDEVS_TAVOR_CR;\r
226         } else if ((ptr=strstr( suffix, "_uar"))) {\r
227             ptr += 4;\r
228             *mst_dev_type = MST_PCI;\r
229             *access_type  = MDEVS_TAVOR_UAR;\r
230         } else if ((ptr=strstr( suffix, "_ddr"))) {\r
231             ptr += 4;\r
232             *mst_dev_type = MST_PCI;\r
233             *access_type  = MDEVS_TAVOR_DDR;\r
234         } else {\r
235             DPRINT1(( "parse_mst_name: incorrect device name '%s' \n", mst_name ));\r
236             return 0;\r
237         }\r
238     \r
239         // get dev_ix\r
240         sscanf( ptr, "%hu", dev_ix );\r
241     }\r
242     \r
243     DPRINT3( ("parse_mst_name: name %s, dev_id %d, dev_ix %d\n", \r
244               mst_name, *dev_id, *dev_ix));\r
245     return 1;\r
246 }\r
247 \r
248 \r
249 // Return: 0 - error, 1 - OK\r
250 int create_mdt_name_by_dev_id(USHORT dev_id, USHORT dev_ix, char *name, int name_len)\r
251 {\r
252     int i; \r
253     \r
254     DPRINT3(( "create_mdt_name_by_dev_id: dev_id %d, dev_ix %d\n", \r
255               dev_id, dev_ix ));\r
256     \r
257     // name generation\r
258     *name = 0;\r
259     for (i=0; i<DEVICE_DB_SIZE; i++) {\r
260         DPRINT5(( "create_mdt_name_by_dev_id: dev_id %d, i %d\n", \r
261                   db[i].DevId, i ));\r
262         if (db[i].DevId == dev_id) {\r
263             _snprintf(name, name_len, MDT_DEVICE_NAME_FMT, db[i].DevName, dev_ix );\r
264             return 1;       // OK\r
265         }\r
266     }\r
267     DPRINT1(( "create_mdt_name_by_dev_id: not found device with dev_id %hu\n", dev_id));\r
268     return 0;\r
269 }   \r
270 \r
271 \r
272 //\r
273 // IBAL Access function\r
274 //\r
275 \r
276 \r
277 \r
278 static\r
279 ib_api_status_t ibal_access(ib_ca_handle_t h_ca, u_int32_t offset, void *p_data, uint32_t length, uint32_t operation )\r
280 {\r
281         \r
282         ib_ci_op_t              ci_op;\r
283         ib_api_status_t         ib_status;\r
284 \r
285         BOOL                    dev_status;\r
286         DWORD                   bytes_ret;\r
287 \r
288         ci_op.buf_size       = length;\r
289         ci_op.p_buf          = p_data;\r
290         ci_op.buf_info       = offset;\r
291         ci_op.num_bytes_ret  = sizeof (ib_ci_op_t);\r
292         ci_op.command        = operation;\r
293 \r
294         ib_status = ib_ci_call (h_ca, NULL, 0, &ci_op);\r
295 \r
296         if ( ib_status != IB_SUCCESS )\r
297         {\r
298             DPRINTS1(("Failed ib_ci_call , cmd %x.\n", operation), ib_status );\r
299             return ib_status;\r
300         }\r
301         return IB_SUCCESS;\r
302 }\r
303 \r
304 \r
305 //\r
306 // Return an array of dev IDs of the HCAs on local machine.\r
307 // IDs are returned in the dev_ids array (allocated by caller)\r
308 //\r
309 // Returns number of HCAs found or -1 for error\r
310 //\r
311 int get_dev_ids(ib_al_handle_t h_al, USHORT* dev_ids, u_int32_t size) {\r
312     int cnt = 0;\r
313 \r
314     u_int32_t stub;\r
315     \r
316     u_int32_t        i;\r
317     ib_net64_t       guids[MAX_HCA_NUM];\r
318     ib_api_status_t  ib_status;\r
319     size_t           ca_guids_count = MAX_HCA_NUM;\r
320     \r
321     ib_status = ib_get_ca_guids ( h_al, guids, &ca_guids_count );\r
322     if (ib_status != IB_SUCCESS) {\r
323         DPRINTS1(("Failed to get CA GUIDs\n"), ib_status);\r
324         goto ErrExit;\r
325     }\r
326         \r
327     if (ca_guids_count == 0) {\r
328         DPRINT3(("FOUND NO GUIDS\n"));\r
329         goto OkExit;\r
330     }\r
331     \r
332     if (ca_guids_count > size) {\r
333         DPRINT1(("get_dev_ids(): Got buffer for %d HCAs, but %d HCAs found on machine.\n", size, ca_guids_count));\r
334         goto ErrExit;\r
335     }\r
336 \r
337     for (i = 0; i < ca_guids_count ; i++) {\r
338         ib_ca_attr_t*     ca_data;\r
339         u_int32_t         bsize;\r
340 \r
341         cnt++;\r
342 \r
343         // Query the CA\r
344         ib_status = ib_query_ca_by_guid(h_al, guids[i], NULL, &bsize);\r
345         if(ib_status != IB_INSUFFICIENT_MEMORY)\r
346         {\r
347             DPRINTS1(("Failed to get size of query ca %d by guid.\n", i), ib_status);\r
348             dev_ids[i] = 0;\r
349             continue;   \r
350         }\r
351 \r
352         ca_data = (ib_ca_attr_t*)malloc(bsize);\r
353         if (ca_data == NULL) {\r
354             DPRINT1(("get_dev_ids: malloc failed.\n"));\r
355             continue;\r
356         }\r
357 \r
358         ca_data->dev_id = 0;\r
359 \r
360         ib_status = ib_query_ca_by_guid(h_al, guids[i], ca_data, &bsize);\r
361         if(ib_status != IB_SUCCESS)\r
362         {\r
363             DPRINTS1(("Failed to query ca %d by guid.\n", i), ib_status);\r
364         }\r
365 \r
366         // Get the device id:\r
367         dev_ids[i] = ca_data->dev_id;\r
368 \r
369         free(ca_data);\r
370 \r
371     }\r
372 \r
373     goto OkExit;\r
374 \r
375 ErrExit:\r
376     cnt = -1;\r
377 \r
378 OkExit:\r
379 \r
380     return cnt;\r
381 }\r
382 \r
383 \r
384 int get_hca_idx(ib_al_handle_t h_al, USHORT dev_id, USHORT dev_ix) {\r
385     USHORT dev_ids[MAX_HCA_NUM];\r
386     int cnt;\r
387     int i;\r
388     int matching_devs_found = 0;\r
389 \r
390     cnt = get_dev_ids(h_al, dev_ids, MAX_HCA_NUM);\r
391 \r
392     if (cnt < 0) {\r
393         return cnt;\r
394     }\r
395 \r
396     for (i = 0 ; i < cnt ; i++) {\r
397         if (dev_ids[i] == dev_id) {\r
398             if (matching_devs_found == dev_ix) {\r
399                 DPRINT3(("get_hca_idx, type=%d, idx=%d. HCA index = %d\n", dev_id, dev_ix, i));\r
400                 return i;\r
401             }\r
402             matching_devs_found++;\r
403         }\r
404     }\r
405 \r
406     DPRINT3(("get_hca_idx, type=%d, idx=%d. No matching device found in %d HCAs\n", dev_id, dev_ix, i));\r
407 \r
408     return -1;\r
409 }\r
410 \r
411 \r
412 \r
413 //\r
414 // dev_idx_by_type - stores current hca type idx for each type. Assumed to\r
415 //                   be in the same size of DEVICE_DB_SIZE\r
416 //\r
417 int get_and_inc_dev_idx(u_int32_t* dev_idx_by_type, USHORT dev_id) {\r
418     u_int32_t i;\r
419     int ret = -1;\r
420 \r
421     for (i = 0; i < DEVICE_DB_SIZE; i++) {\r
422         if (dev_id == db[i].DevId) {\r
423             ret = dev_idx_by_type[i];\r
424             dev_idx_by_type[i]++;\r
425             break;\r
426         }\r
427     }\r
428 \r
429     return ret;\r
430 }\r
431 \r
432 \r
433 //\r
434 //\r
435 // List devices in their MST compatible names.\r
436 // Each device type is indexed sepetrately.\r
437 //\r
438 //\r
439 \r
440 MTCR_API int mdevices(char *buf, int len, int mask)\r
441 {\r
442     u_int32_t   tot_len  = 0;\r
443     char*       p         = buf;\r
444     int         devs      = 0;\r
445     int         i;\r
446 \r
447     u_int32_t   dev_idx_by_type[DEVICE_DB_SIZE];\r
448     USHORT      dev_ids[MAX_HCA_NUM];\r
449     int         cnt = 0;\r
450 \r
451     ib_api_status_t  ib_status;\r
452     ib_al_handle_t   h_al = 0;\r
453 \r
454 \r
455 \r
456     memset(  (char*)dev_idx_by_type, 0, sizeof(dev_idx_by_type));\r
457     \r
458     ib_status = ib_open_al( &h_al );\r
459     if ( ib_status != IB_SUCCESS ) {\r
460         DPRINTS1(("Failed to open AL\n"), ib_status );\r
461         // return -1;\r
462     } else {\r
463         cnt = get_dev_ids(h_al, dev_ids, MAX_HCA_NUM);\r
464 \r
465         if (cnt < 0) {\r
466             cnt = 0;\r
467         }\r
468 \r
469         ib_close_al(h_al);\r
470 \r
471     }\r
472 \r
473     for(i = 0; i < cnt; i++) {\r
474         int idx;\r
475         int curr_cnt = 0;\r
476         int curr_len;\r
477 \r
478         if (dev_ids[i] == 0) {\r
479             continue;\r
480         }\r
481 \r
482         idx = get_and_inc_dev_idx(dev_idx_by_type, dev_ids[i]);\r
483 \r
484         if (idx < 0) {\r
485             DPRINT1(("mdevices: Unknown dev id detected: %d. skipped.\n", dev_ids[i]));\r
486             continue;\r
487         }\r
488 \r
489         // For now - get only TAVOR_CR (cr, conf ) devices.\r
490         curr_len = create_mst_names_by_dev_id(dev_ids[i], idx, MDEVS_TAVOR_CR , p , len - tot_len , &curr_cnt);\r
491         if (curr_cnt < 0) {\r
492             return -1;\r
493         }\r
494 \r
495         tot_len += curr_len;\r
496         p       += curr_len;  \r
497         devs    += curr_cnt;\r
498     }\r
499 \r
500 \r
501     if (usb_is_connected() ) {\r
502         sprintf(p, USB_DEV_NAME );\r
503         devs++;\r
504     }\r
505 \r
506     return devs;\r
507 \r
508 }\r
509 \r
510 \r
511 MTCR_API mfile *mopen(const char *name)\r
512 {\r
513     return mopend(name, MST_TAVOR);\r
514 }\r
515 \r
516 MTCR_API mfile *mopend(const char *name, DType dtype)\r
517 {\r
518     USHORT dev_id=0, dev_ix=0;\r
519     HANDLE h;\r
520     MType mst_dev_type;\r
521     Mdevs access_type;\r
522     int   target_hca;\r
523         \r
524     /* allocate mfile struct */\r
525     mfile_ibal *mf = (mfile_ibal *)malloc(sizeof(mfile_ibal));\r
526     if (!mf) {\r
527         errno = ENOMEM;\r
528         return 0;\r
529     }\r
530 \r
531     memset(  (char*)mf, 0, sizeof(mfile_ibal));\r
532 \r
533     mf->s.sock = -1;\r
534 \r
535     /* parse name */\r
536 \r
537     if (!parse_mst_name(name, &dev_id, &dev_ix, &mst_dev_type, &access_type )) {\r
538          goto ErrExit;\r
539     }\r
540 \r
541     DPRINT3(( "mopend: %s, dtype %d, devid %d\n", name, dtype, dev_id));\r
542 \r
543     \r
544     switch(dev_id) {\r
545     case TAVOR_DEV_ID:    case ARBEL_TM_DEV_ID:\r
546     case ARBEL_DEV_ID:    case SINAI_4X_DEV_ID:\r
547     case SINAI_8X_DEV_ID:\r
548         mf->s.itype = MST_TAVOR;\r
549         break;\r
550     default:        \r
551         mf->s.itype = MST_GAMLA;\r
552     }\r
553 \r
554 \r
555     /* Type of device */\r
556     mf->s.dtype = dtype;\r
557     if (dtype == MST_TAVOR)\r
558         mf->s.i2c_slave = 0x48;\r
559     else\r
560         mf->s.i2c_slave = 0x5a;\r
561 \r
562 #ifdef SUPPORT_I2CM\r
563     /* Use the device as I2C master? */\r
564     mf->s.is_i2cm = strstr(name, "i2cm") ? 1 : 0;\r
565 \r
566     /* Type of interface (relevant when is_i2cm==1, unused otherwise */\r
567     if (mf->s.is_i2cm)\r
568     {\r
569         switch(dev_id) {\r
570         case TAVOR_DEV_ID: case ARBEL_TM_DEV_ID:\r
571         case ARBEL_DEV_ID: case SINAI_4X_DEV_ID:\r
572         case SINAI_8X_DEV_ID:\r
573             mf->s.itype = MST_TAVOR;\r
574             break;\r
575         default:        \r
576             goto ErrExit;\r
577         }\r
578     }\r
579 #endif\r
580 \r
581     if (dev_id != DEVASYS_DEV_ID ) {\r
582         /* Open ibal HCA handle */\r
583         u_int32_t stub;\r
584         \r
585         ib_net64_t       guids[MAX_HCA_NUM];\r
586 \r
587         ib_api_status_t  ib_status;\r
588         size_t           ca_guids_count = MAX_HCA_NUM;\r
589 \r
590         ib_status = ib_open_al( &mf->h_al );\r
591 \r
592         if ( ib_status != IB_SUCCESS ) {\r
593             M_DEBUGS(("Failed to open AL\n"), ib_status );\r
594             goto ErrExit;\r
595         }\r
596 \r
597 \r
598         ib_status = ib_get_ca_guids ( mf->h_al, guids, &ca_guids_count );\r
599         if (ib_status != IB_SUCCESS) {\r
600             M_DEBUGS(("Failed to get CA GUIDs\n"), ib_status);\r
601             goto ErrExit;\r
602         }\r
603         \r
604         if (ca_guids_count == 0) {\r
605             DPRINT1(("FOUND NO GUIDS\n"));\r
606             goto ErrExit;\r
607         }\r
608 \r
609         target_hca = get_hca_idx(mf->h_al, dev_id , dev_ix );\r
610         if (target_hca < 0) {\r
611             goto ErrExit;\r
612         }\r
613 \r
614         ib_status = ib_open_ca( mf->h_al, guids[target_hca], NULL, mf,  &mf->h_ca );\r
615         if (ib_status != IB_SUCCESS)\r
616         {\r
617             DPRINTS1(("Failed to open CA\n"), ib_status);\r
618             goto ErrExit;\r
619         }\r
620 \r
621         if(mst_dev_type == MST_PCICONF) {\r
622             // Type of file \r
623             mf->s.tp = MST_PCICONF;\r
624 \r
625             DPRINT5(("Calling: ibal_access(mf->h_ca, 0x0, &stub, 4, FW_OPEN_IF )\n"));\r
626             if (ibal_access(mf->h_ca, 0x0, &stub, 4, FW_OPEN_IF ) != IB_SUCCESS) {\r
627                 goto ErrExit;\r
628             }\r
629         } else {\r
630                     \r
631             int bar_num;\r
632 \r
633             // Type of file \r
634             mf->s.tp = MST_PCI;\r
635             \r
636             // calculate bar number\r
637             if (access_type == MDEVS_TAVOR_CR) {                \r
638                 // TODO: See what about UAR and DDR bars - not supported for now.\r
639 \r
640             } else {\r
641                 DPRINT1(("Only _cr access is supported"));\r
642                 goto ErrName;\r
643             }\r
644                 \r
645             // check FW_MAP_CRSPACE\r
646             if (ibal_access(mf->h_ca, 0x0, &mf->cr_map, sizeof(mf->cr_map), FW_MAP_CRSPACE ) != IB_SUCCESS) {\r
647                 goto ErrExit;\r
648             }\r
649 \r
650             mf->s.ptr = mf->cr_map.va;\r
651         }\r
652            \r
653     } else if (dev_id == DEVASYS_DEV_ID) {\r
654         // Type of file \r
655         h = usb_open();\r
656         if ( h == INVALID_HANDLE_VALUE ) \r
657             goto ErrExit;\r
658         mf->s.fd = FromHandle(h);\r
659         //                      mf->s.tp = (usb_is_dimax()) ? MST_USB_DIMAX : MST_USB;\r
660         mf->s.tp = MST_USB;\r
661     } else {\r
662         goto ErrExit;\r
663     }\r
664     \r
665     /* OK */\r
666     return (mfile*)mf;\r
667 ErrName:    \r
668 //    CloseHandle(h);\r
669 ErrExit:    \r
670     mclose((mfile*)mf);\r
671     errno = ENODEV;\r
672     return 0;\r
673 }\r
674 \r
675 MTCR_API void maccelerate(mfile *mf)\r
676 {\r
677 #ifdef SUPPORT_I2CM\r
678     if (mf->is_i2cm)\r
679         i2c_master_set((mfile*)mf);\r
680 #endif\r
681 }\r
682 \r
683 MTCR_API void mrestore(mfile *mf)\r
684 {\r
685 #ifdef SUPPORT_I2CM\r
686     if (mf->is_i2cm)\r
687         i2c_master_restore(mf);\r
688 #endif\r
689 }\r
690 \r
691 MTCR_API int mclose(mfile *mf)\r
692 {\r
693     int rc=0;\r
694     \r
695     if (mf->tp == MST_USB) {\r
696         rc = usb_close( (HANDLE)mf->fd);\r
697     } else {\r
698         mfile_ibal* mfi = (mfile_ibal*)mf;\r
699         u_int32_t stub;\r
700 \r
701         if (mf->tp == MST_PCICONF) {\r
702             ibal_access(mfi->h_ca, 0x0, &stub, 4, FW_CLOSE_IF );\r
703         } else if (mf->tp = MST_PCI) {\r
704             if (mfi->cr_map.size) {\r
705                 \r
706                 if (ibal_access(mfi->h_ca, 0x0, NULL, 0, FW_UNMAP_CRSPACE ) != IB_SUCCESS) {\r
707                     DPRINT1(("Unmap crspace failed"));\r
708                 }         \r
709             }\r
710         }\r
711         \r
712         if (mfi->h_ca)\r
713             ib_close_ca( mfi->h_ca, NULL );\r
714         if (mfi->h_al)\r
715             ib_close_al( mfi->h_al);\r
716     }\r
717     \r
718     free(mf);\r
719     return rc;\r
720 }\r
721 \r
722 MTCR_API int mread4(mfile *mf, unsigned int offset, u_int32_t *value)\r
723 {\r
724     int rc = 4;\r
725     u_int32_t lvalue;\r
726     mfile_ibal* mfi = (mfile_ibal*)mf;\r
727     switch (mf->tp) {\r
728     \r
729     case MST_PCI:\r
730 \r
731         if (!mf->ptr)\r
732             return -1;\r
733 \r
734         if (offset >= mfi->cr_map.size) {\r
735             DPRINT1(("MTCR:mread4: Tried to access value at offset %x, which is out of pci bar (size %x)\n",\r
736                      offset,\r
737                      mfi->cr_map.size));\r
738             errno = EINVAL;\r
739             return -1;\r
740         }\r
741 \r
742 \r
743 #ifdef SUPPORT_I2CM\r
744         if (mf->is_i2cm)\r
745             return i2c_master_read_cr(mf, value, offset, 4);\r
746 #endif\r
747 \r
748         if (mf->dtype == MST_TAVOR)\r
749             *value = __be32_to_cpu(*((volatile unsigned int *)((char *)mf->ptr + offset)));\r
750         else\r
751             *value = *((volatile unsigned int *)((char *)mf->ptr + offset));\r
752         break;\r
753 \r
754     case MST_PCICONF:\r
755         {\r
756 \r
757 #ifdef SUPPORT_I2CM\r
758             if (mf->is_i2cm)\r
759                 return i2c_master_read_cr(mf, value, offset, 4);\r
760 #endif\r
761 \r
762             if (ibal_access(((mfile_ibal*)mf)->h_ca, offset, value, 4, FW_READ_CMD) == IB_SUCCESS) {\r
763                 rc = 4;\r
764             } else {\r
765                 rc = -1;\r
766             }\r
767 \r
768             break;\r
769         }\r
770 \r
771     case MST_USB:\r
772         {\r
773             switch(mf->dtype)\r
774             {\r
775             case MST_GAMLA:\r
776                 {\r
777                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
778                     unsigned int addr_len = 2;\r
779                     rc = usb_read( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
780                                    (u_int8_t*)&lvalue, 4 );\r
781                     break;\r
782                 }\r
783             case MST_TAVOR:\r
784             default:\r
785                 {\r
786                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
787                     unsigned int addr_len = 4;\r
788                     rc = usb_read( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
789                                    (u_int8_t*)&lvalue, 4 );\r
790                     break;\r
791                 }\r
792             }\r
793             \r
794             if (rc == MT_OK) {\r
795                 *value = __be32_to_cpu(lvalue);\r
796                 rc = 4;\r
797             }\r
798             break;\r
799 \r
800         }\r
801 \r
802     default:\r
803         return -1;\r
804     }\r
805 \r
806     DPRINT5(( "MTCR:mread4: off 0x%x, val 0x%x\n", offset, *value));\r
807     return rc;\r
808 }\r
809 \r
810 MTCR_API int mwrite4(mfile *mf, unsigned int offset, u_int32_t value)\r
811 {\r
812     int rc = 4;\r
813     unsigned int lvalue;\r
814     mfile_ibal* mfi = (mfile_ibal*)mf;\r
815 \r
816     switch(mf->tp)\r
817     {\r
818     case MST_PCI:\r
819         if (!mf->ptr)\r
820             return -1;\r
821 \r
822         if (offset >= mfi->cr_map.size) {\r
823             DPRINT1(("MTCR:mwrite4: Tried to access value at offset %x, which is out of pci bar (size %x)\n",\r
824                      offset,\r
825                      mfi->cr_map.size));\r
826             errno = EINVAL;\r
827             return -1;\r
828         }\r
829 \r
830 #ifdef SUPPORT_I2CM\r
831         if (mf->is_i2cm)\r
832             return i2c_master_write_cr(mf, value, offset, 4);\r
833 #endif\r
834         \r
835         if (mf->dtype == MST_TAVOR)\r
836             *((volatile unsigned int *)((char *)mf->ptr + offset)) = __cpu_to_be32(value);\r
837         else\r
838             *((volatile unsigned int *)((char *)mf->ptr + offset)) = value;\r
839         break;\r
840         \r
841     case MST_PCICONF:\r
842         {\r
843 \r
844 #ifdef SUPPORT_I2CM\r
845             if (mf->is_i2cm)\r
846                 return i2c_master_write_cr(mf, value, offset, 4);\r
847 #endif\r
848 \r
849             if (ibal_access(((mfile_ibal*)mf)->h_ca, offset, &value, 4, FW_WRITE_CMD) == IB_SUCCESS) {\r
850                 rc = 4;\r
851             } else {\r
852                 rc = -1;\r
853             }\r
854 \r
855             break;\r
856         }\r
857         \r
858     case MST_USB:\r
859         {\r
860 \r
861             switch(mf->dtype)\r
862             {\r
863             case MST_GAMLA:\r
864                 {\r
865                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
866                     unsigned int addr_len = 2;\r
867                     lvalue = __cpu_to_be32(value);\r
868                     rc = usb_write( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
869                                     (u_int8_t*)&lvalue, 4 );\r
870                     break;\r
871                 }\r
872             case MST_TAVOR:\r
873             default:\r
874                 {\r
875                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
876                     unsigned int addr_len = 4;\r
877                     lvalue = __cpu_to_be32(value);\r
878                     rc = usb_write( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
879                                     (u_int8_t*)&lvalue, 4 );\r
880                     break;\r
881                 }\r
882             }\r
883 \r
884             if (rc == MT_OK) {\r
885                 rc = 4;\r
886             }\r
887             break;\r
888         }\r
889     default:\r
890         return -1;\r
891     }\r
892     \r
893     DPRINT5(("MTCR:mwrite4: off 0x%x, val 0x%x\n", offset, value));\r
894     return rc;\r
895 }\r
896 \r
897 MTCR_API int mread64(mfile *mf, unsigned int offset, void *data, int length)\r
898 {\r
899     int                 rc;\r
900 \r
901     if (length > MAX_TRANS_SIZE)\r
902     {\r
903         errno = EINVAL;\r
904         return -1;\r
905     }\r
906 \r
907     switch(mf->tp)\r
908     {\r
909     case MST_PCI:\r
910     case MST_PCICONF:\r
911     {\r
912         int i;\r
913         unsigned char *cdata = (unsigned char *)data;\r
914 \r
915         for (i=0; i<length; i++)\r
916         {\r
917             rc = i2c_master_read_cr(mf, cdata++, offset++, 1);\r
918             if (rc < 0)\r
919                 return rc;\r
920             else if (rc < 1)\r
921                 return i;\r
922         }\r
923         return length;\r
924     }\r
925     break;\r
926 \r
927 #ifdef MTCR_USB_SUPPORT\r
928     case MST_USB:\r
929     {\r
930         call_result_t ret;\r
931         int aw = 0;\r
932         int trans_type = I2C_TRANS_NOADR;\r
933         switch (mf->dtype)\r
934         {\r
935         case MST_NOADDR: trans_type = I2C_TRANS_NOADR; aw = 0; break;\r
936         case MST_DIMM:   trans_type = I2C_TRANS_8ADR;  aw = 1; break;\r
937         case MST_GAMLA:  trans_type = I2C_TRANS_16ADR; aw = 2; break;\r
938         case MST_TAVOR:  trans_type = I2C_TRANS_32ADR; aw = 4; break;\r
939         }\r
940 \r
941         ret = usb_read((HANDLE)mf->fd, trans_type, mf->i2c_slave, offset, aw, data, length);\r
942         if (ret == MT_OK) {\r
943             return length;\r
944         } else {\r
945             errno = ret;\r
946             return -1;\r
947         }\r
948     }\r
949 #endif\r
950 \r
951 \r
952     }\r
953 \r
954     errno = EPERM;\r
955     return -1;\r
956 }\r
957 \r
958 \r
959 MTCR_API int mwrite64(mfile *mf, unsigned int offset, void *data, int length)\r
960 {\r
961 \r
962     int                 rc;\r
963 \r
964     if (length > MAX_TRANS_SIZE)\r
965     {\r
966         errno = EINVAL;\r
967         return -1;\r
968     }\r
969 \r
970     switch(mf->tp)\r
971     {\r
972     case MST_PCI:\r
973     case MST_PCICONF:\r
974     {\r
975         int i;\r
976         unsigned char *cdata = (unsigned char *)data;\r
977 \r
978         for (i=0; i<length; i++)\r
979         {\r
980             rc = i2c_master_write_cr(mf, *cdata++, offset++, 1);\r
981             if (rc < 0)\r
982                 return rc;\r
983             else if (rc < 1)\r
984                 return i;\r
985         }\r
986         return length;\r
987     }\r
988 \r
989 #ifdef MTCR_USB_SUPPORT\r
990     case MST_USB:\r
991      {\r
992          call_result_t ret;\r
993          int aw = 0;\r
994          int trans_type = I2C_TRANS_NOADR;\r
995          switch (mf->dtype)\r
996          {\r
997          case MST_NOADDR: trans_type = I2C_TRANS_NOADR; aw = 0; break;\r
998          case MST_DIMM:   trans_type = I2C_TRANS_8ADR;  aw = 1; break;\r
999          case MST_GAMLA:  trans_type = I2C_TRANS_16ADR; aw = 2; break;\r
1000          case MST_TAVOR:  trans_type = I2C_TRANS_32ADR; aw = 4; break;\r
1001          }\r
1002 \r
1003          ret = usb_write((HANDLE)mf->fd, trans_type, mf->i2c_slave, offset, aw, data, length);\r
1004          if (ret == MT_OK) {\r
1005              return length;\r
1006          } else {\r
1007              errno = ret;\r
1008              return -1;\r
1009          }\r
1010      }\r
1011 #endif\r
1012 \r
1013     }\r
1014 \r
1015     errno = EPERM;\r
1016     return -1;\r
1017 }\r
1018 \r
1019 unsigned char mset_i2c_slave(mfile *mf, unsigned char new_i2c_slave)\r
1020 {\r
1021     unsigned char ret;\r
1022     if (mf)\r
1023     {\r
1024        ret = mf->i2c_slave;\r
1025        mf->i2c_slave = new_i2c_slave;\r
1026     }\r
1027     else\r
1028        ret = 0xff;\r
1029     return ret;\r
1030 }\r
1031 \r