@@ -199,26 +199,43 @@ afk_match_service(struct apple_dcp_afkep *ep, const char *name)
199199 return NULL ;
200200}
201201
202+ static struct apple_epic_service * afk_epic_find_service (struct apple_dcp_afkep * ep ,
203+ u32 channel )
204+ {
205+ for (u32 i = 0 ; i < ep -> num_channels ; i ++ )
206+ if (ep -> services [i ].enabled && ep -> services [i ].channel == channel )
207+ return & ep -> services [i ];
208+
209+ return NULL ;
210+ }
211+
202212static void afk_recv_handle_init (struct apple_dcp_afkep * ep , u32 channel ,
203213 u8 * payload , size_t payload_size )
204214{
205215 char name [32 ];
206216 s64 epic_unit = -1 ;
217+ u32 ch_idx ;
207218 const char * service_name = name ;
208219 const char * epic_name = NULL , * epic_class = NULL ;
209220 const struct apple_epic_service_ops * ops ;
210221 struct dcp_parse_ctx ctx ;
211222 u8 * props = payload + sizeof (name );
212223 size_t props_size = payload_size - sizeof (name );
213224
214- WARN_ON (ep -> services [ channel ]. enabled );
225+ WARN_ON (afk_epic_find_service ( ep , channel ) );
215226
216227 if (payload_size < sizeof (name )) {
217228 dev_err (ep -> dcp -> dev , "AFK[ep:%02x]: payload too small: %lx\n" ,
218229 ep -> endpoint , payload_size );
219230 return ;
220231 }
221232
233+ if (ep -> num_channels >= AFK_MAX_CHANNEL ) {
234+ dev_err (ep -> dcp -> dev , "AFK[ep:%02x]: too many enabled services!\n" ,
235+ ep -> endpoint );
236+ return ;
237+ }
238+
222239 strlcpy (name , payload , sizeof (name ));
223240
224241 /*
@@ -255,13 +272,14 @@ static void afk_recv_handle_init(struct apple_dcp_afkep *ep, u32 channel,
255272 goto free ;
256273 }
257274
258- spin_lock_init (& ep -> services [channel ].lock );
259- ep -> services [channel ].enabled = true;
260- ep -> services [channel ].ops = ops ;
261- ep -> services [channel ].ep = ep ;
262- ep -> services [channel ].channel = channel ;
263- ep -> services [channel ].cmd_tag = 0 ;
264- ops -> init (& ep -> services [channel ], epic_name , epic_class , epic_unit );
275+ ch_idx = ep -> num_channels ++ ;
276+ spin_lock_init (& ep -> services [ch_idx ].lock );
277+ ep -> services [ch_idx ].enabled = true;
278+ ep -> services [ch_idx ].ops = ops ;
279+ ep -> services [ch_idx ].ep = ep ;
280+ ep -> services [ch_idx ].channel = channel ;
281+ ep -> services [ch_idx ].cmd_tag = 0 ;
282+ ops -> init (& ep -> services [ch_idx ], epic_name , epic_class , epic_unit );
265283 dev_info (ep -> dcp -> dev , "AFK[ep:%02x]: new service %s on channel %d\n" ,
266284 ep -> endpoint , service_name , channel );
267285free :
@@ -271,11 +289,16 @@ static void afk_recv_handle_init(struct apple_dcp_afkep *ep, u32 channel,
271289
272290static void afk_recv_handle_teardown (struct apple_dcp_afkep * ep , u32 channel )
273291{
274- struct apple_epic_service * service = & ep -> services [ channel ] ;
292+ struct apple_epic_service * service ;
275293 const struct apple_epic_service_ops * ops ;
276294 unsigned long flags ;
277295
278- WARN_ON (!service -> enabled );
296+ service = afk_epic_find_service (ep , channel );
297+ if (!service ) {
298+ dev_warn (ep -> dcp -> dev , "AFK[ep:%02x]: teardown for disabled channel %u\n" ,
299+ ep -> endpoint , channel );
300+ return ;
301+ }
279302
280303 // TODO: think through what locking is necessary
281304 spin_lock_irqsave (& service -> lock , flags );
@@ -291,13 +314,20 @@ static void afk_recv_handle_reply(struct apple_dcp_afkep *ep, u32 channel,
291314 u16 tag , void * payload , size_t payload_size )
292315{
293316 struct epic_cmd * cmd = payload ;
294- struct apple_epic_service * service = & ep -> services [ channel ] ;
317+ struct apple_epic_service * service ;
295318 unsigned long flags ;
296319 u8 idx = tag & 0xff ;
297320 void * rxbuf , * txbuf ;
298321 dma_addr_t rxbuf_dma , txbuf_dma ;
299322 size_t rxlen , txlen ;
300323
324+ service = afk_epic_find_service (ep , channel );
325+ if (!service ) {
326+ dev_warn (ep -> dcp -> dev , "AFK[ep:%02x]: command reply on disabled channel %u\n" ,
327+ ep -> endpoint , channel );
328+ return ;
329+ }
330+
301331 if (payload_size < sizeof (* cmd )) {
302332 dev_err (ep -> dcp -> dev ,
303333 "AFK[ep:%02x]: command reply on channel %d too small: %ld\n" ,
@@ -369,7 +399,14 @@ static void afk_recv_handle_std_service(struct apple_dcp_afkep *ep, u32 channel,
369399 struct epic_sub_hdr * eshdr ,
370400 void * payload , size_t payload_size )
371401{
372- struct apple_epic_service * service = & ep -> services [channel ];
402+ struct apple_epic_service * service = afk_epic_find_service (ep , channel );
403+
404+ if (!service ) {
405+ dev_warn (ep -> dcp -> dev ,
406+ "AFK[ep:%02x]: std service notify on disabled channel %u\n" ,
407+ ep -> endpoint , channel );
408+ return ;
409+ }
373410
374411 if (type == EPIC_TYPE_NOTIFY && eshdr -> category == EPIC_CAT_NOTIFY ) {
375412 struct epic_std_service_ap_call * call = payload ;
@@ -436,6 +473,7 @@ static void afk_recv_handle_std_service(struct apple_dcp_afkep *ep, u32 channel,
436473static void afk_recv_handle (struct apple_dcp_afkep * ep , u32 channel , u32 type ,
437474 u8 * data , size_t data_size )
438475{
476+ struct apple_epic_service * service ;
439477 struct epic_hdr * ehdr = (struct epic_hdr * )data ;
440478 struct epic_sub_hdr * eshdr =
441479 (struct epic_sub_hdr * )(data + sizeof (* ehdr ));
@@ -452,13 +490,9 @@ static void afk_recv_handle(struct apple_dcp_afkep *ep, u32 channel, u32 type,
452490
453491 trace_afk_recv_handle (ep , channel , type , data_size , ehdr , eshdr );
454492
455- if (channel >= AFK_MAX_CHANNEL ) {
456- dev_err (ep -> dcp -> dev , "AFK[ep:%02x]: channel %d out of bounds\n" ,
457- ep -> endpoint , channel );
458- return ;
459- }
493+ service = afk_epic_find_service (ep , channel );
460494
461- if (!ep -> services [ channel ]. enabled ) {
495+ if (!service ) {
462496 if (type != EPIC_TYPE_NOTIFY ) {
463497 dev_err (ep -> dcp -> dev ,
464498 "AFK[ep:%02x]: expected notify but got 0x%x on channel %d\n" ,
@@ -481,7 +515,7 @@ static void afk_recv_handle(struct apple_dcp_afkep *ep, u32 channel, u32 type,
481515 return afk_recv_handle_init (ep , channel , payload , payload_size );
482516 }
483517
484- if (!ep -> services [ channel ]. enabled ) {
518+ if (!service ) {
485519 dev_err (ep -> dcp -> dev , "AFK[ep:%02x]: channel %d has no service\n" ,
486520 ep -> endpoint , channel );
487521 return ;
0 commit comments