drivers/scsi/esas2r/esas2r_disc.c

Source file repositories/reference/linux-study-clean/drivers/scsi/esas2r/esas2r_disc.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/esas2r/esas2r_disc.c
Extension
.c
Size
29291 bytes
Lines
1186
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

test_bit(AF_POWER_MGT, &a->flags)) {
		if (a->prev_dev_cnt == 0) {
			/* Don't bother waiting if there is nothing to wait
			 * for.
			 */
			a->disc_wait_time = 0;
		} else {
			/*
			 * Set the device wait count to what was previously
			 * found.  We don't care if the user only configured
			 * a time because we know the exact count to wait for.
			 * There is no need to honor the user's wishes to
			 * always wait the full time.
			 */
			a->disc_wait_cnt = a->prev_dev_cnt;

			/*
			 * bump the minimum wait time to 15 seconds since the
			 * default is 3 (system boot or the boot driver usually
			 * buys us more time).
			 */
			if (a->disc_wait_time < 15000)
				a->disc_wait_time = 15000;
		}
	}

	esas2r_trace("disc wait count: %d", a->disc_wait_cnt);
	esas2r_trace("disc wait time: %d", a->disc_wait_time);

	if (a->disc_wait_time == 0)
		esas2r_disc_check_complete(a);

	esas2r_trace_exit();
}

void esas2r_disc_start_waiting(struct esas2r_adapter *a)
{
	unsigned long flags;

	spin_lock_irqsave(&a->mem_lock, flags);

	if (a->disc_ctx.disc_evt)
		esas2r_disc_start_port(a);

	spin_unlock_irqrestore(&a->mem_lock, flags);
}

void esas2r_disc_check_for_work(struct esas2r_adapter *a)
{
	struct esas2r_request *rq = &a->general_req;

	/* service any pending interrupts first */

	esas2r_polled_interrupt(a);

	/*
	 * now, interrupt processing may have queued up a discovery event.  go
	 * see if we have one to start.  we couldn't start it in the ISR since
	 * polled discovery would cause a deadlock.
	 */

	esas2r_disc_start_waiting(a);

	if (rq->interrupt_cx == NULL)
		return;

	if (rq->req_stat == RS_STARTED
	    && rq->timeout <= RQ_MAX_TIMEOUT) {
		/* wait for the current discovery request to complete. */
		esas2r_wait_request(a, rq);

		if (rq->req_stat == RS_TIMEOUT) {
			esas2r_disc_abort(a, rq);
			esas2r_local_reset_adapter(a);
			return;
		}
	}

	if (rq->req_stat == RS_PENDING
	    || rq->req_stat == RS_STARTED)
		return;

	esas2r_disc_continue(a, rq);
}

void esas2r_disc_check_complete(struct esas2r_adapter *a)
{
	unsigned long flags;

	esas2r_trace_enter();

Annotation

Implementation Notes