|
@@ -237,29 +237,16 @@ static struct ib_completion_queue_operations ib_gma_completion_ops = {
|
237
|
237
|
};
|
238
|
238
|
|
239
|
239
|
/**
|
240
|
|
- * Handle MAD request timer expiry
|
|
240
|
+ * Transmit MAD request
|
241
|
241
|
*
|
242
|
|
- * @v timer Retry timer
|
243
|
|
- * @v expired Failure indicator
|
|
242
|
+ * @v gma General management agent
|
|
243
|
+ * @v request MAD request
|
|
244
|
+ * @ret rc Return status code
|
244
|
245
|
*/
|
245
|
|
-static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
246
|
|
- struct ib_mad_request *request =
|
247
|
|
- container_of ( timer, struct ib_mad_request, timer );
|
248
|
|
- struct ib_gma *gma = request->gma;
|
249
|
|
- struct ib_device *ibdev = gma->ibdev;
|
|
246
|
+static int ib_gma_send ( struct ib_gma *gma, struct ib_mad_request *request ) {
|
250
|
247
|
struct io_buffer *iobuf;
|
251
|
248
|
int rc;
|
252
|
249
|
|
253
|
|
- /* Abandon TID if we have tried too many times */
|
254
|
|
- if ( expired ) {
|
255
|
|
- DBGC ( gma, "GMA %p abandoning TID %08x%08x\n",
|
256
|
|
- gma, ntohl ( request->mad.hdr.tid[0] ),
|
257
|
|
- ntohl ( request->mad.hdr.tid[1] ) );
|
258
|
|
- list_del ( &request->list );
|
259
|
|
- free ( request );
|
260
|
|
- return;
|
261
|
|
- }
|
262
|
|
-
|
263
|
250
|
DBGC ( gma, "GMA %p TX TID %08x%08x (%02x,%02x,%02x,%04x)\n",
|
264
|
251
|
gma, ntohl ( request->mad.hdr.tid[0] ),
|
265
|
252
|
ntohl ( request->mad.hdr.tid[1] ), request->mad.hdr.mgmt_class,
|
|
@@ -267,29 +254,56 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
267
|
254
|
ntohs ( request->mad.hdr.attr_id ) );
|
268
|
255
|
DBGC2_HDA ( gma, 0, &request->mad, sizeof ( request->mad ) );
|
269
|
256
|
|
270
|
|
- /* Restart retransmission timer */
|
271
|
|
- start_timer ( timer );
|
272
|
|
-
|
273
|
257
|
/* Construct I/O buffer */
|
274
|
258
|
iobuf = alloc_iob ( sizeof ( request->mad ) );
|
275
|
259
|
if ( ! iobuf ) {
|
276
|
260
|
DBGC ( gma, "GMA %p could not allocate buffer for TID "
|
277
|
261
|
"%08x%08x\n", gma, ntohl ( request->mad.hdr.tid[0] ),
|
278
|
262
|
ntohl ( request->mad.hdr.tid[1] ) );
|
279
|
|
- return;
|
|
263
|
+ return -ENOMEM;
|
280
|
264
|
}
|
281
|
265
|
memcpy ( iob_put ( iobuf, sizeof ( request->mad ) ), &request->mad,
|
282
|
266
|
sizeof ( request->mad ) );
|
283
|
267
|
|
284
|
|
- /* Post send request */
|
285
|
|
- if ( ( rc = ib_post_send ( ibdev, gma->qp, &request->av,
|
|
268
|
+ /* Send I/O buffer */
|
|
269
|
+ if ( ( rc = ib_post_send ( gma->ibdev, gma->qp, &request->av,
|
286
|
270
|
iobuf ) ) != 0 ) {
|
287
|
271
|
DBGC ( gma, "GMA %p could not send TID %08x%08x: %s\n",
|
288
|
272
|
gma, ntohl ( request->mad.hdr.tid[0] ),
|
289
|
273
|
ntohl ( request->mad.hdr.tid[1] ), strerror ( rc ) );
|
290
|
274
|
free_iob ( iobuf );
|
|
275
|
+ return rc;
|
|
276
|
+ }
|
|
277
|
+
|
|
278
|
+ return 0;
|
|
279
|
+}
|
|
280
|
+
|
|
281
|
+/**
|
|
282
|
+ * Handle MAD request timer expiry
|
|
283
|
+ *
|
|
284
|
+ * @v timer Retry timer
|
|
285
|
+ * @v expired Failure indicator
|
|
286
|
+ */
|
|
287
|
+static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
|
288
|
+ struct ib_mad_request *request =
|
|
289
|
+ container_of ( timer, struct ib_mad_request, timer );
|
|
290
|
+ struct ib_gma *gma = request->gma;
|
|
291
|
+
|
|
292
|
+ /* Abandon TID if we have tried too many times */
|
|
293
|
+ if ( expired ) {
|
|
294
|
+ DBGC ( gma, "GMA %p abandoning TID %08x%08x\n",
|
|
295
|
+ gma, ntohl ( request->mad.hdr.tid[0] ),
|
|
296
|
+ ntohl ( request->mad.hdr.tid[1] ) );
|
|
297
|
+ list_del ( &request->list );
|
|
298
|
+ free ( request );
|
291
|
299
|
return;
|
292
|
300
|
}
|
|
301
|
+
|
|
302
|
+ /* Restart retransmission timer */
|
|
303
|
+ start_timer ( timer );
|
|
304
|
+
|
|
305
|
+ /* Resend request */
|
|
306
|
+ ib_gma_send ( gma, request );
|
293
|
307
|
}
|
294
|
308
|
|
295
|
309
|
/**
|
|
@@ -298,10 +312,11 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
298
|
312
|
* @v gma General management agent
|
299
|
313
|
* @v mad MAD request
|
300
|
314
|
* @v av Destination address, or NULL for SM
|
|
315
|
+ * @v retry Request should be retried until a response arrives
|
301
|
316
|
* @ret rc Return status code
|
302
|
317
|
*/
|
303
|
318
|
int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
|
304
|
|
- struct ib_address_vector *av ) {
|
|
319
|
+ struct ib_address_vector *av, int retry ) {
|
305
|
320
|
struct ib_device *ibdev = gma->ibdev;
|
306
|
321
|
struct ib_mad_request *request;
|
307
|
322
|
|
|
@@ -312,7 +327,6 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
|
312
|
327
|
return -ENOMEM;
|
313
|
328
|
}
|
314
|
329
|
request->gma = gma;
|
315
|
|
- list_add ( &request->list, &gma->requests );
|
316
|
330
|
request->timer.expired = ib_gma_timer_expired;
|
317
|
331
|
|
318
|
332
|
/* Determine address vector */
|
|
@@ -332,8 +346,18 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
|
332
|
346
|
request->mad.hdr.tid[0] = htonl ( IB_GMA_TID_MAGIC );
|
333
|
347
|
request->mad.hdr.tid[1] = htonl ( ++next_request_tid );
|
334
|
348
|
|
335
|
|
- /* Start timer to initiate transmission */
|
336
|
|
- start_timer_nodelay ( &request->timer );
|
|
349
|
+ /* Send initial request. Ignore errors; the retry timer will
|
|
350
|
+ * take care of those we care about.
|
|
351
|
+ */
|
|
352
|
+ ib_gma_send ( gma, request );
|
|
353
|
+
|
|
354
|
+ /* Add to list and start timer if applicable */
|
|
355
|
+ if ( retry ) {
|
|
356
|
+ list_add ( &request->list, &gma->requests );
|
|
357
|
+ start_timer ( &request->timer );
|
|
358
|
+ } else {
|
|
359
|
+ free ( request );
|
|
360
|
+ }
|
337
|
361
|
|
338
|
362
|
return 0;
|
339
|
363
|
}
|