diff --git a/driver-bflsc.c b/driver-bflsc.c index 2dcf7349..328d4648 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -462,6 +462,105 @@ static void xlinkstr(char *xlink, int dev, struct bflsc_info *sc_info) } } +static int write_to_dev(struct cgpu_info *bflsc, int dev, char *buf, int buflen, int *amount, enum usb_cmds cmd) +{ + struct DataForwardToChain data; + int len; + + if (dev == 0) + return usb_write(bflsc, buf, buflen, amount, cmd); + + data.header = BFLSC_XLINKHDR; + data.deviceAddress = (uint8_t)dev; + data.payloadSize = buflen; + memcpy(data.payloadData, buf, buflen); + len = DATAFORWARDSIZE(data); + + // TODO: handle xlink timeout message - here or at call? + return usb_write(bflsc, (char *)&data, len, amount, cmd); +} + +static bool getok(struct cgpu_info *bflsc, enum usb_cmds cmd, int *err, int *amount) +{ + char buf[BFLSC_BUFSIZ+1]; + + *err = usb_ftdi_read_nl(bflsc, buf, sizeof(buf)-1, amount, cmd); + if (*err < 0 || *amount < (int)BFLSC_OK_LEN) + return false; + else + return true; +} + +static bool getokerr(struct cgpu_info *bflsc, enum usb_cmds cmd, int *err, int *amount, char *buf, size_t bufsiz) +{ + *err = usb_ftdi_read_nl(bflsc, buf, bufsiz-1, amount, cmd); + if (*err < 0 || *amount < (int)BFLSC_OK_LEN) + return false; + else { + if (*amount > (int)BFLSC_ANERR_LEN && strncmp(buf, BFLSC_ANERR, BFLSC_ANERR_LEN) == 0) + return false; + else + return true; + } +} + +static void bflsc_send_flush_work(struct cgpu_info *bflsc, int dev) +{ + int err, amount; + + // Device is gone + if (bflsc->usbinfo.nodev) + return; + + mutex_lock(&bflsc->device_mutex); + + err = write_to_dev(bflsc, dev, BFLSC_QFLUSH, BFLSC_QFLUSH_LEN, &amount, C_QUEFLUSH); + if (err < 0 || amount != BFLSC_QFLUSH_LEN) { + mutex_unlock(&bflsc->device_mutex); + bflsc_applog(bflsc, dev, C_QUEFLUSH, amount, err); + } else { + // TODO: do we care if we don't get 'OK'? (always will in normal processing) + err = getok(bflsc, C_QUEFLUSHREPLY, &err, &amount); + mutex_unlock(&bflsc->device_mutex); + // TODO: report an error if not 'OK' ? + } +} + +/* return True = attempted usb_ftdi_read_ok() + * set ignore to true means no applog/ignore errors */ +static bool bflsc_qres(struct cgpu_info *bflsc, char *buf, size_t bufsiz, int dev, int *err, int *amount, bool ignore) +{ + bool readok = false; + + mutex_lock(&(bflsc->device_mutex)); + + *err = write_to_dev(bflsc, dev, BFLSC_QRES, BFLSC_QRES_LEN, amount, C_REQUESTRESULTS); + if (*err < 0 || *amount != BFLSC_QRES_LEN) { + mutex_unlock(&(bflsc->device_mutex)); + if (!ignore) + bflsc_applog(bflsc, dev, C_REQUESTRESULTS, *amount, *err); + + // TODO: do what? flag as dead device? + // count how many times it has happened and reset/fail it + // or even make sure it is all x-link and that means device + // has failed after some limit of this? + // of course all other I/O must also be failing ... + } else { + readok = true; + *err = usb_ftdi_read_ok(bflsc, buf, bufsiz-1, amount, C_GETRESULTS); + mutex_unlock(&(bflsc->device_mutex)); + + if (*err < 0 || *amount < 1) { + if (!ignore) + bflsc_applog(bflsc, dev, C_GETRESULTS, *amount, *err); + + // TODO: do what? ... see above + } + } + + return readok; +} + static void __bflsc_initialise(struct cgpu_info *bflsc) { int err; @@ -546,27 +645,19 @@ static void __bflsc_initialise(struct cgpu_info *bflsc) static void bflsc_initialise(struct cgpu_info *bflsc) { + struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_file); + char buf[BFLSC_BUFSIZ+1]; + int err, amount; + int dev; + mutex_lock(&(bflsc->device_mutex)); __bflsc_initialise(bflsc); mutex_unlock(&(bflsc->device_mutex)); -} - -static int write_to_dev(struct cgpu_info *bflsc, int dev, char *buf, int buflen, int *amount, enum usb_cmds cmd) -{ - struct DataForwardToChain data; - int len; - - if (dev == 0) - return usb_write(bflsc, buf, buflen, amount, cmd); - - data.header = BFLSC_XLINKHDR; - data.deviceAddress = (uint8_t)dev; - data.payloadSize = buflen; - memcpy(data.payloadData, buf, buflen); - len = DATAFORWARDSIZE(data); - // TODO: handle xlink timeout message - here or at call? - return usb_write(bflsc, (char *)&data, len, amount, cmd); + for (dev = 0; dev < sc_info->sc_count; dev++) { + bflsc_send_flush_work(bflsc, dev); + bflsc_qres(bflsc, buf, sizeof(buf), dev, &err, &amount, true); + } } static bool getinfo(struct cgpu_info *bflsc, int dev) @@ -865,52 +956,6 @@ static void get_bflsc_statline_before(char *buf, struct cgpu_info *bflsc) tailsprintf(buf, " max%3.0fC %4.2fV | ", temp, vcc1); } -static bool getok(struct cgpu_info *bflsc, enum usb_cmds cmd, int *err, int *amount) -{ - char buf[BFLSC_BUFSIZ+1]; - - *err = usb_ftdi_read_nl(bflsc, buf, sizeof(buf)-1, amount, cmd); - if (*err < 0 || *amount < (int)BFLSC_OK_LEN) - return false; - else - return true; -} - -static bool getokerr(struct cgpu_info *bflsc, enum usb_cmds cmd, int *err, int *amount, char *buf, size_t bufsiz) -{ - *err = usb_ftdi_read_nl(bflsc, buf, bufsiz-1, amount, cmd); - if (*err < 0 || *amount < (int)BFLSC_OK_LEN) - return false; - else { - if (*amount > (int)BFLSC_ANERR_LEN && strncmp(buf, BFLSC_ANERR, BFLSC_ANERR_LEN) == 0) - return false; - else - return true; - } -} - -static void bflsc_send_flush_work(struct cgpu_info *bflsc, int dev) -{ - int err, amount; - - // Device is gone - if (bflsc->usbinfo.nodev) - return; - - mutex_lock(&bflsc->device_mutex); - - err = write_to_dev(bflsc, dev, BFLSC_QFLUSH, BFLSC_QFLUSH_LEN, &amount, C_QUEFLUSH); - if (err < 0 || amount != BFLSC_QFLUSH_LEN) { - mutex_unlock(&bflsc->device_mutex); - bflsc_applog(bflsc, dev, C_QUEFLUSH, amount, err); - } else { - // TODO: do we care if we don't get 'OK'? (always will in normal processing) - err = getok(bflsc, C_QUEFLUSHREPLY, &err, &amount); - mutex_unlock(&bflsc->device_mutex); - // TODO: report an error if not 'OK' ? - } -} - static void flush_one_dev(struct cgpu_info *bflsc, int dev) { struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_file); @@ -1337,41 +1382,6 @@ arigatou: return que; } -/* return True = attempted usb_ftdi_read_ok() - * set ignore to true means no applog/ignore errors */ -static bool bflsc_qres(struct cgpu_info *bflsc, char *buf, size_t bufsiz, int dev, int *err, int *amount, bool ignore) -{ - bool readok = false; - - mutex_lock(&(bflsc->device_mutex)); - - *err = write_to_dev(bflsc, dev, BFLSC_QRES, BFLSC_QRES_LEN, amount, C_REQUESTRESULTS); - if (*err < 0 || *amount != BFLSC_QRES_LEN) { - mutex_unlock(&(bflsc->device_mutex)); - if (!ignore) - bflsc_applog(bflsc, dev, C_REQUESTRESULTS, *amount, *err); - - // TODO: do what? flag as dead device? - // count how many times it has happened and reset/fail it - // or even make sure it is all x-link and that means device - // has failed after some limit of this? - // of course all other I/O must also be failing ... - } else { - readok = true; - *err = usb_ftdi_read_ok(bflsc, buf, bufsiz-1, amount, C_GETRESULTS); - mutex_unlock(&(bflsc->device_mutex)); - - if (*err < 0 || *amount < 1) { - if (!ignore) - bflsc_applog(bflsc, dev, C_GETRESULTS, *amount, *err); - - // TODO: do what? ... see above - } - } - - return readok; -} - #define TVF(tv) ((float)((tv)->tv_sec) + ((float)((tv)->tv_usec) / 1000000.0)) #define TVFMS(tv) (TVF(tv) * 1000.0)