| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870 |
- /*
- * Copyright 2013 Andrew Smith
- * Copyright 2013 bitfury
- *
- * BitFury GPIO code based on chainminer code:
- * https://github.com/bfsb/chainminer
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version. See COPYING for more details.
- */
- #include "config.h"
- #include "compat.h"
- #include "miner.h"
- #include "sha2.h"
- /*
- * Tested on RPi running Raspbian with BlackArrow BitFury V1 16 chip GPIO board
- */
- #ifndef LINUX
- static void bab_detect(__maybe_unused bool hotplug)
- {
- }
- #else
- #include <unistd.h>
- #include <linux/spi/spidev.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #define BAB_SPI_BUS 0
- #define BAB_SPI_CHIP 0
- #define BAB_SPI_SPEED 96000
- #define BAB_SPI_BUFSIZ 1024
- #define BAB_ADDR(_n) (*((babinfo->gpio) + (_n)))
- #define BAB_INP_GPIO(_n) BAB_ADDR((_n) / 10) &= (~(7 << (((_n) % 10) * 3)))
- #define BAB_OUT_GPIO(_n) BAB_ADDR((_n) / 10) |= (1 << (((_n) % 10) * 3))
- #define BAB_OUT_GPIO_V(_n, _v) BAB_ADDR((_n) / 10) |= (((_v) <= 3 ? (_v) + 4 : \
- ((_v) == 4 ? 3 : 2)) << (((_n) % 10) * 3))
- #define BAB_GPIO_SET BAB_ADDR(7)
- #define BAB_GPIO_CLR BAB_ADDR(10)
- #define BAB_GPIO_LEVEL BAB_ADDR(13)
- #define BAB_MAXCHIPS 256
- #define BAB_MAXBUF (BAB_MAXCHIPS * 512)
- #define BAB_MAXBANKS 4
- #define BAB_CORES 16
- #define BAB_X_COORD 21
- #define BAB_Y_COORD 36
- #define BAB_BREAK ((uint8_t *)"\04")
- #define BAB_ASYNC ((uint8_t *)"\05")
- #define BAB_SYNC ((uint8_t *)"\06")
- #define BAB_FFL " - from %s %s() line %d"
- #define BAB_FFL_HERE __FILE__, __func__, __LINE__
- #define BAB_FFL_PASS file, func, line
- #define bab_reset(_bank, _times) _bab_reset(babcgpu, babinfo, _bank, _times)
- #define bab_txrx(_buf, _siz, _det) _bab_txrx(babcgpu, babinfo, _buf, _siz, _det, BAB_FFL_HERE)
- #define bab_add_buf(_data) _bab_add_buf(babcgpu, babinfo, _data, sizeof(_data)-1, BAB_FFL_HERE)
- #define BAB_ADD_BREAK() _bab_add_buf(babcgpu, babinfo, BAB_BREAK, 1, BAB_FFL_HERE)
- #define BAB_ADD_ASYNC() _bab_add_buf(babcgpu, babinfo, BAB_ASYNC, 1, BAB_FFL_HERE)
- #define bab_config_reg(_reg, _ena) _bab_config_reg(babcgpu, babinfo, _reg, _ena, BAB_FFL_HERE)
- #define bab_add_data(_addr, _data, _siz) _bab_add_data(babcgpu, babinfo, _addr, (const uint8_t *)(_data), _siz, BAB_FFL_HERE)
- #define BAB_ADD_MIN 4
- #define BAB_ADD_MAX 128
- #define BAB_STATE_DONE 0
- #define BAB_STATE_READY 1
- #define BAB_STATE_SENDING 2
- #define BAB_STATE_SENT 3
- #define BAB_STATE_READING 4
- #define BAB_SPI_BUFFERS 2
- #define BAB_BASEA 4
- #define BAB_BASEB 61
- #define BAB_COUNTERS 16
- static const uint8_t bab_counters[BAB_COUNTERS] = {
- 64, 64,
- BAB_BASEA, BAB_BASEA+4,
- BAB_BASEA+2, BAB_BASEA+2+16,
- BAB_BASEA, BAB_BASEA+1,
- (BAB_BASEB)%65, (BAB_BASEB+1)%65,
- (BAB_BASEB+3)%65, (BAB_BASEB+3+16)%65,
- (BAB_BASEB+4)%65, (BAB_BASEB+4+4)%65,
- (BAB_BASEB+3+3)%65, (BAB_BASEB+3+1+3)%65
- };
- #define BAB_W1 16
- static const uint32_t bab_w1[BAB_W1] = {
- 0, 0, 0, 0xffffffff,
- 0x80000000, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0x00000280
- };
- #define BAB_W2 8
- static const uint32_t bab_w2[BAB_W2] = {
- 0x80000000, 0, 0, 0,
- 0, 0, 0, 0x00000100
- };
- #define BAB_TEST_DATA 19
- static const uint32_t bab_test_data[BAB_TEST_DATA] = {
- 0xb0e72d8e, 0x1dc5b862, 0xe9e7c4a6, 0x3050f1f5,
- 0x8a1a6b7e, 0x7ec384e8, 0x42c1c3fc, 0x8ed158a1,
- 0x8a1a6b7e, 0x6f484872, 0x4ff0bb9b, 0x12c97f07,
- 0xb0e72d8e, 0x55d979bc, 0x39403296, 0x40f09e84,
- 0x8a0bb7b7, 0x33af304f, 0x0b290c1a //, 0xf0c4e61f
- };
- //maximum number of chips on alternative bank
- // #define BANKCHIPS 64
- /*
- * maximum chip speed available for auto tuner
- * speed/nrate/hrate/watt
- * 53/ 97/ 100/ 84
- * 54/ 98/ 107/ 88
- * 55/ 99/ 115/ 93
- * 56/ 101/ 125/ 99
- */
- #define BAB_MAXSPEED 57
- #define BAB_DEFSPEED 54
- #define BAB_MINSPEED 52
- #define MIDSTATE_BYTES 32
- #define MERKLE_OFFSET 64
- #define MERKLE_BYTES 12
- #define BLOCK_HEADER_BYTES 80
- #define MIDSTATE_UINTS (MIDSTATE_BYTES / sizeof(uint32_t))
- #define DATA_UINTS ((BLOCK_HEADER_BYTES / sizeof(uint32_t)) - 1)
- // Auto adjust
- #define BAB_AUTO_REG 0
- #define BAB_AUTO_VAL 0x01
- // iclk
- #define BAB_ICLK_REG 1
- #define BAB_ICLK_VAL 0x02
- // No fast clock
- #define BAB_FAST_REG 2
- #define BAB_FAST_VAL 0x04
- // Divide by 2
- #define BAB_DIV2_REG 3
- #define BAB_DIV2_VAL 0x08
- // Slow Clock
- #define BAB_SLOW_REG 4
- #define BAB_SLOW_VAL 0x10
- // No oclk
- #define BAB_OCLK_REG 6
- #define BAB_OCLK_VAL 0x20
- // Has configured
- #define BAB_CFGD_VAL 0x40
- #define BAB_DEFCONF (BAB_AUTO_VAL | \
- BAB_ICLK_VAL | \
- BAB_DIV2_VAL | \
- BAB_SLOW_VAL)
- #define BAB_REG_CLR_FROM 7
- #define BAB_REG_CLR_TO 11
- #define BAB_AUTO_SET(_c) ((_c) & BAB_AUTO_VAL)
- #define BAB_ICLK_SET(_c) ((_c) & BAB_ICLK_VAL)
- #define BAB_FAST_SET(_c) ((_c) & BAB_FAST_VAL)
- #define BAB_DIV2_SET(_c) ((_c) & BAB_DIV2_VAL)
- #define BAB_SLOW_SET(_c) ((_c) & BAB_SLOW_VAL)
- #define BAB_OCLK_SET(_c) ((_c) & BAB_OCLK_VAL)
- #define BAB_CFGD_SET(_c) ((_c) & BAB_CFGD_VAL)
- #define BAB_AUTO_BIT(_c) (BAB_AUTO_SET(_c) ? true : false)
- #define BAB_ICLK_BIT(_c) (BAB_ICLK_SET(_c) ? false : true)
- #define BAB_FAST_BIT(_c) (BAB_FAST_SET(_c) ? true : false)
- #define BAB_DIV2_BIT(_c) (BAB_DIV2_SET(_c) ? false : true)
- #define BAB_SLOW_BIT(_c) (BAB_SLOW_SET(_c) ? true : false)
- #define BAB_OCLK_BIT(_c) (BAB_OCLK_SET(_c) ? true : false)
- #define BAB_COUNT_ADDR 0x0100
- #define BAB_W1A_ADDR 0x1000
- #define BAB_W1B_ADDR 0x1400
- #define BAB_W2_ADDR 0x1900
- #define BAB_INP_ADDR 0x3000
- #define BAB_OSC_ADDR 0x6000
- #define BAB_REG_ADDR 0x7000
- /*
- * valid: 0x01 0x03 0x07 0x0F 0x1F 0x3F 0x7F 0xFF
- * max { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00 }
- * max { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00 }
- * avg { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00 }
- * slo { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00 }
- * min { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- * good: 0x1F (97) 0x3F (104) 0x7F (109) 0xFF (104)
- */
- #define BAB_OSC 8
- static const uint8_t bab_osc_bits[BAB_OSC] =
- { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };
- static const uint8_t bab_reg_ena[4] = { 0xc1, 0x6a, 0x59, 0xe3 };
- static const uint8_t bab_reg_dis[4] = { 0x00, 0x00, 0x00, 0x00 };
- #define BAB_NONCE_OFFSETS 3
- static const uint32_t bab_nonce_offsets[] = {-0x800000, 0, -0x400000};
- struct bab_work_send {
- uint32_t midstate[MIDSTATE_UINTS];
- uint32_t ms3steps[MIDSTATE_UINTS];
- uint32_t merkle7;
- uint32_t ntime;
- uint32_t bits;
- };
- #define BAB_REPLY_NONCES 16
- struct bab_work_reply {
- uint32_t nonce[BAB_REPLY_NONCES];
- uint32_t jobsel;
- };
- #define MAX_BLISTS 4096
- typedef struct blist {
- struct blist *prev;
- struct blist *next;
- struct work *work;
- int nonces;
- } BLIST;
- #define MAX_RLISTS 256
- typedef struct rlist {
- struct rlist *prev;
- struct rlist *next;
- int chip;
- uint32_t nonce;
- bool first_second;
- } RLIST;
- struct bab_info {
- struct thr_info spi_thr;
- struct thr_info res_thr;
- pthread_mutex_t spi_lock;
- pthread_mutex_t res_lock;
- pthread_mutex_t did_lock;
- cglock_t blist_lock;
- // All GPIO goes through this
- volatile unsigned *gpio;
- int spifd;
- int chips;
- uint32_t chip_spis[BAB_MAXCHIPS+1];
- int buffer;
- int buf_status[BAB_SPI_BUFFERS];
- uint8_t buf_write[BAB_SPI_BUFFERS][BAB_MAXBUF];
- uint8_t buf_read[BAB_SPI_BUFFERS][BAB_MAXBUF];
- uint32_t buf_used[BAB_SPI_BUFFERS];
- uint32_t chip_off[BAB_SPI_BUFFERS][BAB_MAXCHIPS+1];
- uint32_t bank_off[BAB_SPI_BUFFERS][BAB_MAXBANKS+2];
- struct bab_work_send chip_input[BAB_MAXCHIPS];
- struct bab_work_reply chip_results[BAB_MAXCHIPS];
- struct bab_work_reply chip_prev[BAB_MAXCHIPS];
- uint8_t chip_fast[BAB_MAXCHIPS];
- uint8_t chip_conf[BAB_MAXCHIPS];
- uint8_t old_fast[BAB_MAXCHIPS];
- uint8_t old_conf[BAB_MAXCHIPS];
- uint8_t chip_bank[BAB_MAXCHIPS+1];
- uint8_t osc[BAB_OSC];
- int fixchip;
- /*
- * Ignore errors in the first work reply since
- * they may be from a previous run or random junk
- * There can be >100 with just a 16 chip board
- */
- uint32_t initial_ignored;
- bool nonce_before[BAB_MAXCHIPS];
- bool not_first_reply[BAB_MAXCHIPS];
- // Stats
- struct timeval chip_start[BAB_MAXCHIPS];
- int chip_busy[BAB_MAXCHIPS];
- uint64_t core_good[BAB_MAXCHIPS][BAB_CORES];
- uint64_t core_bad[BAB_MAXCHIPS][BAB_CORES];
- uint64_t chip_spie[BAB_MAXCHIPS]; // spi errors
- uint64_t chip_miso[BAB_MAXCHIPS]; // msio errors
- uint64_t chip_nonces[BAB_MAXCHIPS];
- uint64_t chip_good[BAB_MAXCHIPS];
- uint64_t chip_bad[BAB_MAXCHIPS];
- uint64_t chip_ncore[BAB_MAXCHIPS][BAB_X_COORD][BAB_Y_COORD];
- uint64_t untested_nonces;
- uint64_t tested_nonces;
- uint64_t new_nonces;
- uint64_t ok_nonces;
- uint64_t nonce_offset_count[BAB_NONCE_OFFSETS];
- uint64_t total_tests;
- uint64_t max_tests_per_nonce;
- uint64_t total_links;
- uint64_t max_links;
- int blist_count;
- int bfree_count;
- int work_count;
- int chip_count;
- BLIST *bfree_list;
- BLIST *work_list;
- BLIST *chip_list[BAB_MAXCHIPS];
- int rlist_count;
- int rfree_count;
- int res_count;
- RLIST *rfree_list;
- RLIST *res_list_head;
- RLIST *res_list_tail;
- struct timeval last_did;
- bool initialised;
- };
- static BLIST *new_blist_set(struct cgpu_info *babcgpu)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- BLIST *blist = NULL;
- int i;
- blist = calloc(MAX_BLISTS, sizeof(*blist));
- if (!blist)
- quithere(1, "Failed to calloc blist - when old count=%d", babinfo->blist_count);
- babinfo->blist_count += MAX_BLISTS;
- babinfo->bfree_count = MAX_BLISTS;
- blist[0].prev = NULL;
- blist[0].next = &(blist[1]);
- for (i = 1; i < MAX_BLISTS-1; i++) {
- blist[i].prev = &blist[i-1];
- blist[i].next = &blist[i+1];
- }
- blist[MAX_BLISTS-1].prev = &(blist[MAX_BLISTS-2]);
- blist[MAX_BLISTS-1].next = NULL;
- return blist;
- }
- static BLIST *next_work(struct cgpu_info *babcgpu, int chip)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- BLIST *bitem;
- cg_wlock(&babinfo->blist_lock);
- bitem = babinfo->work_list;
- if (bitem) {
- // Unlink it from work
- if (bitem->next)
- bitem->next->prev = NULL;
- babinfo->work_list = bitem->next;
- babinfo->work_count--;
- // Add it to the chip
- bitem->next = babinfo->chip_list[chip];
- bitem->prev = NULL;
- if (bitem->next)
- bitem->next->prev = bitem;
- babinfo->chip_list[chip] = bitem;
- babinfo->chip_count++;
- }
- cg_wunlock(&babinfo->blist_lock);
- return bitem;
- }
- static void discard_last(struct cgpu_info *babcgpu, int chip)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- BLIST *bitem;
- cg_wlock(&babinfo->blist_lock);
- bitem = babinfo->chip_list[chip];
- if (bitem) {
- // Unlink it from the chip
- if (bitem->next)
- bitem->next->prev = NULL;
- babinfo->chip_list[chip] = bitem->next;
- babinfo->chip_count--;
- // Put it in the free list
- bitem->next = babinfo->bfree_list;
- bitem->prev = NULL;
- if (bitem->next)
- bitem->next->prev = bitem;
- babinfo->bfree_list = bitem;
- babinfo->bfree_count++;
- }
- cg_wunlock(&babinfo->blist_lock);
- }
- static BLIST *store_work(struct cgpu_info *babcgpu, struct work *work)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- BLIST *bitem = NULL;
- int ran_out = 0;
- cg_wlock(&babinfo->blist_lock);
- if (babinfo->bfree_list == NULL) {
- ran_out = babinfo->blist_count;
- babinfo->bfree_list = new_blist_set(babcgpu);
- }
- // unlink from free
- bitem = babinfo->bfree_list;
- babinfo->bfree_list = babinfo->bfree_list->next;
- if (babinfo->bfree_list)
- babinfo->bfree_list->prev = NULL;
- babinfo->bfree_count--;
- // add to work
- bitem->next = babinfo->work_list;
- bitem->prev = NULL;
- if (bitem->next)
- bitem->next->prev = bitem;
- babinfo->work_list = bitem;
- babinfo->work_count++;
- bitem->work = work;
- bitem->nonces = 0;
- cg_wunlock(&babinfo->blist_lock);
- if (ran_out > 0) {
- applog(LOG_ERR, "%s%i: BLIST used count exceeded %d, now %d (work=%d chip=%d)",
- babcgpu->drv->name, babcgpu->device_id,
- ran_out, babinfo->blist_count,
- babinfo->work_count,
- babinfo->chip_count);
- }
- return bitem;
- }
- static void free_blist(struct cgpu_info *babcgpu, BLIST *bhead, int chip)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- struct work *work;
- BLIST *bitem;
- if (!bhead)
- return;
- // Unlink it from the chip
- cg_wlock(&babinfo->blist_lock);
- if (unlikely(bhead == babinfo->chip_list[chip])) {
- // Removing the chip head is an error
- bhead = bhead->next;
- babinfo->chip_list[chip]->next = NULL;
- } else
- bhead->prev->next = NULL;
- bitem = bhead;
- while (bitem) {
- babinfo->chip_count--;
- bitem = bitem->next;
- }
- cg_wunlock(&babinfo->blist_lock);
- while (bhead) {
- bitem = bhead;
- bhead = bitem->next;
- // add to free
- cg_wlock(&babinfo->blist_lock);
- bitem->next = babinfo->bfree_list;
- if (babinfo->bfree_list)
- babinfo->bfree_list->prev = bitem;
- bitem->prev = NULL;
- babinfo->bfree_list = bitem;
- babinfo->bfree_count++;
- work = bitem->work;
- cg_wunlock(&babinfo->blist_lock);
- work_completed(babcgpu, work);
- }
- }
- static RLIST *new_rlist_set(struct cgpu_info *babcgpu)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- RLIST *rlist = NULL;
- int i;
- rlist = calloc(MAX_RLISTS, sizeof(*rlist));
- if (!rlist)
- quithere(1, "Failed to calloc rlist - when old count=%d", babinfo->rlist_count);
- babinfo->rlist_count += MAX_RLISTS;
- babinfo->rfree_count = MAX_RLISTS;
- rlist[0].prev = NULL;
- rlist[0].next = &(rlist[1]);
- for (i = 1; i < MAX_RLISTS-1; i++) {
- rlist[i].prev = &rlist[i-1];
- rlist[i].next = &rlist[i+1];
- }
- rlist[MAX_RLISTS-1].prev = &(rlist[MAX_RLISTS-2]);
- rlist[MAX_RLISTS-1].next = NULL;
- return rlist;
- }
- static RLIST *store_nonce(struct cgpu_info *babcgpu, int chip, uint32_t nonce, bool first_second)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- RLIST *ritem = NULL;
- int ran_out = 0;
- mutex_lock(&(babinfo->res_lock));
- if (babinfo->rfree_list == NULL) {
- ran_out = babinfo->rlist_count;
- babinfo->rfree_list = new_rlist_set(babcgpu);
- }
- // unlink from rfree
- ritem = babinfo->rfree_list;
- babinfo->rfree_list = babinfo->rfree_list->next;
- if (babinfo->rfree_list)
- babinfo->rfree_list->prev = NULL;
- babinfo->rfree_count--;
- // add to head of results
- ritem->next = babinfo->res_list_head;
- ritem->prev = NULL;
- babinfo->res_list_head = ritem;
- if (ritem->next)
- ritem->next->prev = ritem;
- else
- babinfo->res_list_tail = ritem;
- babinfo->res_count++;
- ritem->chip = chip;
- ritem->nonce = nonce;
- ritem->first_second = first_second;
- mutex_unlock(&(babinfo->res_lock));
- if (ran_out > 0) {
- applog(LOG_ERR, "%s%i: RLIST used count exceeded %d, now %d (work=%d chip=%d)",
- babcgpu->drv->name, babcgpu->device_id,
- ran_out, babinfo->rlist_count,
- babinfo->work_count,
- babinfo->chip_count);
- }
- return ritem;
- }
- static bool oldest_nonce(struct cgpu_info *babcgpu, int *chip, uint32_t *nonce, bool *first_second)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- RLIST *ritem = NULL;
- bool found = false;
- mutex_lock(&(babinfo->res_lock));
- if (babinfo->res_list_tail) {
- // unlink from res
- ritem = babinfo->res_list_tail;
- if (ritem->prev) {
- ritem->prev->next = NULL;
- babinfo->res_list_tail = ritem->prev;
- } else
- babinfo->res_list_head = babinfo->res_list_tail = NULL;
- babinfo->res_count--;
- found = true;
- *chip = ritem->chip;
- *nonce = ritem->nonce;
- *first_second = ritem->first_second;
- // add to rfree
- ritem->next = babinfo->rfree_list;
- ritem->prev = NULL;
- if (ritem->next)
- ritem->next->prev = ritem;
- babinfo->rfree_list = ritem;
- babinfo->rfree_count++;
- }
- mutex_unlock(&(babinfo->res_lock));
- return found;
- }
- static void _bab_reset(__maybe_unused struct cgpu_info *babcgpu, struct bab_info *babinfo, int bank, int times)
- {
- const int banks[4] = { 18, 23, 24, 25 };
- int i;
- BAB_INP_GPIO(10);
- BAB_OUT_GPIO(10);
- BAB_INP_GPIO(11);
- BAB_OUT_GPIO(11);
- if (bank) {
- for (i = 0; i < 4; i++) {
- BAB_INP_GPIO(banks[i]);
- BAB_OUT_GPIO(banks[i]);
- if (bank == i+1)
- BAB_GPIO_SET = 1 << banks[i];
- else
- BAB_GPIO_CLR = 1 << banks[i];
- }
- cgsleep_us(4096);
- } else {
- for (i = 0; i < 4; i++)
- BAB_INP_GPIO(banks[i]);
- }
- BAB_GPIO_SET = 1 << 11;
- for (i = 0; i < times; i++) { // 1us = 1MHz
- BAB_GPIO_SET = 1 << 10;
- cgsleep_us(1);
- BAB_GPIO_CLR = 1 << 10;
- cgsleep_us(1);
- }
- BAB_GPIO_CLR = 1 << 11;
- BAB_INP_GPIO(11);
- BAB_INP_GPIO(10);
- BAB_INP_GPIO(9);
- BAB_OUT_GPIO_V(11, 0);
- BAB_OUT_GPIO_V(10, 0);
- BAB_OUT_GPIO_V(9, 0);
- }
- // TODO: handle a false return where this is called?
- static bool _bab_txrx(struct cgpu_info *babcgpu, struct bab_info *babinfo, int buf, uint32_t siz, bool detect_ignore, const char *file, const char *func, const int line)
- {
- int bank, i;
- uint32_t pos;
- struct spi_ioc_transfer tran;
- uintptr_t rbuf, wbuf;
- wbuf = (uintptr_t)(babinfo->buf_write[buf]);
- rbuf = (uintptr_t)(babinfo->buf_read[buf]);
- memset(&tran, 0, sizeof(tran));
- tran.delay_usecs = 0;
- tran.speed_hz = BAB_SPI_SPEED;
- i = 0;
- pos = 0;
- for (bank = 0; bank <= BAB_MAXBANKS; bank++) {
- if (babinfo->bank_off[buf][bank]) {
- bab_reset(bank, 64);
- break;
- }
- }
- if (unlikely(bank > BAB_MAXBANKS)) {
- applog(LOG_ERR, "%s%d: %s() failed to find a bank" BAB_FFL,
- babcgpu->drv->name, babcgpu->device_id,
- __func__, BAB_FFL_PASS);
- return false;
- }
- while (siz > 0) {
- tran.tx_buf = wbuf;
- tran.rx_buf = rbuf;
- tran.speed_hz = BAB_SPI_SPEED;
- if (pos == babinfo->bank_off[buf][bank]) {
- for (; ++bank <= BAB_MAXBANKS; ) {
- if (babinfo->bank_off[buf][bank] > pos) {
- bab_reset(bank, 64);
- break;
- }
- }
- }
- if (siz < BAB_SPI_BUFSIZ)
- tran.len = siz;
- else
- tran.len = BAB_SPI_BUFSIZ;
- if (pos < babinfo->bank_off[buf][bank] &&
- babinfo->bank_off[buf][bank] < (pos + tran.len))
- tran.len = babinfo->bank_off[buf][bank] - pos;
- for (; i < babinfo->chips; i++) {
- if (!babinfo->chip_off[buf][i])
- continue;
- if (babinfo->chip_off[buf][i] >= pos + tran.len) {
- tran.speed_hz = babinfo->chip_spis[i];
- break;
- }
- }
- if (unlikely(i > babinfo->chips)) {
- applog(LOG_ERR, "%s%d: %s() failed to find chip" BAB_FFL,
- babcgpu->drv->name, babcgpu->device_id,
- __func__, BAB_FFL_PASS);
- return false;
- }
- if (unlikely(babinfo->chip_spis[i] == BAB_SPI_SPEED)) {
- applog(LOG_DEBUG, "%s%d: %s() chip[%d] speed %d shouldn't be %d" BAB_FFL,
- babcgpu->drv->name, babcgpu->device_id,
- __func__, i, (int)babinfo->chip_spis[i],
- BAB_SPI_SPEED, BAB_FFL_PASS);
- }
- if (unlikely(tran.speed_hz == BAB_SPI_SPEED)) {
- applog(LOG_DEBUG, "%s%d: %s() transfer speed %d shouldn't be %d" BAB_FFL,
- babcgpu->drv->name, babcgpu->device_id,
- __func__, (int)tran.speed_hz,
- BAB_SPI_SPEED, BAB_FFL_PASS);
- }
- if (ioctl(babinfo->spifd, SPI_IOC_MESSAGE(1), (void *)&tran) < 0) {
- if (!detect_ignore || errno != 110) {
- applog(LOG_ERR, "%s%d: ioctl failed err=%d" BAB_FFL,
- babcgpu->drv->name, babcgpu->device_id,
- errno, BAB_FFL_PASS);
- }
- return false;
- }
- siz -= tran.len;
- wbuf += tran.len;
- rbuf += tran.len;
- pos += tran.len;
- }
- mutex_lock(&(babinfo->did_lock));
- cgtime(&(babinfo->last_did));
- mutex_unlock(&(babinfo->did_lock));
- return true;
- }
- static void _bab_add_buf_rev(__maybe_unused struct cgpu_info *babcgpu, struct bab_info *babinfo, const uint8_t *data, uint32_t siz, const char *file, const char *func, const int line)
- {
- uint8_t tmp;
- uint32_t now_used, i;
- int buf;
- buf = babinfo->buffer;
- now_used = babinfo->buf_used[buf];
- if (now_used + siz >= BAB_MAXBUF) {
- quitfrom(1, file, func, line,
- "%s() buffer %d limit of %d exceeded=%d siz=%d",
- __func__, buf, BAB_MAXBUF, now_used + siz, siz);
- }
- for (i = 0; i < siz; i++) {
- tmp = data[i];
- tmp = ((tmp & 0xaa)>>1) | ((tmp & 0x55) << 1);
- tmp = ((tmp & 0xcc)>>2) | ((tmp & 0x33) << 2);
- tmp = ((tmp & 0xf0)>>4) | ((tmp & 0x0f) << 4);
- babinfo->buf_write[buf][now_used + i] = tmp;
- }
- babinfo->buf_used[buf] += siz;
- }
- static void _bab_add_buf(__maybe_unused struct cgpu_info *babcgpu, struct bab_info *babinfo, const uint8_t *data, size_t siz, const char *file, const char *func, const int line)
- {
- uint32_t now_used;
- int buf;
- buf = babinfo->buffer;
- now_used = babinfo->buf_used[buf];
- if (now_used + siz >= BAB_MAXBUF) {
- quitfrom(1, file, func, line,
- "%s() buffer %d limit of %d exceeded=%d siz=%d",
- __func__, buf, BAB_MAXBUF, (int)(now_used + siz), (int)siz);
- }
- memcpy(&(babinfo->buf_write[buf][now_used]), data, siz);
- babinfo->buf_used[buf] += siz;
- }
- static void _bab_add_data(struct cgpu_info *babcgpu, struct bab_info *babinfo, uint32_t addr, const uint8_t *data, size_t siz, const char *file, const char *func, const int line)
- {
- uint8_t tmp[3];
- int trf_siz;
- if (siz < BAB_ADD_MIN || siz > BAB_ADD_MAX) {
- quitfrom(1, file, func, line,
- "%s() called with invalid siz=%d (min=%d max=%d)",
- __func__, (int)siz, BAB_ADD_MIN, BAB_ADD_MAX);
- }
- trf_siz = siz / 4;
- tmp[0] = (trf_siz - 1) | 0xE0;
- tmp[1] = (addr >> 8) & 0xff;
- tmp[2] = addr & 0xff;
- _bab_add_buf(babcgpu, babinfo, tmp, sizeof(tmp), BAB_FFL_PASS);
- _bab_add_buf_rev(babcgpu, babinfo, data, siz, BAB_FFL_PASS);
- }
- static void _bab_config_reg(struct cgpu_info *babcgpu, struct bab_info *babinfo, uint32_t reg, bool enable, const char *file, const char *func, const int line)
- {
- if (enable) {
- _bab_add_data(babcgpu, babinfo, BAB_REG_ADDR + reg*32,
- bab_reg_ena, sizeof(bab_reg_ena), BAB_FFL_PASS);
- } else {
- _bab_add_data(babcgpu, babinfo, BAB_REG_ADDR + reg*32,
- bab_reg_dis, sizeof(bab_reg_dis), BAB_FFL_PASS);
- }
- }
- static void bab_set_osc(struct bab_info *babinfo, int chip)
- {
- int fast, i;
- fast = babinfo->chip_fast[chip];
- for (i = 0; i < BAB_OSC && fast > BAB_OSC; i++, fast -= BAB_OSC) {
- babinfo->osc[i] = 0xff;
- }
- if (i < BAB_OSC && fast > 0 && fast <= BAB_OSC)
- babinfo->osc[i++] = bab_osc_bits[fast - 1];
- for (; i < BAB_OSC; i++)
- babinfo->osc[i] = 0x00;
- applog(LOG_DEBUG, "@osc(chip=%d) fast=%d 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", chip, fast, babinfo->osc[0], babinfo->osc[1], babinfo->osc[2], babinfo->osc[3], babinfo->osc[4], babinfo->osc[5], babinfo->osc[6], babinfo->osc[7]);
- }
- static bool bab_put(struct cgpu_info *babcgpu, struct bab_info *babinfo)
- {
- int buf, i, reg, bank = 0;
- babinfo->buffer = -1;
- mutex_lock(&(babinfo->spi_lock));
- if (babinfo->buf_status[0] == BAB_STATE_DONE) {
- babinfo->buffer = 0;
- } else if (babinfo->buf_status[1] == BAB_STATE_DONE) {
- babinfo->buffer = 1;
- } else if (babinfo->buf_status[0] == BAB_STATE_READY) {
- babinfo->buf_status[0] = BAB_STATE_DONE;
- babinfo->buffer = 0;
- } else if (babinfo->buf_status[1] == BAB_STATE_READY) {
- babinfo->buf_status[1] = BAB_STATE_DONE;
- babinfo->buffer = 1;
- }
- mutex_unlock(&(babinfo->spi_lock));
- if (babinfo->buffer == -1)
- return false;
- buf = babinfo->buffer;
- babinfo->buf_used[buf] = 0;
- memset(babinfo->bank_off[buf], 0, sizeof(babinfo->bank_off) / BAB_SPI_BUFFERS);
- BAB_ADD_BREAK();
- for (i = 0; i < babinfo->chips; i++) {
- if (babinfo->chip_bank[i] != bank) {
- babinfo->bank_off[buf][bank] = babinfo->buf_used[buf];
- bank = babinfo->chip_bank[i];
- BAB_ADD_BREAK();
- }
- if (i == babinfo->fixchip &&
- (BAB_CFGD_SET(babinfo->chip_conf[i]) ||
- !babinfo->chip_conf[i])) {
- bab_set_osc(babinfo, i);
- bab_add_data(BAB_OSC_ADDR, babinfo->osc, sizeof(babinfo->osc));
- bab_config_reg(BAB_ICLK_REG, BAB_ICLK_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_FAST_REG, BAB_FAST_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_DIV2_REG, BAB_DIV2_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_SLOW_REG, BAB_SLOW_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_OCLK_REG, BAB_OCLK_BIT(babinfo->chip_conf[i]));
- for (reg = BAB_REG_CLR_FROM; reg <= BAB_REG_CLR_TO; reg++)
- bab_config_reg(reg, false);
- if (babinfo->chip_conf[i]) {
- bab_add_data(BAB_COUNT_ADDR, bab_counters, sizeof(bab_counters));
- bab_add_data(BAB_W1A_ADDR, bab_w1, sizeof(bab_w1));
- bab_add_data(BAB_W1B_ADDR, bab_w1, sizeof(bab_w1)/2);
- bab_add_data(BAB_W2_ADDR, bab_w2, sizeof(bab_w2));
- babinfo->chip_conf[i] ^= BAB_CFGD_VAL;
- }
- babinfo->old_fast[i] = babinfo->chip_fast[i];
- babinfo->old_conf[i] = babinfo->chip_conf[i];
- } else {
- if (babinfo->old_fast[i] != babinfo->chip_fast[i]) {
- bab_set_osc(babinfo, i);
- bab_add_data(BAB_OSC_ADDR, babinfo->osc, sizeof(babinfo->osc));
- babinfo->old_fast[i] = babinfo->chip_fast[i];
- }
- if (babinfo->old_conf[i] != babinfo->chip_conf[i]) {
- if (BAB_ICLK_SET(babinfo->old_conf[i]) !=
- BAB_ICLK_SET(babinfo->chip_conf[i]))
- bab_config_reg(BAB_ICLK_REG,
- BAB_ICLK_BIT(babinfo->chip_conf[i]));
- if (BAB_FAST_SET(babinfo->old_conf[i]) !=
- BAB_FAST_SET(babinfo->chip_conf[i]))
- bab_config_reg(BAB_FAST_REG,
- BAB_FAST_BIT(babinfo->chip_conf[i]));
- if (BAB_DIV2_SET(babinfo->old_conf[i]) !=
- BAB_DIV2_SET(babinfo->chip_conf[i]))
- bab_config_reg(BAB_DIV2_REG,
- BAB_DIV2_BIT(babinfo->chip_conf[i]));
- if (BAB_SLOW_SET(babinfo->old_conf[i]) !=
- BAB_SLOW_SET(babinfo->chip_conf[i]))
- bab_config_reg(BAB_SLOW_REG,
- BAB_SLOW_BIT(babinfo->chip_conf[i]));
- if (BAB_OCLK_SET(babinfo->old_conf[i]) !=
- BAB_OCLK_SET(babinfo->chip_conf[i]))
- bab_config_reg(BAB_OCLK_REG,
- BAB_OCLK_BIT(babinfo->chip_conf[i]));
- babinfo->old_conf[i] = babinfo->chip_conf[i];
- }
- }
- babinfo->chip_off[buf][i] = babinfo->buf_used[buf] + 3;
- if (babinfo->chip_conf[i])
- bab_add_data(BAB_INP_ADDR, (uint8_t *)(&(babinfo->chip_input[i])),
- sizeof(babinfo->chip_input[i]));
- BAB_ADD_ASYNC();
- }
- babinfo->chip_off[buf][i] = babinfo->buf_used[buf];
- babinfo->bank_off[buf][bank] = babinfo->buf_used[buf];
- mutex_lock(&(babinfo->spi_lock));
- babinfo->buf_status[buf] = BAB_STATE_READY;
- mutex_unlock(&(babinfo->spi_lock));
- babinfo->fixchip = (babinfo->fixchip + 1) % babinfo->chips;
- return true;
- }
- static bool bab_get(__maybe_unused struct cgpu_info *babcgpu, struct bab_info *babinfo)
- {
- int buf, i;
- babinfo->buffer = -1;
- mutex_lock(&(babinfo->spi_lock));
- if (babinfo->buf_status[0] == BAB_STATE_SENT) {
- babinfo->buf_status[0] = BAB_STATE_READING;
- babinfo->buffer = 0;
- } else if (babinfo->buf_status[1] == BAB_STATE_SENT) {
- babinfo->buf_status[1] = BAB_STATE_READING;
- babinfo->buffer = 1;
- }
- mutex_unlock(&(babinfo->spi_lock));
- if (babinfo->buffer == -1)
- return false;
- buf = babinfo->buffer;
- for (i = 0; i < babinfo->chips; i++) {
- if (babinfo->chip_conf[i] & 0x7f) {
- memcpy((void *)&(babinfo->chip_results[i]),
- (void *)(babinfo->buf_read[buf] + babinfo->chip_off[buf][i]),
- sizeof(babinfo->chip_results[0]));
- }
- }
- mutex_lock(&(babinfo->spi_lock));
- babinfo->buf_status[buf] = BAB_STATE_DONE;
- mutex_unlock(&(babinfo->spi_lock));
- return true;
- }
- void bab_detect_chips(struct cgpu_info *babcgpu, struct bab_info *babinfo, int bank, int first, int last)
- {
- int buf, i, reg, j;
- if (sizeof(struct bab_work_send) != sizeof(bab_test_data)) {
- quithere(1, "struct bab_work_send (%d) and bab_test_data (%d)"
- " must be the same size",
- (int)sizeof(struct bab_work_send),
- (int)sizeof(bab_test_data));
- }
- memset(babinfo->bank_off, 0, sizeof(babinfo->bank_off));
- buf = babinfo->buffer = 0;
- babinfo->buf_used[buf] = 0;
- BAB_ADD_BREAK();
- for (i = first; i < last && i < BAB_MAXCHIPS; i++) {
- bab_set_osc(babinfo, i);
- bab_add_data(BAB_OSC_ADDR, babinfo->osc, sizeof(babinfo->osc));
- bab_config_reg(BAB_ICLK_REG, BAB_ICLK_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_FAST_REG, BAB_FAST_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_DIV2_REG, BAB_DIV2_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_SLOW_REG, BAB_SLOW_BIT(babinfo->chip_conf[i]));
- bab_config_reg(BAB_OCLK_REG, BAB_OCLK_BIT(babinfo->chip_conf[i]));
- for (reg = BAB_REG_CLR_FROM; reg <= BAB_REG_CLR_TO; reg++)
- bab_config_reg(reg, false);
- bab_add_data(BAB_COUNT_ADDR, bab_counters, sizeof(bab_counters));
- bab_add_data(BAB_W1A_ADDR, bab_w1, sizeof(bab_w1));
- bab_add_data(BAB_W1B_ADDR, bab_w1, sizeof(bab_w1)/2);
- bab_add_data(BAB_W2_ADDR, bab_w2, sizeof(bab_w2));
- babinfo->chip_off[buf][i] = babinfo->buf_used[buf] + 3;
- bab_add_data(BAB_INP_ADDR, bab_test_data, sizeof(bab_test_data));
- babinfo->chip_off[buf][i+1] = babinfo->buf_used[buf];
- babinfo->bank_off[buf][bank] = babinfo->buf_used[buf];
- babinfo->chips = i + 1;
- bab_txrx(buf, babinfo->buf_used[buf], false);
- babinfo->buf_used[buf] = 0;
- BAB_ADD_BREAK();
- for (j = first; j <= i; j++) {
- babinfo->chip_off[buf][j] = babinfo->buf_used[buf] + 3;
- BAB_ADD_ASYNC();
- }
- }
- buf = babinfo->buffer = 1;
- babinfo->buf_used[buf] = 0;
- BAB_ADD_BREAK();
- for (i = first; i < last && i < BAB_MAXCHIPS; i++) {
- babinfo->chip_off[buf][i] = babinfo->buf_used[buf] + 3;
- bab_add_data(BAB_INP_ADDR, bab_test_data, sizeof(bab_test_data));
- BAB_ADD_ASYNC();
- }
- babinfo->chip_off[buf][i] = babinfo->buf_used[buf];
- babinfo->bank_off[buf][bank] = babinfo->buf_used[buf];
- babinfo->chips = i;
- bab_txrx(buf, babinfo->buf_used[buf], true);
- babinfo->buf_used[buf] = 0;
- babinfo->chips = first;
- for (i = first; i < last && i < BAB_MAXCHIPS; i++) {
- uint32_t tmp[DATA_UINTS-1];
- memcpy(tmp, babinfo->buf_read[buf]+babinfo->chip_off[buf][i], sizeof(tmp));
- for (j = 0; j < BAB_SPI_BUFFERS; j++)
- babinfo->chip_off[j][i] = 0;
- for (j = 0; j < BAB_REPLY_NONCES; j++) {
- if (tmp[j] != 0xffffffff && tmp[j] != 0x00000000) {
- babinfo->chip_bank[i] = bank;
- babinfo->chips = i + 1;
- break;
- }
- }
- }
- for (i = first ; i < babinfo->chips; i++)
- babinfo->chip_bank[i] = bank;
- }
- static const char *bab_modules[] = {
- "i2c-dev",
- "i2c-bcm2708",
- "spidev",
- "spi-bcm2708",
- NULL
- };
- static const char *bab_memory = "/dev/mem";
- static int bab_memory_addr = 0x20200000;
- static struct {
- int request;
- int value;
- } bab_ioc[] = {
- { SPI_IOC_RD_MODE, 0 },
- { SPI_IOC_WR_MODE, 0 },
- { SPI_IOC_RD_BITS_PER_WORD, 8 },
- { SPI_IOC_WR_BITS_PER_WORD, 8 },
- { SPI_IOC_RD_MAX_SPEED_HZ, 1000000 },
- { SPI_IOC_WR_MAX_SPEED_HZ, 1000000 },
- { -1, -1 }
- };
- static bool bab_init_gpio(struct cgpu_info *babcgpu, struct bab_info *babinfo, int bus, int chip)
- {
- int i, err, memfd, data;
- char buf[64];
- for (i = 0; bab_modules[i]; i++) {
- snprintf(buf, sizeof(buf), "modprobe %s", bab_modules[i]);
- err = system(buf);
- if (err) {
- applog(LOG_ERR, "%s failed to modprobe %s (%d) - you need to be root?",
- babcgpu->drv->dname,
- bab_modules[i], err);
- goto bad_out;
- }
- }
- memfd = open(bab_memory, O_RDWR | O_SYNC);
- if (memfd < 0) {
- applog(LOG_ERR, "%s failed open %s (%d)",
- babcgpu->drv->dname,
- bab_memory, errno);
- goto bad_out;
- }
- babinfo->gpio = (volatile unsigned *)mmap(NULL, BAB_SPI_BUFSIZ,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, memfd,
- bab_memory_addr);
- if (babinfo->gpio == MAP_FAILED) {
- close(memfd);
- applog(LOG_ERR, "%s failed mmap gpio (%d)",
- babcgpu->drv->dname,
- errno);
- goto bad_out;
- }
- close(memfd);
- snprintf(buf, sizeof(buf), "/dev/spidev%d.%d", bus, chip);
- babinfo->spifd = open(buf, O_RDWR);
- if (babinfo->spifd < 0) {
- applog(LOG_ERR, "%s failed to open spidev (%d)",
- babcgpu->drv->dname,
- errno);
- goto map_out;
- }
- babcgpu->device_path = strdup(buf);
- for (i = 0; bab_ioc[i].value != -1; i++) {
- data = bab_ioc[i].value;
- err = ioctl(babinfo->spifd, bab_ioc[i].request, (void *)&data);
- if (err < 0) {
- applog(LOG_ERR, "%s failed ioctl (%d) (%d)",
- babcgpu->drv->dname,
- i, errno);
- goto close_out;
- }
- }
- for (i = 0; i < BAB_MAXCHIPS; i++)
- babinfo->chip_spis[i] = (int)((1000000.0 / (100.0 + 31.0 * (i + 1))) * 1000);
- return true;
- close_out:
- close(babinfo->spifd);
- babinfo->spifd = 0;
- free(babcgpu->device_path);
- babcgpu->device_path = NULL;
- map_out:
- munmap((void *)(babinfo->gpio), BAB_SPI_BUFSIZ);
- babinfo->gpio = NULL;
- bad_out:
- return false;
- }
- static void bab_init_chips(struct cgpu_info *babcgpu, struct bab_info *babinfo)
- {
- bab_detect_chips(babcgpu, babinfo, 0, 0, BAB_MAXCHIPS);
- memcpy(babinfo->old_conf, babinfo->chip_conf, sizeof(babinfo->old_conf));
- memcpy(babinfo->old_fast, babinfo->chip_fast, sizeof(babinfo->old_fast));
- }
- static void bab_detect(bool hotplug)
- {
- struct cgpu_info *babcgpu = NULL;
- struct bab_info *babinfo = NULL;
- int i;
- if (hotplug)
- return;
- babcgpu = calloc(1, sizeof(*babcgpu));
- if (unlikely(!babcgpu))
- quithere(1, "Failed to calloc babcgpu");
- babcgpu->drv = &bab_drv;
- babcgpu->deven = DEV_ENABLED;
- babcgpu->threads = 1;
- babinfo = calloc(1, sizeof(*babinfo));
- if (unlikely(!babinfo))
- quithere(1, "Failed to calloc babinfo");
- babcgpu->device_data = (void *)babinfo;
- for (i = 0; i < BAB_MAXCHIPS; i++) {
- babinfo->chip_conf[i] = BAB_DEFCONF;
- babinfo->chip_fast[i] = BAB_DEFSPEED;
- }
- mutex_init(&babinfo->spi_lock);
- if (!bab_init_gpio(babcgpu, babinfo, BAB_SPI_BUS, BAB_SPI_CHIP))
- goto unalloc;
- applog(LOG_WARNING, "%s V1 testing for %d chips ...", babcgpu->drv->dname, BAB_MAXCHIPS);
- bab_init_chips(babcgpu, babinfo);
- applog(LOG_WARNING, "%s found %d chips", babcgpu->drv->dname, babinfo->chips);
- if (babinfo->chips == 0)
- goto cleanup;
- if (!add_cgpu(babcgpu))
- goto cleanup;
- mutex_init(&babinfo->res_lock);
- mutex_init(&babinfo->did_lock);
- cglock_init(&babinfo->blist_lock);
- babinfo->initialised = true;
- return;
- cleanup:
- close(babinfo->spifd);
- munmap((void *)(babinfo->gpio), BAB_SPI_BUFSIZ);
- unalloc:
- mutex_destroy(&babinfo->spi_lock);
- free(babinfo);
- free(babcgpu);
- }
- static void bab_identify(__maybe_unused struct cgpu_info *babcgpu)
- {
- }
- #define BAB_LONG_WAIT_uS 1200000
- #define BAB_WAIT_MSG_EVERY 10
- #define BAB_LONG_WAIT_SLEEP_uS 100000
- #define BAB_STD_WAIT_uS 3000
- // thread to do spi txrx
- static void *bab_spi(void *userdata)
- {
- struct cgpu_info *babcgpu = (struct cgpu_info *)userdata;
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- struct timeval start, stop;
- double wait;
- int i, buf, msgs;
- applog(LOG_DEBUG, "%s%i: SPIing...",
- babcgpu->drv->name, babcgpu->device_id);
- // Wait until we're ready
- while (babcgpu->shutdown == false) {
- if (babinfo->initialised) {
- break;
- }
- cgsleep_ms(3);
- }
- msgs = 0;
- cgtime(&start);
- while (babcgpu->shutdown == false) {
- buf = -1;
- mutex_lock(&(babinfo->spi_lock));
- for (i = 0; i < BAB_SPI_BUFFERS; i++) {
- if (babinfo->buf_status[i] == BAB_STATE_READY) {
- babinfo->buf_status[i] = BAB_STATE_SENDING;
- buf = i;
- cgtime(&start);
- break;
- }
- }
- mutex_unlock(&(babinfo->spi_lock));
- if (buf == -1) {
- cgtime(&stop);
- wait = us_tdiff(&stop, &start);
- if (wait > BAB_LONG_WAIT_uS) {
- if ((msgs++ % BAB_WAIT_MSG_EVERY) == 0) {
- applog(LOG_WARNING, "%s%i: SPI waiting %.0fus ...",
- babcgpu->drv->name,
- babcgpu->device_id,
- (float)wait);
- }
- }
- cgsleep_us(BAB_LONG_WAIT_SLEEP_uS);
- continue;
- }
- bab_txrx(buf, babinfo->buf_used[buf], false);
- cgtime(&stop);
- wait = us_tdiff(&stop, &start);
- if (wait < BAB_STD_WAIT_uS)
- cgsleep_us((uint64_t)(BAB_STD_WAIT_uS - wait));
- else if (wait > BAB_LONG_WAIT_uS) {
- applog(LOG_DEBUG, "%s%i: SPI waited %.0fus",
- babcgpu->drv->name, babcgpu->device_id,
- (float)wait);
- }
- mutex_lock(&(babinfo->spi_lock));
- babinfo->buf_status[i] = BAB_STATE_SENT;
- mutex_unlock(&(babinfo->spi_lock));
- msgs = 0;
- }
- return NULL;
- }
- static void bab_flush_work(struct cgpu_info *babcgpu)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- applog(LOG_DEBUG, "%s%i: flushing work",
- babcgpu->drv->name, babcgpu->device_id);
- mutex_lock(&(babinfo->did_lock));
- memset(&(babinfo->last_did), 0, sizeof(babinfo->last_did));
- mutex_unlock(&(babinfo->did_lock));
- }
- static void ms3steps(uint32_t *p)
- {
- uint32_t a, b, c, d, e, f, g, h, new_e, new_a;
- int i;
- a = p[0];
- b = p[1];
- c = p[2];
- d = p[3];
- e = p[4];
- f = p[5];
- g = p[6];
- h = p[7];
- for (i = 0; i < 3; i++) {
- new_e = p[i+16] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) + d;
- new_a = p[i+16] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) +
- SHA256_F1(a) + MAJ(a,b,c);
- d = c;
- c = b;
- b = a;
- a = new_a;
- h = g;
- g = f;
- f = e;
- e = new_e;
- }
- p[15] = a;
- p[14] = b;
- p[13] = c;
- p[12] = d;
- p[11] = e;
- p[10] = f;
- p[9] = g;
- p[8] = h;
- }
- #define DATA_MERKLE7 16
- #define DATA_NTIME 17
- #define DATA_BITS 18
- #define DATA_NONCE 19
- #define WORK_MERKLE7 (16*4)
- #define WORK_NTIME (17*4)
- #define WORK_BITS (18*4)
- #define WORK_NONCE (19*4)
- static uint32_t decnonce(uint32_t in)
- {
- uint32_t out;
- /* First part load */
- out = (in & 0xFF) << 24;
- in >>= 8;
- /* Byte reversal */
- in = (((in & 0xaaaaaaaa) >> 1) | ((in & 0x55555555) << 1));
- in = (((in & 0xcccccccc) >> 2) | ((in & 0x33333333) << 2));
- in = (((in & 0xf0f0f0f0) >> 4) | ((in & 0x0f0f0f0f) << 4));
- out |= (in >> 2) & 0x3FFFFF;
- /* Extraction */
- if (in & 1)
- out |= (1 << 23);
- if (in & 2)
- out |= (1 << 22);
- out -= 0x800004;
- return out;
- }
- /*
- * Find the matching work item by checking the nonce against each work
- * item for the chip
- * Discard any work items older than a match
- */
- static bool oknonce(struct thr_info *thr, struct cgpu_info *babcgpu, int chip, uint32_t nonce)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- BLIST *bitem;
- unsigned int links, tests;
- int i;
- babinfo->chip_nonces[chip]++;
- nonce = decnonce(nonce);
- /*
- * We can grab the head of the chip work queue and then
- * release the lock and follow it to the end
- * since the other thread will only add items above the
- * head - it wont touch the list->next pointers from the
- * head to the end - only the head->prev pointer may get
- * changed
- */
- cg_rlock(&babinfo->blist_lock);
- bitem = babinfo->chip_list[chip];
- cg_runlock(&babinfo->blist_lock);
- if (!bitem) {
- applog(LOG_ERR, "%s%i: chip %d has no work!",
- babcgpu->drv->name, babcgpu->device_id, chip);
- babinfo->untested_nonces++;
- return false;
- }
- babinfo->tested_nonces++;
- tests = 0;
- links = 0;
- while (bitem) {
- if (!bitem->work) {
- applog(LOG_ERR, "%s%i: chip %d bitem links %d has no work!",
- babcgpu->drv->name,
- babcgpu->device_id,
- chip, links);
- } else {
- for (i = 0; i < BAB_NONCE_OFFSETS; i++) {
- tests++;
- if (test_nonce(bitem->work, nonce + bab_nonce_offsets[i])) {
- submit_tested_work(thr, bitem->work);
- babinfo->nonce_offset_count[i]++;
- babinfo->chip_good[chip]++;
- bitem->nonces++;
- babinfo->new_nonces++;
- babinfo->ok_nonces++;
- free_blist(babcgpu, bitem->next, chip);
- babinfo->total_tests += tests;
- if (babinfo->max_tests_per_nonce < tests)
- babinfo->max_tests_per_nonce = tests;
- babinfo->total_links += links;
- if (babinfo->max_links < links)
- babinfo->max_links = links;
- return true;
- }
- }
- }
- bitem = bitem->next;
- links++;
- }
- if (babinfo->not_first_reply[chip]) {
- babinfo->chip_bad[chip]++;
- inc_hw_errors(thr);
- } else
- babinfo->initial_ignored++;
- return false;
- }
- // Results checking thread
- static void *bab_res(void *userdata)
- {
- struct cgpu_info *babcgpu = (struct cgpu_info *)userdata;
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- struct thr_info *thr = babcgpu->thr[0];
- bool first_second;
- uint32_t nonce;
- int chip;
- applog(LOG_DEBUG, "%s%i: Results...",
- babcgpu->drv->name, babcgpu->device_id);
- // Wait until we're ready
- while (babcgpu->shutdown == false) {
- if (babinfo->initialised) {
- break;
- }
- cgsleep_ms(3);
- }
- while (babcgpu->shutdown == false) {
- if (!oldest_nonce(babcgpu, &chip, &nonce, &first_second)) {
- cgsleep_ms(3);
- continue;
- }
- if (first_second)
- babinfo->not_first_reply[chip] = true;
- oknonce(thr, babcgpu, chip, nonce);
- }
- return NULL;
- }
- static bool bab_do_work(struct cgpu_info *babcgpu)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- int busy, newbusy, match, work_items = 0;
- int spi, mis, miso;
- int i, j;
- BLIST *bitem;
- bool res, got_a_nonce;
- for (i = 0; i < babinfo->chips; i++) {
- bitem = next_work(babcgpu, i);
- if (!bitem) {
- applog(LOG_ERR, "%s%i: short work list (%i) expected %d - discarded",
- babcgpu->drv->name, babcgpu->device_id,
- i, babinfo->chips);
- for (j = 0; j < i; i++)
- discard_last(babcgpu, j);
- return false;
- }
- memcpy((void *)&(babinfo->chip_input[i].midstate[0]),
- bitem->work->midstate, sizeof(bitem->work->midstate));
- memcpy((void *)&(babinfo->chip_input[i].merkle7),
- (void *)&(bitem->work->data[WORK_MERKLE7]), 12);
- ms3steps((void *)&(babinfo->chip_input[i]));
- work_items++;
- }
- // Send
- res = bab_put(babcgpu, babinfo);
- if (!res) {
- applog(LOG_DEBUG, "%s%i: couldn't put work ...",
- babcgpu->drv->name, babcgpu->device_id);
- }
- // Receive
- res = bab_get(babcgpu, babinfo);
- if (!res) {
- applog(LOG_DEBUG, "%s%i: didn't get work reply ...",
- babcgpu->drv->name, babcgpu->device_id);
- return false;
- }
- applog(LOG_DEBUG, "%s%i: Did get work reply ...",
- babcgpu->drv->name, babcgpu->device_id);
- spi = mis = miso = 0;
- for (i = 0; i < babinfo->chips; i++) {
- match = 0;
- newbusy = busy = babinfo->chip_busy[i];
- if (!babinfo->chip_conf[i])
- continue;
- for (j = 1; j < BAB_REPLY_NONCES; j++) {
- if (babinfo->chip_results[i].nonce[(busy+j) % BAB_REPLY_NONCES] !=
- babinfo->chip_prev[i].nonce[(busy+j) % BAB_REPLY_NONCES])
- newbusy = (busy+j) % BAB_REPLY_NONCES;
- else
- match++;
- }
- if (!match) {
- if (!miso) {
- mis++;
- // ignore for now ... babinfo->chip_miso[i]++;
- }
- miso = 1;
- continue;
- }
- miso = 0;
- if (babinfo->chip_results[i].jobsel != 0xffffffff &&
- babinfo->chip_results[i].jobsel != 0x00000000) {
- spi++;
- babinfo->chip_spie[i]++;
- applog(LOG_DEBUG, "%s%i: SPI ERROR on chip %d (0x%08x)",
- babcgpu->drv->name, babcgpu->device_id,
- i, babinfo->chip_results[i].jobsel);
- }
- // Not used yet
- // if (babinfo->chip_results[i].jobsel != babinfo->chip_prev[i].jobsel) {
- got_a_nonce = false;
- for (; newbusy != busy; busy = (busy + 1) % BAB_REPLY_NONCES) {
- if (babinfo->chip_results[i].nonce[busy] == 0xffffffff ||
- babinfo->chip_results[i].nonce[busy] == 0x00000000) {
- babinfo->chip_results[i].nonce[busy] = babinfo->chip_prev[i].nonce[busy];
- spi = 1;
- continue;
- }
- store_nonce(babcgpu, i,
- babinfo->chip_results[i].nonce[busy],
- babinfo->nonce_before[i]);
- got_a_nonce = true;
- }
- /*
- * We only care about this after the first reply we find a nonce
- * After that, the value has no more effect
- */
- if (got_a_nonce)
- babinfo->nonce_before[i] = true;
- mis += miso;
- babinfo->chip_miso[i] += miso;
- babinfo->chip_busy[i] = busy;
- }
- memcpy((void *)(&(babinfo->chip_prev[0])),
- (void *)(&(babinfo->chip_results[0])),
- sizeof(babinfo->chip_prev));
- applog(LOG_DEBUG, "Work: items:%d spi:%d miso:%d",
- work_items, spi, mis);
- return true;
- }
- static bool bab_thread_prepare(struct thr_info *thr)
- {
- struct cgpu_info *babcgpu = thr->cgpu;
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- if (thr_info_create(&(babinfo->spi_thr), NULL, bab_spi, (void *)babcgpu)) {
- applog(LOG_ERR, "%s%i: SPI thread create failed",
- babcgpu->drv->name, babcgpu->device_id);
- return false;
- }
- pthread_detach(babinfo->spi_thr.pth);
- /*
- * We require a seperate results checking thread since there is a lot
- * of work done checking the results multiple times - thus we don't
- * want that delay affecting sending/receiving work to/from the device
- */
- if (thr_info_create(&(babinfo->res_thr), NULL, bab_res, (void *)babcgpu)) {
- applog(LOG_ERR, "%s%i: Results thread create failed",
- babcgpu->drv->name, babcgpu->device_id);
- return false;
- }
- pthread_detach(babinfo->res_thr.pth);
- return true;
- }
- static void bab_shutdown(struct thr_info *thr)
- {
- struct cgpu_info *babcgpu = thr->cgpu;
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- int i;
- applog(LOG_DEBUG, "%s%i: shutting down",
- babcgpu->drv->name, babcgpu->device_id);
- for (i = 0; i < babinfo->chips; i++)
- // TODO: bab_shutdown(babcgpu, babinfo, i);
- ;
- babcgpu->shutdown = true;
- }
- static bool bab_queue_full(struct cgpu_info *babcgpu)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- struct work *work;
- bool ret;
- if (babinfo->work_count >= babinfo->chips)
- ret = true;
- else {
- work = get_queued(babcgpu);
- if (work)
- store_work(babcgpu, work);
- else
- // Avoid a hard loop when we can't get work fast enough
- cgsleep_ms(10);
- ret = false;
- }
- return ret;
- }
- /*
- * 1.0s per nonce = 4.2GH/s
- * So anything around 4GH/s or less per chip should be fine
- */
- #define BAB_STD_WORK_uS 1000000
- #define BAB_STD_DELAY_uS 30000
- /*
- * TODO: allow this to run through more than once - the second+
- * time not sending any new work unless a flush occurs since:
- * at the moment we have BAB_STD_WORK_uS latency added to earliest replies
- */
- static int64_t bab_scanwork(__maybe_unused struct thr_info *thr)
- {
- struct cgpu_info *babcgpu = thr->cgpu;
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- int64_t hashcount = 0;
- struct timeval now;
- double delay;
- bab_do_work(babcgpu);
- // Sleep now so we get the work "bab_queue_full()" just before we use it
- while (80085) {
- cgtime(&now);
- mutex_lock(&(babinfo->did_lock));
- delay = us_tdiff(&now, &(babinfo->last_did));
- mutex_unlock(&(babinfo->did_lock));
- if (delay < (BAB_STD_WORK_uS - BAB_STD_DELAY_uS))
- cgsleep_us(BAB_STD_DELAY_uS);
- else
- break;
- }
- if (babinfo->new_nonces) {
- hashcount += 0xffffffffull * babinfo->new_nonces;
- babinfo->new_nonces = 0;
- }
- return hashcount;
- }
- #define CHIPS_PER_STAT 16
- static struct api_data *bab_api_stats(struct cgpu_info *babcgpu)
- {
- struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
- struct api_data *root = NULL;
- char data[2048];
- char buf[32];
- int i, to, j;
- if (babinfo->initialised == false)
- return NULL;
- root = api_add_int(root, "Chips", &(babinfo->chips), true);
- for (i = 0; i < babinfo->chips; i += CHIPS_PER_STAT) {
- to = i + CHIPS_PER_STAT - 1;
- if (to >= babinfo->chips)
- to = babinfo->chips - 1;
- data[0] = '\0';
- for (j = i; j <= to; j++) {
- snprintf(buf, sizeof(buf),
- "%s%"PRIu64,
- j == i ? "" : " ",
- babinfo->chip_nonces[j]);
- strcat(data, buf);
- }
- snprintf(buf, sizeof(buf), "Nonces %d - %d", i, to);
- root = api_add_string(root, buf, data, true);
- data[0] = '\0';
- for (j = i; j <= to; j++) {
- snprintf(buf, sizeof(buf),
- "%s%"PRIu64,
- j == i ? "" : " ",
- babinfo->chip_good[j]);
- strcat(data, buf);
- }
- snprintf(buf, sizeof(buf), "Good %d - %d", i, to);
- root = api_add_string(root, buf, data, true);
- data[0] = '\0';
- for (j = i; j <= to; j++) {
- snprintf(buf, sizeof(buf),
- "%s%"PRIu64,
- j == i ? "" : " ",
- babinfo->chip_bad[j]);
- strcat(data, buf);
- }
- snprintf(buf, sizeof(buf), "Bad %d - %d", i, to);
- root = api_add_string(root, buf, data, true);
- data[0] = '\0';
- for (j = i; j <= to; j++) {
- snprintf(buf, sizeof(buf),
- "%s0x%02x",
- j == i ? "" : " ",
- (int)(babinfo->chip_conf[j]));
- strcat(data, buf);
- }
- snprintf(buf, sizeof(buf), "Conf %d - %d", i, to);
- root = api_add_string(root, buf, data, true);
- data[0] = '\0';
- for (j = i; j <= to; j++) {
- snprintf(buf, sizeof(buf),
- "%s0x%02x",
- j == i ? "" : " ",
- (int)(babinfo->chip_fast[j]));
- strcat(data, buf);
- }
- snprintf(buf, sizeof(buf), "Fast %d - %d", i, to);
- root = api_add_string(root, buf, data, true);
- }
- for (i = 0; i < BAB_NONCE_OFFSETS; i++) {
- snprintf(buf, sizeof(buf), "Nonce Offset 0x%08x", bab_nonce_offsets[i]);
- root = api_add_uint64(root, buf, &(babinfo->nonce_offset_count[i]), true);
- }
- root = api_add_uint64(root, "Tested", &(babinfo->tested_nonces), true);
- root = api_add_uint64(root, "Total Tests", &(babinfo->total_tests), true);
- root = api_add_uint64(root, "Max Tests", &(babinfo->max_tests_per_nonce), true);
- float avg = babinfo->tested_nonces ? (float)(babinfo->total_tests) /
- (float)(babinfo->tested_nonces) : 0;
- // TODO: add a API_AVG which is 3 places - double/float?
- root = api_add_volts(root, "Avg Tests", &avg, true);
- root = api_add_uint64(root, "Untested", &(babinfo->untested_nonces), true);
- root = api_add_uint64(root, "Work Links", &(babinfo->total_links), true);
- root = api_add_uint64(root, "Max Links", &(babinfo->max_links), true);
- avg = babinfo->tested_nonces ? (float)(babinfo->total_links) /
- (float)(babinfo->tested_nonces) : 0;
- root = api_add_volts(root, "Avg Links", &avg, true);
- root = api_add_uint32(root, "Initial Ignored", &(babinfo->initial_ignored), true);
- root = api_add_int(root, "BList Count", &(babinfo->blist_count), true);
- root = api_add_int(root, "BFree Count", &(babinfo->bfree_count), true);
- root = api_add_int(root, "Work Count", &(babinfo->work_count), true);
- root = api_add_int(root, "Chip Count", &(babinfo->chip_count), true);
- root = api_add_int(root, "RList Count", &(babinfo->rlist_count), true);
- root = api_add_int(root, "RFree Count", &(babinfo->rfree_count), true);
- root = api_add_int(root, "Result Count", &(babinfo->res_count), true);
- return root;
- }
- #endif
- struct device_drv bab_drv = {
- .drv_id = DRIVER_bab,
- .dname = "BlackArrowBitFuryGPIO",
- .name = "BaB",
- .drv_detect = bab_detect,
- #ifdef LINUX
- .get_api_stats = bab_api_stats,
- //TODO: .get_statline_before = get_bab_statline_before,
- .identify_device = bab_identify,
- .thread_prepare = bab_thread_prepare,
- .hash_work = hash_queued_work,
- .scanwork = bab_scanwork,
- .queue_full = bab_queue_full,
- .flush_work = bab_flush_work,
- .thread_shutdown = bab_shutdown
- #endif
- };
|