[MTHCA] added support for burning (for flint et al)
[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                 unmap_crspace unmap;\r
706                 \r
707                 unmap.va  = mfi->cr_map.va;\r
708                 if (ibal_access(mfi->h_ca, 0x0, &unmap, sizeof(unmap), FW_UNMAP_CRSPACE ) != IB_SUCCESS) {\r
709                     DPRINT1(("Unmap crspace failed"));\r
710                 }         \r
711             }\r
712         }\r
713         \r
714         if (mfi->h_ca)\r
715             ib_close_ca( mfi->h_ca, NULL );\r
716         if (mfi->h_al)\r
717             ib_close_al( mfi->h_al);\r
718     }\r
719     \r
720     free(mf);\r
721     return rc;\r
722 }\r
723 \r
724 MTCR_API int mread4(mfile *mf, unsigned int offset, u_int32_t *value)\r
725 {\r
726     int rc = 4;\r
727     u_int32_t lvalue;\r
728     mfile_ibal* mfi = (mfile_ibal*)mf;\r
729     switch (mf->tp) {\r
730     \r
731     case MST_PCI:\r
732 \r
733         if (!mf->ptr)\r
734             return -1;\r
735 \r
736         if (offset >= mfi->cr_map.size) {\r
737             DPRINT1(("MTCR:mread4: Tried to access value at offset %x, which is out of pci bar (size %x)\n",\r
738                      offset,\r
739                      mfi->cr_map.size));\r
740             errno = EINVAL;\r
741             return -1;\r
742         }\r
743 \r
744 \r
745 #ifdef SUPPORT_I2CM\r
746         if (mf->is_i2cm)\r
747             return i2c_master_read_cr(mf, value, offset, 4);\r
748 #endif\r
749 \r
750         if (mf->dtype == MST_TAVOR)\r
751             *value = __be32_to_cpu(*((volatile unsigned int *)((char *)mf->ptr + offset)));\r
752         else\r
753             *value = *((volatile unsigned int *)((char *)mf->ptr + offset));\r
754         break;\r
755 \r
756     case MST_PCICONF:\r
757         {\r
758 \r
759 #ifdef SUPPORT_I2CM\r
760             if (mf->is_i2cm)\r
761                 return i2c_master_read_cr(mf, value, offset, 4);\r
762 #endif\r
763 \r
764             if (ibal_access(((mfile_ibal*)mf)->h_ca, offset, value, 4, FW_READ_CMD) == IB_SUCCESS) {\r
765                 rc = 4;\r
766             } else {\r
767                 rc = -1;\r
768             }\r
769 \r
770             break;\r
771         }\r
772 \r
773     case MST_USB:\r
774         {\r
775             switch(mf->dtype)\r
776             {\r
777             case MST_GAMLA:\r
778                 {\r
779                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
780                     unsigned int addr_len = 2;\r
781                     rc = usb_read( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
782                                    (u_int8_t*)&lvalue, 4 );\r
783                     break;\r
784                 }\r
785             case MST_TAVOR:\r
786             default:\r
787                 {\r
788                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
789                     unsigned int addr_len = 4;\r
790                     rc = usb_read( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
791                                    (u_int8_t*)&lvalue, 4 );\r
792                     break;\r
793                 }\r
794             }\r
795             \r
796             if (rc == MT_OK) {\r
797                 *value = __be32_to_cpu(lvalue);\r
798                 rc = 4;\r
799             }\r
800             break;\r
801 \r
802         }\r
803 \r
804     default:\r
805         return -1;\r
806     }\r
807 \r
808     DPRINT5(( "MTCR:mread4: off 0x%x, val 0x%x\n", offset, *value));\r
809     return rc;\r
810 }\r
811 \r
812 MTCR_API int mwrite4(mfile *mf, unsigned int offset, u_int32_t value)\r
813 {\r
814     int rc = 4;\r
815     unsigned int lvalue;\r
816     mfile_ibal* mfi = (mfile_ibal*)mf;\r
817 \r
818     switch(mf->tp)\r
819     {\r
820     case MST_PCI:\r
821         if (!mf->ptr)\r
822             return -1;\r
823 \r
824         if (offset >= mfi->cr_map.size) {\r
825             DPRINT1(("MTCR:mwrite4: Tried to access value at offset %x, which is out of pci bar (size %x)\n",\r
826                      offset,\r
827                      mfi->cr_map.size));\r
828             errno = EINVAL;\r
829             return -1;\r
830         }\r
831 \r
832 #ifdef SUPPORT_I2CM\r
833         if (mf->is_i2cm)\r
834             return i2c_master_write_cr(mf, value, offset, 4);\r
835 #endif\r
836         \r
837         if (mf->dtype == MST_TAVOR)\r
838             *((volatile unsigned int *)((char *)mf->ptr + offset)) = __cpu_to_be32(value);\r
839         else\r
840             *((volatile unsigned int *)((char *)mf->ptr + offset)) = value;\r
841         break;\r
842         \r
843     case MST_PCICONF:\r
844         {\r
845 \r
846 #ifdef SUPPORT_I2CM\r
847             if (mf->is_i2cm)\r
848                 return i2c_master_write_cr(mf, value, offset, 4);\r
849 #endif\r
850 \r
851             if (ibal_access(((mfile_ibal*)mf)->h_ca, offset, &value, 4, FW_WRITE_CMD) == IB_SUCCESS) {\r
852                 rc = 4;\r
853             } else {\r
854                 rc = -1;\r
855             }\r
856 \r
857             break;\r
858         }\r
859         \r
860     case MST_USB:\r
861         {\r
862 \r
863             switch(mf->dtype)\r
864             {\r
865             case MST_GAMLA:\r
866                 {\r
867                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
868                     unsigned int addr_len = 2;\r
869                     lvalue = __cpu_to_be32(value);\r
870                     rc = usb_write( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
871                                     (u_int8_t*)&lvalue, 4 );\r
872                     break;\r
873                 }\r
874             case MST_TAVOR:\r
875             default:\r
876                 {\r
877                     unsigned int offs = (usb_is_dimax()) ? offset : __cpu_to_be32(offset);\r
878                     unsigned int addr_len = 4;\r
879                     lvalue = __cpu_to_be32(value);\r
880                     rc = usb_write( (HANDLE)mf->fd, I2C_TRANS_32ADR, mf->i2c_slave, offs, addr_len, \r
881                                     (u_int8_t*)&lvalue, 4 );\r
882                     break;\r
883                 }\r
884             }\r
885 \r
886             if (rc == MT_OK) {\r
887                 rc = 4;\r
888             }\r
889             break;\r
890         }\r
891     default:\r
892         return -1;\r
893     }\r
894     \r
895     DPRINT5(("MTCR:mwrite4: off 0x%x, val 0x%x\n", offset, value));\r
896     return rc;\r
897 }\r
898 \r
899 MTCR_API int mread64(mfile *mf, unsigned int offset, void *data, int length)\r
900 {\r
901     int                 rc;\r
902 \r
903     if (length > MAX_TRANS_SIZE)\r
904     {\r
905         errno = EINVAL;\r
906         return -1;\r
907     }\r
908 \r
909     switch(mf->tp)\r
910     {\r
911     case MST_PCI:\r
912     case MST_PCICONF:\r
913     {\r
914         int i;\r
915         unsigned char *cdata = (unsigned char *)data;\r
916 \r
917         for (i=0; i<length; i++)\r
918         {\r
919             rc = i2c_master_read_cr(mf, cdata++, offset++, 1);\r
920             if (rc < 0)\r
921                 return rc;\r
922             else if (rc < 1)\r
923                 return i;\r
924         }\r
925         return length;\r
926     }\r
927     break;\r
928 \r
929 #ifdef MTCR_USB_SUPPORT\r
930     case MST_USB:\r
931     {\r
932         call_result_t ret;\r
933         int aw = 0;\r
934         int trans_type = I2C_TRANS_NOADR;\r
935         switch (mf->dtype)\r
936         {\r
937         case MST_NOADDR: trans_type = I2C_TRANS_NOADR; aw = 0; break;\r
938         case MST_DIMM:   trans_type = I2C_TRANS_8ADR;  aw = 1; break;\r
939         case MST_GAMLA:  trans_type = I2C_TRANS_16ADR; aw = 2; break;\r
940         case MST_TAVOR:  trans_type = I2C_TRANS_32ADR; aw = 4; break;\r
941         }\r
942 \r
943         ret = usb_read((HANDLE)mf->fd, trans_type, mf->i2c_slave, offset, aw, data, length);\r
944         if (ret == MT_OK) {\r
945             return length;\r
946         } else {\r
947             errno = ret;\r
948             return -1;\r
949         }\r
950     }\r
951 #endif\r
952 \r
953 \r
954     }\r
955 \r
956     errno = EPERM;\r
957     return -1;\r
958 }\r
959 \r
960 \r
961 MTCR_API int mwrite64(mfile *mf, unsigned int offset, void *data, int length)\r
962 {\r
963 \r
964     int                 rc;\r
965 \r
966     if (length > MAX_TRANS_SIZE)\r
967     {\r
968         errno = EINVAL;\r
969         return -1;\r
970     }\r
971 \r
972     switch(mf->tp)\r
973     {\r
974     case MST_PCI:\r
975     case MST_PCICONF:\r
976     {\r
977         int i;\r
978         unsigned char *cdata = (unsigned char *)data;\r
979 \r
980         for (i=0; i<length; i++)\r
981         {\r
982             rc = i2c_master_write_cr(mf, *cdata++, offset++, 1);\r
983             if (rc < 0)\r
984                 return rc;\r
985             else if (rc < 1)\r
986                 return i;\r
987         }\r
988         return length;\r
989     }\r
990 \r
991 #ifdef MTCR_USB_SUPPORT\r
992     case MST_USB:\r
993      {\r
994          call_result_t ret;\r
995          int aw = 0;\r
996          int trans_type = I2C_TRANS_NOADR;\r
997          switch (mf->dtype)\r
998          {\r
999          case MST_NOADDR: trans_type = I2C_TRANS_NOADR; aw = 0; break;\r
1000          case MST_DIMM:   trans_type = I2C_TRANS_8ADR;  aw = 1; break;\r
1001          case MST_GAMLA:  trans_type = I2C_TRANS_16ADR; aw = 2; break;\r
1002          case MST_TAVOR:  trans_type = I2C_TRANS_32ADR; aw = 4; break;\r
1003          }\r
1004 \r
1005          ret = usb_write((HANDLE)mf->fd, trans_type, mf->i2c_slave, offset, aw, data, length);\r
1006          if (ret == MT_OK) {\r
1007              return length;\r
1008          } else {\r
1009              errno = ret;\r
1010              return -1;\r
1011          }\r
1012      }\r
1013 #endif\r
1014 \r
1015     }\r
1016 \r
1017     errno = EPERM;\r
1018     return -1;\r
1019 }\r
1020 \r
1021 unsigned char mset_i2c_slave(mfile *mf, unsigned char new_i2c_slave)\r
1022 {\r
1023     unsigned char ret;\r
1024     if (mf)\r
1025     {\r
1026        ret = mf->i2c_slave;\r
1027        mf->i2c_slave = new_i2c_slave;\r
1028     }\r
1029     else\r
1030        ret = 0xff;\r
1031     return ret;\r
1032 }\r
1033 \r