/* * Driver for Option High Speed Mobile Devices. * * (c) 2008 Dan Williams * * Inspiration taken from sierra_ms.c by Kevin Lloyd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "usb.h" #include "transport.h" #include "option_ms.h" #include "debug.h" #define ZCD_FORCE_MODEM 0x01 #define ZCD_ALLOW_MS 0x02 static unsigned int option_zero_cd = ZCD_FORCE_MODEM; module_param(option_zero_cd, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(option_zero_cd, "ZeroCD mode (1=Force Modem (default)," " 2=Allow CD-Rom"); #define RESPONSE_LEN 1024 static int option_rezero(struct us_data *us) { const unsigned char rezero_msg[] = { 0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; char *buffer; int result; usb_stor_dbg(us, "Option MS: %s\n", "DEVICE MODE SWITCH"); buffer = kzalloc(RESPONSE_LEN, GFP_KERNEL); if (buffer == NULL) return USB_STOR_TRANSPORT_ERROR; memcpy(buffer, rezero_msg, sizeof(rezero_msg)); result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, buffer, sizeof(rezero_msg), NULL); if (result != USB_STOR_XFER_GOOD) { result = USB_STOR_XFER_ERROR; goto out; } /* * Some of the devices need to be asked for a response, but we don't * care what that response is. */ usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, buffer, RESPONSE_LEN, NULL); /* Read the CSW */ usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, buffer, 13, NULL); result = USB_STOR_XFER_GOOD; out: kfree(buffer); return result; } static int option_inquiry(struct us_data *us) { const unsigned char inquiry_msg[] = { 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0x24, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; char *buffer; int result; usb_stor_dbg(us, "Option MS: %s\n", "device inquiry for vendor name"); buffer = kzalloc(0x24, GFP_KERNEL); if (buffer == NULL) return USB_STOR_TRANSPORT_ERROR; memcpy(buffer, inquiry_msg, sizeof(inquiry_msg)); result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, buffer, sizeof(inquiry_msg), NULL); if (result != USB_STOR_XFER_GOOD) { result = USB_STOR_XFER_ERROR; goto out; } result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, buffer, 0x24, NULL); if (result != USB_STOR_XFER_GOOD) { result = USB_STOR_XFER_ERROR; goto out; } result = memcmp(buffer+8, "Option", 6); if (result != 0) result = memcmp(buffer+8, "ZCOPTION", 8); /* Read the CSW */ usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, buffer, 13, NULL); out: kfree(buffer); return result; } int option_ms_init(struct us_data *us) { int result; usb_stor_dbg(us, "Option MS: %s\n", "option_ms_init called"); /* * Additional test for vendor information via INQUIRY, * because some vendor/product IDs are ambiguous */ result = option_inquiry(us); if (result != 0) { usb_stor_dbg(us, "Option MS: %s\n", "vendor is not Option or not determinable, no action taken"); return 0; } else usb_stor_dbg(us, "Option MS: %s\n", "this is a genuine Option device, proceeding"); /* Force Modem mode */ if (option_zero_cd == ZCD_FORCE_MODEM) { usb_stor_dbg(us, "Option MS: %s\n", "Forcing Modem Mode"); result = option_rezero(us); if (result != USB_STOR_XFER_GOOD) usb_stor_dbg(us, "Option MS: %s\n", "Failed to switch to modem mode"); return -EIO; } else if (option_zero_cd == ZCD_ALLOW_MS) { /* Allow Mass Storage mode (keep CD-Rom) */ usb_stor_dbg(us, "Option MS: %s\n", "Allowing Mass Storage Mode if device requests it"); } return 0; } ;id=33084060fb6d51ff566439a387f69ed90301280c'>33084060fb6d51ff566439a387f69ed90301280c (patch) treefdf257c069543dae105b4f9645dc62dc13016a90 parent1c0e6a3613d3f0bb088a3160095c8da4c1214d02 (diff)
i40e: add interrupt rate limit verbosity
Due to the resolution of the register controlling interrupt rate limiting, setting certain values for the interrupt rate limit make it appear as though the limiting is not completely accurate. The problem is that the interrupt rate limit is getting rounded down to the nearest multiple of 4. This patch fixes the problem by adding some feedback to the user as to the actual interrupt rate limit being used when it differs from the requested limit. Without this patch setting interrupt rate limits may appear to behave inaccurately. Change-ID: I3093cf3f2d437d35a4c4f4bb5af5ce1b85ab21b7 Signed-off-by: Alan Brady <alan.brady@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>