memset(cmd, 0, sizeof(cmd));
cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0);
- if (sdev->use_10_for_ms) {
- if (len > 65535)
+ /*
+ * Use MODE SELECT(10) if the device asked for it or if the mode page
+ * and the mode select header cannot fit within the maximumm 255 bytes
+ * of the MODE SELECT(6) command.
+ */
+ if (sdev->use_10_for_ms ||
+ len + 4 > 255 ||
+ data->block_descriptor_length > 255) {
+ if (len > 65535 - 8)
return -EINVAL;
real_buffer = kmalloc(8 + len, GFP_KERNEL);
if (!real_buffer)
real_buffer[3] = data->device_specific;
real_buffer[4] = data->longlba ? 0x01 : 0;
real_buffer[5] = 0;
- real_buffer[6] = data->block_descriptor_length >> 8;
- real_buffer[7] = data->block_descriptor_length;
+ put_unaligned_be16(data->block_descriptor_length,
+ &real_buffer[6]);
cmd[0] = MODE_SELECT_10;
- cmd[7] = len >> 8;
- cmd[8] = len;
+ put_unaligned_be16(len, &cmd[7]);
} else {
- if (len > 255 || data->block_descriptor_length > 255 ||
- data->longlba)
+ if (data->longlba)
return -EINVAL;
real_buffer = kmalloc(4 + len, GFP_KERNEL);