|
@@ -73,9 +73,6 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *queue,
|
|
|
struct qeth_qdio_out_buffer *buf,
|
|
|
enum iucv_tx_notify notification);
|
|
|
static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf);
|
|
|
-static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
|
|
|
- struct qeth_qdio_out_buffer *buf,
|
|
|
- enum qeth_qdio_buffer_states newbufstate);
|
|
|
static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
|
|
|
|
|
|
struct workqueue_struct *qeth_wq;
|
|
@@ -489,6 +486,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
|
|
|
struct qaob *aob;
|
|
|
struct qeth_qdio_out_buffer *buffer;
|
|
|
enum iucv_tx_notify notification;
|
|
|
+ unsigned int i;
|
|
|
|
|
|
aob = (struct qaob *) phys_to_virt(phys_aob_addr);
|
|
|
QETH_CARD_TEXT(card, 5, "haob");
|
|
@@ -513,10 +511,18 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
|
|
|
qeth_notify_skbs(buffer->q, buffer, notification);
|
|
|
|
|
|
buffer->aob = NULL;
|
|
|
- qeth_clear_output_buffer(buffer->q, buffer,
|
|
|
- QETH_QDIO_BUF_HANDLED_DELAYED);
|
|
|
+ /* Free dangling allocations. The attached skbs are handled by
|
|
|
+ * qeth_cleanup_handled_pending().
|
|
|
+ */
|
|
|
+ for (i = 0;
|
|
|
+ i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
|
|
|
+ i++) {
|
|
|
+ if (aob->sba[i] && buffer->is_header[i])
|
|
|
+ kmem_cache_free(qeth_core_header_cache,
|
|
|
+ (void *) aob->sba[i]);
|
|
|
+ }
|
|
|
+ atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
|
|
|
|
|
|
- /* from here on: do not touch buffer anymore */
|
|
|
qdio_release_aob(aob);
|
|
|
}
|
|
|
|
|
@@ -3759,6 +3765,10 @@ static void qeth_qdio_output_handler(struct ccw_device *ccwdev,
|
|
|
QETH_CARD_TEXT(queue->card, 5, "aob");
|
|
|
QETH_CARD_TEXT_(queue->card, 5, "%lx",
|
|
|
virt_to_phys(buffer->aob));
|
|
|
+
|
|
|
+ /* prepare the queue slot for re-use: */
|
|
|
+ qeth_scrub_qdio_buffer(buffer->buffer,
|
|
|
+ QETH_MAX_BUFFER_ELEMENTS(card));
|
|
|
if (qeth_init_qdio_out_buf(queue, bidx)) {
|
|
|
QETH_CARD_TEXT(card, 2, "outofbuf");
|
|
|
qeth_schedule_recovery(card);
|