Ejemplo n.º 1
0
Archivo: script.c Proyecto: 3a9LL/panda
/**
 * Probe script image
 *
 * @v image		Script
 * @ret rc		Return status code
 */
static int script_probe ( struct image *image ) {
	static const char ipxe_magic[] = "#!ipxe";
	static const char gpxe_magic[] = "#!gpxe";
	linker_assert ( sizeof ( ipxe_magic ) == sizeof ( gpxe_magic ),
			magic_size_mismatch );
	char test[ sizeof ( ipxe_magic ) - 1 /* NUL */
		   + 1 /* terminating space */];

	/* Sanity check */
	if ( image->len < sizeof ( test ) ) {
		DBG ( "Too short to be a script\n" );
		return -ENOEXEC;
	}

	/* Check for magic signature */
	copy_from_user ( test, image->data, 0, sizeof ( test ) );
	if ( ! ( ( ( memcmp ( test, ipxe_magic, sizeof ( test ) - 1 ) == 0 ) ||
		   ( memcmp ( test, gpxe_magic, sizeof ( test ) - 1 ) == 0 )) &&
		 isspace ( test[ sizeof ( test ) - 1 ] ) ) ) {
		DBG ( "Invalid magic signature\n" );
		return -ENOEXEC;
	}

	return 0;
}
Ejemplo n.º 2
0
/**
 * Send AoE command
 *
 * @v aoe		AoE session
 * @ret rc		Return status code
 *
 * This transmits an AoE command packet.  It does not wait for a
 * response.
 */
static int aoe_send_command ( struct aoe_session *aoe ) {
	struct ata_command *command = aoe->command;
	struct io_buffer *iobuf;
	struct aoehdr *aoehdr;
	union aoecmd *aoecmd;
	struct aoeata *aoeata;
	unsigned int count;
	unsigned int data_out_len;
	unsigned int aoecmdlen;

	/* Fail immediately if we have no netdev to send on */
	if ( ! aoe->netdev ) {
		aoe_done ( aoe, -ENETUNREACH );
		return -ENETUNREACH;
	}

	/* If we are transmitting anything that requires a response,
         * start the retransmission timer.  Do this before attempting
         * to allocate the I/O buffer, in case allocation itself
         * fails.
         */
	start_timer ( &aoe->timer );

	/* Calculate count and data_out_len for this subcommand */
	switch ( aoe->aoe_cmd_type ) {
	case AOE_CMD_ATA:
		count = command->cb.count.native;
		if ( count > AOE_MAX_COUNT )
			count = AOE_MAX_COUNT;
		data_out_len = ( command->data_out ?
				 ( count * ATA_SECTOR_SIZE ) : 0 );
		aoecmdlen = sizeof ( aoecmd->ata );
		break;
	case AOE_CMD_CONFIG:
		count = 0;
		data_out_len = 0;
		aoecmdlen = sizeof ( aoecmd->cfg );
		break;
	default:
		return -ENOTSUP;
	}

	/* Create outgoing I/O buffer */
	iobuf = alloc_iob ( ETH_HLEN + sizeof ( *aoehdr ) +
			    aoecmdlen + data_out_len );

	if ( ! iobuf )
		return -ENOMEM;
	iob_reserve ( iobuf, ETH_HLEN );
	aoehdr = iob_put ( iobuf, sizeof ( *aoehdr ) );
	aoecmd = iob_put ( iobuf, aoecmdlen );
	memset ( aoehdr, 0, ( sizeof ( *aoehdr ) + aoecmdlen ) );

	/* Fill AoE header */
	aoehdr->ver_flags = AOE_VERSION;
	aoehdr->major = htons ( aoe->major );
	aoehdr->minor = aoe->minor;
	aoehdr->command = aoe->aoe_cmd_type;
	aoehdr->tag = htonl ( ++aoe->tag );

	/* Fill AoE payload */
	switch ( aoe->aoe_cmd_type ) {
	case AOE_CMD_ATA:
		/* Fill AoE command */
		aoeata = &aoecmd->ata;
		linker_assert ( AOE_FL_DEV_HEAD	== ATA_DEV_SLAVE,
				__fix_ata_h__ );
		aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 )|
				   ( command->cb.device & ATA_DEV_SLAVE ) |
				   ( data_out_len ? AOE_FL_WRITE : 0 ) );
		aoeata->err_feat = command->cb.err_feat.bytes.cur;
		aoeata->count = count;
		aoeata->cmd_stat = command->cb.cmd_stat;
		aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
		if ( ! command->cb.lba48 )
			aoeata->lba.bytes[3] |=
				( command->cb.device & ATA_DEV_MASK );

		/* Fill data payload */
		copy_from_user ( iob_put ( iobuf, data_out_len ),
				 command->data_out, aoe->command_offset,
				 data_out_len );
		break;
	case AOE_CMD_CONFIG:
		/* Nothing to do */
		break;
	default:
		assert ( 0 );
	}

	/* Send packet */
	return net_tx ( iobuf, aoe->netdev, &aoe_protocol, aoe->target );
}