mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-23 09:36:24 +03:00
Provide dev option -c*/u for udev rules
This commit is contained in:
@@ -1381,8 +1381,9 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
|
||||
for(int i=0; i<N_PINS; i++) {
|
||||
const char *str = pins_to_str(pgm->pin+i);
|
||||
const char *bstr = base? pins_to_str(base->pin+i): NULL;
|
||||
if(!base || !str_eq(bstr, str))
|
||||
_pgmout_fmt(avr_pin_lcname(i), "%s", str);
|
||||
const char *pinname = avr_pin_lcname(i);
|
||||
if((!base || !str_eq(bstr, str)) && !str_eq(pinname, "<unknown>"))
|
||||
_pgmout_fmt(pinname, "%s", str);
|
||||
}
|
||||
|
||||
pgmstr = dev_hvupdi_support_liststr(pgm);
|
||||
@@ -1413,9 +1414,54 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
|
||||
}
|
||||
|
||||
|
||||
// -c <wildcard>/[dASsrtiBUPTIJWHQ]
|
||||
typedef struct {
|
||||
int vid, pid, ishid;
|
||||
const char *ids;
|
||||
} Dev_udev;
|
||||
|
||||
|
||||
static Dev_udev *add_udev(Dev_udev *ud, int *uip, int vid, int pid, int ishid, const char *ids) {
|
||||
for(int i = 0; i < *uip; i++) // Already entered?
|
||||
if(ud[i].vid == vid && ud[i].pid == pid && ud[i].ishid == ishid && ud[i].ids == ids)
|
||||
return ud;
|
||||
if(*uip % 128 == 0)
|
||||
ud = (Dev_udev *) mmt_realloc(ud, sizeof*ud*(*uip+128));
|
||||
|
||||
ud[*uip].vid = vid;
|
||||
ud[*uip].pid = pid;
|
||||
ud[*uip].ishid = ishid;
|
||||
ud[*uip].ids = ids;
|
||||
(*uip)++;
|
||||
|
||||
return ud;
|
||||
}
|
||||
|
||||
static int udev_cmp_wout_ids(const Dev_udev *p1, const Dev_udev *p2) {
|
||||
int diff;
|
||||
if((diff = p1->vid - p2->vid))
|
||||
return diff;
|
||||
if((diff = p1->pid - p2->pid))
|
||||
return diff;
|
||||
return p1->ishid - p2->ishid;
|
||||
}
|
||||
|
||||
static int udev_cmp(const void *v1, const void *v2) {
|
||||
const Dev_udev *p1 = v1, *p2 = v2;
|
||||
int diff;
|
||||
|
||||
if((diff = udev_cmp_wout_ids(p1, p2)))
|
||||
return diff;
|
||||
return strcmp(p1->ids, p2->ids);
|
||||
}
|
||||
|
||||
#include "flip1.h"
|
||||
#include "flip2.h"
|
||||
#include "jtag3.h"
|
||||
#include "stk500v2.h"
|
||||
|
||||
// -c <wildcard>/[duASsrtiBUPTIJWHQ]
|
||||
void dev_output_pgm_defs(char *pgmidcp) {
|
||||
bool descs, astrc, strct, cmpst, raw, tsv, injct;
|
||||
bool descs, astrc, strct, cmpst, raw, tsv, injct, udev;
|
||||
char *flags;
|
||||
int nprinted;
|
||||
PROGRAMMER *nullpgm = pgm_new();
|
||||
@@ -1426,7 +1472,7 @@ void dev_output_pgm_defs(char *pgmidcp) {
|
||||
if(!flags && str_eq(pgmidcp, "*")) // Treat -c * as if it was -c */s
|
||||
flags = "s";
|
||||
|
||||
if(!*flags || !strchr("dASsrtiBUPTIJWHQ", *flags)) {
|
||||
if(!*flags || !strchr("duASsrtiBUPTIJWHQ", *flags)) {
|
||||
dev_info("Error: flags for developer option -c <wildcard>/<flags> not recognised\n");
|
||||
dev_info(
|
||||
"Wildcard examples (these need protecting in the shell through quoting):\n"
|
||||
@@ -1436,6 +1482,7 @@ void dev_output_pgm_defs(char *pgmidcp) {
|
||||
" jtag?pdi matches jtag2pdi and jtag3pdi\n"
|
||||
"Flags (one or more of the characters below):\n"
|
||||
" d description of core programmer features\n"
|
||||
" u show udev entry for programmer\n"
|
||||
" A show entries of avrdude.conf programmers with all values\n"
|
||||
" S show entries of avrdude.conf programmers with necessary values\n"
|
||||
" s show short entries of avrdude.conf programmers using parent\n"
|
||||
@@ -1465,9 +1512,13 @@ void dev_output_pgm_defs(char *pgmidcp) {
|
||||
raw = !!strchr(flags, 'r');
|
||||
tsv = !!strchr(flags, 't');
|
||||
injct = !!strchr(flags, 'i');
|
||||
udev = !!strchr(flags, 'u');
|
||||
|
||||
nprinted = dev_nprinted;
|
||||
|
||||
int ui = 0;
|
||||
Dev_udev *udr = NULL;
|
||||
|
||||
LNODEID ln1, ln2;
|
||||
for(ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) {
|
||||
PROGRAMMER *pgm = ldata(ln1);
|
||||
@@ -1480,6 +1531,7 @@ void dev_output_pgm_defs(char *pgmidcp) {
|
||||
}
|
||||
if(!matched)
|
||||
continue;
|
||||
|
||||
if(!prog_modes_in_flags(pgm->prog_modes, flags))
|
||||
continue;
|
||||
|
||||
@@ -1508,7 +1560,60 @@ void dev_output_pgm_defs(char *pgmidcp) {
|
||||
);
|
||||
}
|
||||
|
||||
if(udev && pgm->usbpid && (pgm->conntype == CONNTYPE_USB || is_serialadapter(pgm))) {
|
||||
void (* pi)(PROGRAMMER *) = pgm->initpgm;
|
||||
const char *ids = cache_string(str_ccpgmids(pgm->id));
|
||||
int usbvid = pgm->usbvid, ishid =
|
||||
pi == jtag3_initpgm || pi == jtag3_pdi_initpgm || pi == jtag3_updi_initpgm ||
|
||||
pi == jtag3_dw_initpgm || pi == stk500v2_jtag3_initpgm || pi == jtag3_tpi_initpgm;
|
||||
|
||||
if(!lfirst(pgm->usbpid)) {
|
||||
if(pi == flip1_initpgm || pi == flip2_initpgm) { // Bootloaders, add possible part pids
|
||||
for(LNODEID lp = lfirst(part_list); lp; lp = lnext(lp)) {
|
||||
AVRPART *pt = ldata(lp);
|
||||
if(pt->usbpid)
|
||||
udr = add_udev(udr, &ui, usbvid, pt->usbpid, 0, ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(LNODEID pidn=lfirst(pgm->usbpid); pidn; pidn=lnext(pidn))
|
||||
udr = add_udev(udr, &ui, usbvid, *(int *) ldata(pidn), ishid, ids);
|
||||
}
|
||||
|
||||
if(raw)
|
||||
dev_pgm_raw(pgm);
|
||||
}
|
||||
|
||||
if(udev && ui) {
|
||||
dev_info("# 1. Put Linux udev rules into /etc/udev/rules.d/80-avrdude.rules (or similar)\n");
|
||||
dev_info("# 2. sudo udevadm control --reload-rules && sudo udevadm trigger (or similar)\n");
|
||||
dev_info("# 3. Unplug the device and plug it in again\n");
|
||||
qsort(udr, ui, sizeof *udr, udev_cmp);
|
||||
char *prev_head = mmt_strdup("<none>");
|
||||
for(Dev_udev *u = udr; u-udr < ui; u++) {
|
||||
char head[1024] = {0}, *h = head;
|
||||
strncpy(h, u->ids, sizeof head - 1), h += strlen(h);
|
||||
for(Dev_udev *v = u+1; v-udr < ui; v++) {
|
||||
if(udev_cmp_wout_ids(u, v))
|
||||
break;
|
||||
if((int) (strlen(v->ids) + 3 + h-head) <= (int) sizeof head) {
|
||||
strcpy(h, ", "), h += 2;
|
||||
strcpy(h, v->ids), h += strlen(v->ids);
|
||||
}
|
||||
u = v;
|
||||
}
|
||||
if(!str_eq(prev_head, head)) {
|
||||
dev_info("\n# %s\n", head);
|
||||
mmt_free(prev_head);
|
||||
prev_head = mmt_strdup(head);
|
||||
}
|
||||
dev_info("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", "
|
||||
"GROUP=\"plugdev\", MODE=\"0660\", TAG+=\"uaccess\"\n", u->vid, u->pid);
|
||||
if(u->ishid)
|
||||
dev_info("KERNEL==\"hidraw*\", SUBSYSTEM==\"hidraw\", ATTRS{idVendor}==\"%04x\", "
|
||||
"ATTRS{idProduct}==\"%04x\", GROUP=\"plugdev\", MODE=\"0660\", TAG+=\"uaccess\"\n", u->vid, u->pid);
|
||||
}
|
||||
mmt_free(prev_head);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,7 +1123,7 @@ int main(int argc, char * argv [])
|
||||
pgmid = cache_string(default_programmer);
|
||||
|
||||
// Developer options to print parts and/or programmer entries of avrdude.conf
|
||||
int dev_opt_c = dev_opt(pgmid); // -c <wildcard>/[dASsrtiBUPTIJWHQ]
|
||||
int dev_opt_c = dev_opt(pgmid); // -c <wildcard>/[duASsrtiBUPTIJWHQ]
|
||||
int dev_opt_p = dev_opt(partdesc); // -p <wildcard>/[cdoASsrw*tiBUPTIJWHQ]
|
||||
|
||||
if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h
|
||||
|
||||
Reference in New Issue
Block a user