static void sbp2_status_write()

in sbp2.c [405:454]


static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
			      int tcode, int destination, int source,
			      int generation, unsigned long long offset,
			      void *payload, size_t length, void *callback_data)
{
	struct sbp2_logical_unit *lu = callback_data;
	struct sbp2_orb *orb;
	struct sbp2_status status;
	unsigned long flags;

	if (tcode != TCODE_WRITE_BLOCK_REQUEST ||
	    length < 8 || length > sizeof(status)) {
		fw_send_response(card, request, RCODE_TYPE_ERROR);
		return;
	}

	status.status  = be32_to_cpup(payload);
	status.orb_low = be32_to_cpup(payload + 4);
	memset(status.data, 0, sizeof(status.data));
	if (length > 8)
		memcpy(status.data, payload + 8, length - 8);

	if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) {
		dev_notice(lu_dev(lu),
			   "non-ORB related status write, not handled\n");
		fw_send_response(card, request, RCODE_COMPLETE);
		return;
	}

	/* Lookup the orb corresponding to this status write. */
	spin_lock_irqsave(&lu->tgt->lock, flags);
	list_for_each_entry(orb, &lu->orb_list, link) {
		if (STATUS_GET_ORB_HIGH(status) == 0 &&
		    STATUS_GET_ORB_LOW(status) == orb->request_bus) {
			orb->rcode = RCODE_COMPLETE;
			list_del(&orb->link);
			break;
		}
	}
	spin_unlock_irqrestore(&lu->tgt->lock, flags);

	if (&orb->link != &lu->orb_list) {
		orb->callback(orb, &status);
		kref_put(&orb->kref, free_orb); /* orb callback reference */
	} else {
		dev_err(lu_dev(lu), "status write for unknown ORB\n");
	}

	fw_send_response(card, request, RCODE_COMPLETE);
}