diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-11-04 18:37:49 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-11-04 18:37:49 +0000 |
commit | 14b3bcbc4946c3e6947f9fdcec836defafaf05a9 (patch) | |
tree | f3e0d1042c4ff4c15654ab36cfd8859aeac65d37 /sys/src/9/port/devsd.c | |
parent | 70dfc2d75689339215d26637182830fc7348348b (diff) |
devsd, sdmmc, ether4330: improve infrastructure for sdio
devsd/sdmmc: provide annexsdio() function to take over a
sdio controller from devsd. this removes the tight
coupling between ether4330.
devsd: get rid of legacy function pointer in SDifc struct.
ether4330: cleanup code, fix bugs, set bus speed to 50Mhz,
provide multicast and promiscuous mode support.
Diffstat (limited to 'sys/src/9/port/devsd.c')
-rw-r--r-- | sys/src/9/port/devsd.c | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/sys/src/9/port/devsd.c b/sys/src/9/port/devsd.c index 5449e053b..d4e17bc44 100644 --- a/sys/src/9/port/devsd.c +++ b/sys/src/9/port/devsd.c @@ -110,6 +110,20 @@ freeunit(SDunit *unit) } static void +freesdev(SDev *sdev) +{ + int i; + + /* free units and their files */ + for(i = 0; i < sdev->nunit; i++) + freeunit(sdev->unit[i]); + + free(sdev->unitflg); + free(sdev->unit); + free(sdev); +} + +static void sdaddpart(SDunit* unit, char* name, uvlong start, uvlong end) { SDpart *pp; @@ -393,7 +407,7 @@ sdadddevs(SDev *sdev) continue; } id = sdindex(sdev->idno); - if(id == -1){ + if(id < 0){ print("sdadddevs: bad id number %d (%C)\n", id, id); goto giveup; } @@ -1653,13 +1667,7 @@ unconfigure(char* spec) if(sdev->ifc->clear != nil) (*sdev->ifc->clear)(sdev); - /* free units and their files */ - for(i = 0; i < sdev->nunit; i++) - freeunit(sdev->unit[i]); - - free(sdev->unitflg); - free(sdev->unit); - free(sdev); + freesdev(sdev); return 0; } @@ -1719,6 +1727,46 @@ sdshutdown(void) } } +/* + * find a SDdev, make sure its enabled and free it, + * returning its controller. This is used by + * annexsdio() to take over sdio from devsd. + */ +void* +sdannexctlr(char *spec, SDifc *ifc) +{ + int i; + SDev *sdev; + void *ctlr; + + if((i = sdindex(*spec)) < 0) + error(Enonexist); + + qlock(&devslock); + if((sdev = devs[i]) == nil){ + qunlock(&devslock); + error(Enonexist); + } + if(sdev->ifc != ifc){ + qunlock(&devslock); + error(Enonexist); + } + if(sdev->r.ref){ + qunlock(&devslock); + error(Einuse); + } + devs[i] = nil; + qunlock(&devslock); + + if(!sdev->enabled && ifc->enable != nil) + (*ifc->enable)(sdev); + + ctlr = sdev->ctlr; + freesdev(sdev); + + return ctlr; +} + Dev sddevtab = { 'S', "sd", |