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